[READ-ONLY] Mirror of https://github.com/probablykasper/ferrum. Music library app for Mac, Linux and Windows ferrum.kasper.space
electron linux macos music music-library music-player napi windows
0

Configure Feed

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

Keep old play times separated

Kasper (Apr 12, 2023, 12:39 AM +0200) 29bb84b7 1187fde1

+46 -5
+6 -4
src-native/library.rs
··· 1 - use crate::library_types::Library; 1 + use crate::library_types::{Library, VersionedLibrary}; 2 2 use serde::{Deserialize, Serialize}; 3 3 use std::fs::{create_dir_all, File}; 4 4 use std::io::{Error, ErrorKind, Read}; ··· 29 29 Err(err) => panic!("Error ensuring folder exists: {}", err), 30 30 }; 31 31 32 - match File::open(&paths.library_json) { 32 + let versioned_library = match File::open(&paths.library_json) { 33 33 Ok(mut file) => { 34 34 let mut json_str = String::new(); 35 35 match file.read_to_string(&mut json_str) { ··· 39 39 println!("Read library: {}ms", now.elapsed().as_millis()); 40 40 now = Instant::now(); 41 41 42 - let library = match serde_json::from_str(&mut json_str) { 42 + let versioned_library: VersionedLibrary = match serde_json::from_str(&mut json_str) { 43 43 Ok(library) => library, 44 44 Err(err) => panic!("Error parsing library file: {:?}", err), 45 45 }; 46 46 47 47 println!("Parse library: {}ms", now.elapsed().as_millis()); 48 - return library; 48 + versioned_library 49 49 } 50 50 Err(err) => match err.kind() { 51 51 ErrorKind::NotFound => { ··· 54 54 _err_kind => panic!("Error opening library file: {}", err), 55 55 }, 56 56 }; 57 + 58 + versioned_library.into_latest() 57 59 } 58 60 59 61 pub enum TrackField {
+40 -1
src-native/library_types.rs
··· 10 10 #[derive(Serialize, Deserialize, Clone, Debug)] 11 11 #[serde(deny_unknown_fields)] 12 12 pub struct Library { 13 + pub tracks: LinkedHashMap<TrackID, Track>, 14 + pub trackLists: TrackLists, 15 + /// v1 playtime has two issues: 16 + /// - some durations are double counted (or triple, etc.) 17 + /// - timestamps aren't updated after pausing 18 + pub v1PlayTime: Vec<PlayTime>, 19 + pub playTime: Vec<PlayTime>, 20 + } 21 + 22 + #[derive(Serialize, Deserialize, Clone, Debug)] 23 + #[serde(tag = "version", deny_unknown_fields)] 24 + pub enum VersionedLibrary { 25 + #[serde(rename = "1")] 26 + V1(V1Library), 27 + #[serde(rename = "2")] 28 + V2(Library), 29 + } 30 + impl VersionedLibrary { 31 + pub fn into_latest(self) -> Library { 32 + match self { 33 + VersionedLibrary::V1(v1) => v1.into_v2(), 34 + VersionedLibrary::V2(v2) => v2, 35 + } 36 + } 37 + } 38 + 39 + #[derive(Serialize, Deserialize, Clone, Debug)] 40 + #[serde(deny_unknown_fields)] 41 + pub struct V1Library { 13 42 pub version: Version, 14 43 pub tracks: LinkedHashMap<TrackID, Track>, 15 44 pub trackLists: TrackLists, 16 45 pub playTime: Vec<PlayTime>, 17 46 } 47 + impl V1Library { 48 + pub fn into_v2(self) -> Library { 49 + Library { 50 + tracks: self.tracks, 51 + trackLists: self.trackLists, 52 + v1PlayTime: self.playTime, 53 + playTime: Vec::new(), 54 + } 55 + } 56 + } 18 57 19 58 impl Library { 20 59 pub fn new() -> Self { ··· 27 66 }; 28 67 track_lists.insert("root".to_string(), TrackList::Special(root)); 29 68 Library { 30 - version: Version::V1, 69 + v1PlayTime: Vec::new(), 31 70 playTime: Vec::new(), 32 71 tracks: LinkedHashMap::new(), 33 72 trackLists: track_lists,