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.

gpod: write SysInfoExtended by leveraging libgpod tooling

Gee Sawra 64dc9d46 906a3222

+279 -52
+215 -26
Cargo.lock
··· 428 428 ] 429 429 430 430 [[package]] 431 + name = "cfb" 432 + version = "0.7.3" 433 + source = "registry+https://github.com/rust-lang/crates.io-index" 434 + checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" 435 + dependencies = [ 436 + "byteorder", 437 + "fnv", 438 + "uuid", 439 + ] 440 + 441 + [[package]] 431 442 name = "cfg-expr" 432 443 version = "0.20.5" 433 444 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 828 839 ] 829 840 830 841 [[package]] 842 + name = "fnv" 843 + version = "1.0.7" 844 + source = "registry+https://github.com/rust-lang/crates.io-index" 845 + checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 846 + 847 + [[package]] 831 848 name = "form_urlencoded" 832 849 version = "1.2.1" 833 850 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1225 1242 ] 1226 1243 1227 1244 [[package]] 1245 + name = "infer" 1246 + version = "0.19.0" 1247 + source = "registry+https://github.com/rust-lang/crates.io-index" 1248 + checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" 1249 + dependencies = [ 1250 + "cfb", 1251 + ] 1252 + 1253 + [[package]] 1228 1254 name = "instant" 1229 1255 version = "0.1.13" 1230 1256 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1267 1293 1268 1294 [[package]] 1269 1295 name = "js-sys" 1270 - version = "0.3.69" 1296 + version = "0.3.83" 1271 1297 source = "registry+https://github.com/rust-lang/crates.io-index" 1272 - checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" 1298 + checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" 1273 1299 dependencies = [ 1300 + "once_cell", 1274 1301 "wasm-bindgen", 1275 1302 ] 1276 1303 ··· 1305 1332 checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" 1306 1333 dependencies = [ 1307 1334 "cfg-if", 1308 - "windows-link", 1335 + "windows-link 0.2.1", 1309 1336 ] 1310 1337 1311 1338 [[package]] ··· 1447 1474 ] 1448 1475 1449 1476 [[package]] 1477 + name = "ntapi" 1478 + version = "0.4.2" 1479 + source = "registry+https://github.com/rust-lang/crates.io-index" 1480 + checksum = "c70f219e21142367c70c0b30c6a9e3a14d55b4d12a204d897fbec83a0363f081" 1481 + dependencies = [ 1482 + "winapi", 1483 + ] 1484 + 1485 + [[package]] 1450 1486 name = "num-bigint-dig" 1451 1487 version = "0.8.4" 1452 1488 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1508 1544 version = "0.4.0" 1509 1545 source = "registry+https://github.com/rust-lang/crates.io-index" 1510 1546 checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" 1547 + 1548 + [[package]] 1549 + name = "objc2-core-foundation" 1550 + version = "0.3.2" 1551 + source = "registry+https://github.com/rust-lang/crates.io-index" 1552 + checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" 1553 + dependencies = [ 1554 + "bitflags 2.10.0", 1555 + ] 1556 + 1557 + [[package]] 1558 + name = "objc2-io-kit" 1559 + version = "0.3.2" 1560 + source = "registry+https://github.com/rust-lang/crates.io-index" 1561 + checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15" 1562 + dependencies = [ 1563 + "libc", 1564 + "objc2-core-foundation", 1565 + ] 1511 1566 1512 1567 [[package]] 1513 1568 name = "object" ··· 1948 2003 ] 1949 2004 1950 2005 [[package]] 2006 + name = "rustversion" 2007 + version = "1.0.22" 2008 + source = "registry+https://github.com/rust-lang/crates.io-index" 2009 + checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" 2010 + 2011 + [[package]] 1951 2012 name = "ryu" 1952 2013 version = "1.0.18" 1953 2014 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2398 2459 ] 2399 2460 2400 2461 [[package]] 2462 + name = "sysinfo" 2463 + version = "0.37.2" 2464 + source = "registry+https://github.com/rust-lang/crates.io-index" 2465 + checksum = "16607d5caffd1c07ce073528f9ed972d88db15dd44023fa57142963be3feb11f" 2466 + dependencies = [ 2467 + "libc", 2468 + "memchr", 2469 + "ntapi", 2470 + "objc2-core-foundation", 2471 + "objc2-io-kit", 2472 + "windows", 2473 + ] 2474 + 2475 + [[package]] 2401 2476 name = "system-deps" 2402 2477 version = "7.0.7" 2403 2478 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2598 2673 "futures", 2599 2674 "glib", 2600 2675 "indicatif", 2676 + "infer", 2601 2677 "libc", 2602 2678 "log", 2603 2679 "num_cpus", ··· 2610 2686 "similar-string", 2611 2687 "sqlx", 2612 2688 "string-builder", 2689 + "sysinfo", 2613 2690 "tempdir", 2614 2691 "walkdir", 2615 2692 ] ··· 2689 2766 checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 2690 2767 2691 2768 [[package]] 2769 + name = "uuid" 2770 + version = "1.19.0" 2771 + source = "registry+https://github.com/rust-lang/crates.io-index" 2772 + checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" 2773 + dependencies = [ 2774 + "js-sys", 2775 + "wasm-bindgen", 2776 + ] 2777 + 2778 + [[package]] 2692 2779 name = "value-bag" 2693 2780 version = "1.9.0" 2694 2781 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2742 2829 2743 2830 [[package]] 2744 2831 name = "wasm-bindgen" 2745 - version = "0.2.92" 2832 + version = "0.2.106" 2746 2833 source = "registry+https://github.com/rust-lang/crates.io-index" 2747 - checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" 2834 + checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" 2748 2835 dependencies = [ 2749 2836 "cfg-if", 2837 + "once_cell", 2838 + "rustversion", 2750 2839 "wasm-bindgen-macro", 2751 - ] 2752 - 2753 - [[package]] 2754 - name = "wasm-bindgen-backend" 2755 - version = "0.2.92" 2756 - source = "registry+https://github.com/rust-lang/crates.io-index" 2757 - checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" 2758 - dependencies = [ 2759 - "bumpalo", 2760 - "log", 2761 - "once_cell", 2762 - "proc-macro2", 2763 - "quote", 2764 - "syn 2.0.114", 2765 2840 "wasm-bindgen-shared", 2766 2841 ] 2767 2842 ··· 2779 2854 2780 2855 [[package]] 2781 2856 name = "wasm-bindgen-macro" 2782 - version = "0.2.92" 2857 + version = "0.2.106" 2783 2858 source = "registry+https://github.com/rust-lang/crates.io-index" 2784 - checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" 2859 + checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" 2785 2860 dependencies = [ 2786 2861 "quote", 2787 2862 "wasm-bindgen-macro-support", ··· 2789 2864 2790 2865 [[package]] 2791 2866 name = "wasm-bindgen-macro-support" 2792 - version = "0.2.92" 2867 + version = "0.2.106" 2793 2868 source = "registry+https://github.com/rust-lang/crates.io-index" 2794 - checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" 2869 + checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" 2795 2870 dependencies = [ 2871 + "bumpalo", 2796 2872 "proc-macro2", 2797 2873 "quote", 2798 2874 "syn 2.0.114", 2799 - "wasm-bindgen-backend", 2800 2875 "wasm-bindgen-shared", 2801 2876 ] 2802 2877 2803 2878 [[package]] 2804 2879 name = "wasm-bindgen-shared" 2805 - version = "0.2.92" 2880 + version = "0.2.106" 2806 2881 source = "registry+https://github.com/rust-lang/crates.io-index" 2807 - checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" 2882 + checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" 2883 + dependencies = [ 2884 + "unicode-ident", 2885 + ] 2808 2886 2809 2887 [[package]] 2810 2888 name = "web-sys" ··· 2870 2948 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2871 2949 2872 2950 [[package]] 2951 + name = "windows" 2952 + version = "0.61.3" 2953 + source = "registry+https://github.com/rust-lang/crates.io-index" 2954 + checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" 2955 + dependencies = [ 2956 + "windows-collections", 2957 + "windows-core", 2958 + "windows-future", 2959 + "windows-link 0.1.3", 2960 + "windows-numerics", 2961 + ] 2962 + 2963 + [[package]] 2964 + name = "windows-collections" 2965 + version = "0.2.0" 2966 + source = "registry+https://github.com/rust-lang/crates.io-index" 2967 + checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" 2968 + dependencies = [ 2969 + "windows-core", 2970 + ] 2971 + 2972 + [[package]] 2973 + name = "windows-core" 2974 + version = "0.61.2" 2975 + source = "registry+https://github.com/rust-lang/crates.io-index" 2976 + checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" 2977 + dependencies = [ 2978 + "windows-implement", 2979 + "windows-interface", 2980 + "windows-link 0.1.3", 2981 + "windows-result", 2982 + "windows-strings", 2983 + ] 2984 + 2985 + [[package]] 2986 + name = "windows-future" 2987 + version = "0.2.1" 2988 + source = "registry+https://github.com/rust-lang/crates.io-index" 2989 + checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" 2990 + dependencies = [ 2991 + "windows-core", 2992 + "windows-link 0.1.3", 2993 + "windows-threading", 2994 + ] 2995 + 2996 + [[package]] 2997 + name = "windows-implement" 2998 + version = "0.60.2" 2999 + source = "registry+https://github.com/rust-lang/crates.io-index" 3000 + checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" 3001 + dependencies = [ 3002 + "proc-macro2", 3003 + "quote", 3004 + "syn 2.0.114", 3005 + ] 3006 + 3007 + [[package]] 3008 + name = "windows-interface" 3009 + version = "0.59.3" 3010 + source = "registry+https://github.com/rust-lang/crates.io-index" 3011 + checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" 3012 + dependencies = [ 3013 + "proc-macro2", 3014 + "quote", 3015 + "syn 2.0.114", 3016 + ] 3017 + 3018 + [[package]] 3019 + name = "windows-link" 3020 + version = "0.1.3" 3021 + source = "registry+https://github.com/rust-lang/crates.io-index" 3022 + checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" 3023 + 3024 + [[package]] 2873 3025 name = "windows-link" 2874 3026 version = "0.2.1" 2875 3027 source = "registry+https://github.com/rust-lang/crates.io-index" 2876 3028 checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" 2877 3029 2878 3030 [[package]] 3031 + name = "windows-numerics" 3032 + version = "0.2.0" 3033 + source = "registry+https://github.com/rust-lang/crates.io-index" 3034 + checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" 3035 + dependencies = [ 3036 + "windows-core", 3037 + "windows-link 0.1.3", 3038 + ] 3039 + 3040 + [[package]] 3041 + name = "windows-result" 3042 + version = "0.3.4" 3043 + source = "registry+https://github.com/rust-lang/crates.io-index" 3044 + checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" 3045 + dependencies = [ 3046 + "windows-link 0.1.3", 3047 + ] 3048 + 3049 + [[package]] 3050 + name = "windows-strings" 3051 + version = "0.4.2" 3052 + source = "registry+https://github.com/rust-lang/crates.io-index" 3053 + checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" 3054 + dependencies = [ 3055 + "windows-link 0.1.3", 3056 + ] 3057 + 3058 + [[package]] 2879 3059 name = "windows-sys" 2880 3060 version = "0.48.0" 2881 3061 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2922 3102 "windows_x86_64_gnu 0.52.5", 2923 3103 "windows_x86_64_gnullvm 0.52.5", 2924 3104 "windows_x86_64_msvc 0.52.5", 3105 + ] 3106 + 3107 + [[package]] 3108 + name = "windows-threading" 3109 + version = "0.1.0" 3110 + source = "registry+https://github.com/rust-lang/crates.io-index" 3111 + checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" 3112 + dependencies = [ 3113 + "windows-link 0.1.3", 2925 3114 ] 2926 3115 2927 3116 [[package]]
+2
Cargo.toml
··· 47 47 rusb = "0.9.4" 48 48 libc = "0.2.180" 49 49 tempdir = "0.3.7" 50 + infer = "0.19.0" 51 + sysinfo = "0.37.2"
+62 -26
src/gpod/gpod.rs
··· 1 - use std::{ffi::CString, os::linux::fs::MetadataExt, path::PathBuf, ptr}; 1 + use std::{ 2 + ffi::CString, 3 + os::linux::fs::MetadataExt, 4 + path::{Path, PathBuf}, 5 + ptr, 6 + }; 2 7 3 8 use crate::model::Track; 4 9 ··· 91 96 let mut error: *mut GError = ptr::null_mut(); 92 97 let path = CString::new(file.display().to_string()).unwrap(); 93 98 if let Some(art) = track.artwork_path.clone() { 94 - log::info!("adding album art: {}", art); 95 99 let art = CString::new(art).unwrap(); 96 100 if itdb_track_set_thumbnails(ipod_track, art.as_ptr()) != 1 { 97 101 log::warn!("could not add album art to track") ··· 132 136 pub fn initialize(path: String, model: String) -> Result<()> { 133 137 unsafe { 134 138 g_type_init(); 135 - let mountpoint = std::ffi::CString::new(path).unwrap(); 139 + let mountpoint = std::ffi::CString::new(path.clone()).unwrap(); 136 140 let model = std::ffi::CString::new(model).unwrap(); 137 141 138 142 let mut error: *mut GError = ptr::null_mut(); ··· 152 156 153 157 let serials = rusb::devices()? 154 158 .iter() 155 - .filter(|d| { 156 - let dd = d.device_descriptor(); 157 - let d = d.open(); 158 - if d.is_err() { 159 - return false; 159 + .filter_map(|d| { 160 + let dd = d.device_descriptor().ok()?; 161 + 162 + if dd.vendor_id() != 0x05ac { 163 + return None; 160 164 } 161 - let d = d.unwrap(); 162 165 163 - if let Ok(dd) = dd { 164 - match dd.serial_number_string_index() { 165 - Some(_) => (), 166 - None => return false, 167 - }; 166 + dd.serial_number_string_index()?; 167 + 168 + let handle = d.open().ok()?; 169 + 170 + let dd = handle.device().device_descriptor().ok()?; 168 171 169 - let product_str = d.read_product_string_ascii(&dd).unwrap(); 170 - let serial_str = d.read_serial_number_string_ascii(&dd).unwrap(); 172 + let product_str = handle.read_product_string_ascii(&dd).ok()?; 173 + let serial_str = handle.read_serial_number_string_ascii(&dd).ok()?; 171 174 172 - return dd.vendor_id() == 0x05ac 173 - && product_str == "iPod" 174 - && !serial_str.is_empty(); 175 + if product_str == "iPod" && !serial_str.is_empty() { 176 + Some(serial_str) 175 177 } else { 176 - return false; 178 + None 177 179 } 178 180 }) 179 - .map(|d| { 180 - let d = d.open().unwrap(); 181 - let dd = d.device().device_descriptor().unwrap(); 182 - 183 - d.read_serial_number_string_ascii(&dd).unwrap() 184 - }) 185 181 .collect::<Vec<String>>(); 186 182 187 183 match serials.len() { ··· 214 210 } 215 211 } 216 212 213 + let mp = find_root_device(PathBuf::from(path.clone()).as_path()); 214 + 215 + if let Some(mp) = mp { 216 + log::debug!("root device for {}: {}", path, mp); 217 + let res = std::process::Command::new("ipod-read-sysinfo-extended") 218 + .arg(mp) 219 + .arg(path) 220 + .output()?; 221 + 222 + match res.status.success() { 223 + true => {} 224 + false => { 225 + return Err(anyhow!( 226 + "failed to initialize iPod SysInfoExtended, did you forget root?\n{}: {}", 227 + res.status, 228 + String::from_utf8(res.stdout).unwrap() 229 + )); 230 + } 231 + }; 232 + } else { 233 + log::warn!( 234 + "could not complete initialization, iPod is usable but album art might not work!" 235 + ) 236 + } 237 + 217 238 Ok(()) 218 239 } 240 + 241 + fn find_root_device(path: &Path) -> Option<String> { 242 + let disks = sysinfo::Disks::new_with_refreshed_list(); 243 + let canonical = path.canonicalize().ok()?; 244 + 245 + disks 246 + .iter() 247 + .filter(|disk| canonical.starts_with(disk.mount_point())) 248 + .max_by_key(|disk| disk.mount_point().as_os_str().len()) 249 + .map(|disk| disk.name().to_string_lossy().to_string()) 250 + .map(|disk| { 251 + disk.trim_end_matches(|c: char| c.is_ascii_digit()) 252 + .to_string() 253 + }) 254 + }