Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bonelifer/2dac194abbfbc01910a5ea52a098d0a6 to your computer and use it in GitHub Desktop.
Save bonelifer/2dac194abbfbc01910a5ea52a098d0a6 to your computer and use it in GitHub Desktop.

Automatic Sync Using udev

Phone Udev Rule Setup

Overview

This guide explains how to set up udev rules to automatically mount your phone at /mnt/phone and synchronize music files from a local directory to the phone when it's connected to your computer.

Installation

  1. Create Udev Rule for Mounting Phone at /mnt/phone

    • Create a new udev rule file:

      sudo touch /etc/udev/rules.d/9-local.rules
    • Add the following rule to the newly created file:

      ACTION=="add", SUBSYSTEM=="block", ATTRS{idVendor}=="your_phone_vendor_id", ATTRS{idProduct}=="your_phone_product_id", RUN+="/usr/bin/systemd-mount --no-block --automount --collect /dev/%k /mnt/phone"
      

      Replace your_phone_vendor_id and your_phone_product_id with the actual vendor and product IDs of your phone. See Identify Phone Attributes for instructions on how to find these.

    • Save the file.

  2. Create Udev Rule for Running Command When Phone is Mounted

    • Create a new udev rule file:

      sudo touch /etc/udev/rules.d/10-local.rules
    • Add the following rule to the newly created file:

      ACTION=="add", ENV{DEVTYPE}=="partition", ENV{ID_FS_UUID}=="your_phone_uuid", ENV{ID_FS_MOUNT_POINT}=="/mnt/phone", RUN+="/path/to/your/script.sh"
      

      Replace your_phone_uuid with the actual UUID of your phone's filesystem, and /path/to/your/script.sh with the path to your desired script.

    • Save the file.

  3. Reload Udev Rules

    After saving the udev rule files, reload udev rules to apply the changes:

    sudo udevadm control --reload-rules && sudo udevadm trigger

Identify Phone Attributes

Before setting up the udev rules, you need to identify the attributes of your phone that udev can use to reliably identify it when it's connected. This could include attributes like the device name, vendor ID, product ID, or serial number.

Steps to Identify Phone Attributes

  1. Plug in Your Phone: Connect your phone to your computer using a USB cable.

  2. List USB Devices: Use the lsusb command to list all connected USB devices:

    lsusb

    Example Output:

    Bus 001 Device 002: ID 1234:5678 YourPhoneManufacturer Phone Model
    
  3. Note Vendor and Product IDs: Note down the Vendor ID and Product ID of your phone. In the example output above, 1234 is the Vendor ID, and 5678 is the Product ID.

  4. Verify Mount Point: Ensure that your phone's filesystem is mounted at the expected mount point. You can use the mount command to list mounted filesystems:

    mount

    Example Output:

    /dev/sdc1 on /mnt/phone type ext4 (rw,relatime)
    

    Ensure that /mnt/phone is the correct mount point for your phone's filesystem.

Additional Information

Reloading Udev Rules

After modifying or adding new udev rules, you need to reload the udev rules to apply the changes. Use the following command:

sudo udevadm control --reload-rules && sudo udevadm trigger

Conclusion

With these udev rules in place, your phone will be automatically mounted at /mnt/phone when connected to your computer, and the specified script will synchronize music files from a local directory to your phone. This provides an automated solution for keeping your music library updated on your device without manual intervention. Adjust the attributes in the rules as needed to match your phone's specific characteristics.

#!/bin/bash
###############################################################################
# Description: #
# #
# This script automates the synchronization of music files from a local #
# directory to a connected device such as a smartphone, filtering by artists #
# found on the device. It assumes the device is already mounted and then uses #
# rsync to synchronize the files between the specified directories. #
# #
# By default, notifications are displayed using libnotify. You can optionally #
# specify an icon to be displayed alongside the notification text. #
# Set the ICON_PATH variable to the filepath of the desired icon. #
###############################################################################
# Usage: sync_script.sh [--dry-run] [--notify] #
# Options: #
# --dry-run Perform a trial run with no changes made #
# --notify Display notifications using libnotify #
# Examples: #
# sync_script.sh --dry-run #
# Perform a dry run to preview changes #
# sync_script.sh --notify #
# Synchronize files with notifications #
###############################################################################
### Variables ###
phone_mount="/media/smartphone/music/" # Full path to the directory where the device is mounted
local_dir_to_sync="/mnt/Jukebox/" # Directory in the local computer (should end in '/')
log_file="/tmp/rsync.log"
icon_path="/path/to/icon.png" # Default icon file path (change as needed)
### Functions ###
# Function to print messages
print() {
echo -e "$1"
}
# Function to display notification
notify() {
local message="$1"
if command -v notify-send &> /dev/null; then
if [ -f "$icon_path" ]; then
notify-send -i "$icon_path" "Sync Notification" "$message"
else
notify-send "Sync Notification" "$message"
fi
else
print "Error: libnotify is not installed. Unable to display notifications."
fi
}
# Function to display usage information
usage() {
print "Usage: $0 [--dry-run] [--notify]"
exit 1
}
# Function to get a list of artists from the phone
get_artists() {
# Use find to get a list of directories (artists) in the phone's music directory
find "$phone_mount" -mindepth 1 -maxdepth 1 -type d -printf "%P\n"
}
### Main Script ###
# Parse arguments
while [ -n "$1" ]; do
case "$1" in
--dry-run)
dry_run="--dry-run"
;;
--notify)
use_notify=1
;;
-*)
usage
;;
esac
shift
done
# Notify user about the synchronization start
if [ "$use_notify" ]; then
notify "Starting synchronization"
fi
# Check if rsync command is available
if ! command -v rsync &> /dev/null; then
print "Error: rsync is not installed. Please install rsync."
exit 1
fi
# Check if the source directory exists
if [ ! -d "$local_dir_to_sync" ]; then
print "Error: Source directory does not exist: $local_dir_to_sync"
exit 1
fi
# Check if the destination directory exists
if [ ! -d "$phone_mount" ]; then
print "Error: Destination directory does not exist: $phone_mount"
exit 1
fi
# Get list of artists on the phone
artists_on_phone=$(get_artists)
# Sync each artist's directory from the local computer to the phone
for artist in $artists_on_phone; do
artist_dir="$local_dir_to_sync/$artist/"
if [ -d "$artist_dir" ]; then
print "Syncing $artist..."
rsync $dry_run --delete --verbose --times --recursive --stats --human-readable --progress --log-file="$log_file" --modify-window=3601 "$artist_dir" "$phone_mount"
fi
done
# Notify user about the synchronization completion
if [ "$use_notify" ]; then
notify "Synchronization completed"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment