A tool to sync music with your favorite devices
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

*: add README.md

Gee Sawra 1ab6c4d9 f1875297

+100
+100
README.md
··· 1 + # `tracksync`: if `rsync` was ID3-aware 2 + 3 + `tracksync` synchronizes music files from a source to a destination, keeping a database for both. 4 + 5 + Tracks need to be added to the source database first, and then can be synced on the destination. 6 + 7 + There is no maximum amount of destinations you can have, each one will maintain its database and can be kept in sync 8 + with the source. 9 + 10 + The destination tree structure is ordered by artist, album, disc number, and track name, as detailed by each ID3 tag. 11 + 12 + Pass `-h` to each subcommand to understand how to use it! 13 + 14 + `tracksync` can also create hardlinks instead of copies of your files: pass the `--link` flag to `sync` to do so. 15 + 16 + ## Compiling 17 + 18 + You need a [Rust](https://rustup.rs/) compiler. 19 + 20 + Once you have that setup: 21 + 22 + ```sh 23 + git clone https://github.com/gsora/tracksync 24 + cd tracksync 25 + cargo build --release 26 + ./target/release/tracksync -h 27 + ``` 28 + 29 + ## Filtering 30 + 31 + You might want to exclude some tracks from the syncing process, based on various assumption. 32 + 33 + Since this tool has been built primarily for my own consumption, I added a programmable way of defining filters. 34 + 35 + Each destination can contain a filter written in the [Rhai](https://rhai.rs/): you have the full 36 + power of a regex matching function -- `regex_match` -- and a Turing-complete programming language, have fun! 37 + 38 + Filters can be created in-place or read from a file. 39 + 40 + Each filter must define the `filter(track)` function in order to be evaluated: 41 + 42 + ```rhai 43 + fn filter(track) { 44 + // your logic goes here 45 + true 46 + } 47 + ``` 48 + 49 + As you can see, `filter` returns a boolean value: 50 + - `true`: copy this track 51 + - `false`: the opposite 52 + 53 + The `track` argument is an object that contains the following fields: 54 + 55 + ```rust 56 + pub struct BaseTrack { 57 + pub title: String, 58 + pub artist: String, 59 + pub album: String, 60 + pub number: i64, 61 + pub file_path: String, 62 + pub disc_number: i64, 63 + pub disc_total: i64, 64 + pub extension: String, 65 + } 66 + ``` 67 + 68 + As you can see, there's lots of stuff you can do with this functionality. 69 + 70 + For example, here's a filter I built to avoid copying instrumental tracks from special edition albums: 71 + 72 + ```rhai 73 + fn filter(track) { 74 + track.title.make_lower(); 75 + track.artist.make_lower(); 76 + 77 + let excluded_artists = [ 78 + "periphery", 79 + "i built the sky", 80 + "anup sastry", 81 + "louis cole", 82 + "vulfpeck" 83 + ]; 84 + 85 + for ea in excluded_artists { 86 + if track.artist == ea { 87 + return false 88 + } 89 + } 90 + 91 + regex_match("instru*", track.title) 92 + } 93 + ``` 94 + 95 + ## A note on stability 96 + 97 + This is the first CLI tool I wrote in Rust, as a way of making myself familiar with the language: expect bugs. 98 + 99 + The database schema might break suddenly, making your source and destination(s) libraries unusable: a `rescan` command 100 + is in the works -- I will make sure to keep those at a minimum.