aboutsummaryrefslogtreecommitdiffstats
path: root/src/daemon.rs
diff options
context:
space:
mode:
authorsalmonik <raisersoft@proton.me>2026-06-04 00:21:46 +0200
committersalmonik <raisersoft@proton.me>2026-06-04 00:21:46 +0200
commit1e48765ab39a679abcc4eac6927ad3bb58f7b438 (patch)
tree5554f2a06bde693d4d9c39ed26f80677d61da991 /src/daemon.rs
parentfix no metadata songs handling (diff)
downloadrsplayer-1e48765ab39a679abcc4eac6927ad3bb58f7b438.tar.gz
rsplayer-1e48765ab39a679abcc4eac6927ad3bb58f7b438.zip
dirty, broken commit
Diffstat (limited to '')
-rw-r--r--src/daemon.rs183
1 files changed, 160 insertions, 23 deletions
diff --git a/src/daemon.rs b/src/daemon.rs
index c794495..d34305a 100644
--- a/src/daemon.rs
+++ b/src/daemon.rs
@@ -747,30 +747,40 @@ fn process_command(
747 } else { 747 } else {
748 match Config::load() { 748 match Config::load() {
749 Ok(config) => match crate::database::Database::open(&config) { 749 Ok(config) => match crate::database::Database::open(&config) {
750 Ok(db) => match db.search_tracks(query_str) { 750 Ok(db) => {
751 Ok(tracks) if !tracks.is_empty() => { 751 let tracks = match db.resolve_path(query_str) {
752 let db_track = &tracks[0]; 752 Ok(Some(t)) => t,
753 let album_tracks = db 753 Ok(None) => match db.search_tracks(query_str) {
754 .get_album_tracks_after( 754 Ok(t) => t,
755 db_track.album_id, 755 Err(e) => return format!("Database error: {}\n", e),
756 db_track.track_number, 756 },
757 &db_track.path, 757 Err(e) => return format!("Database error: {}\n", e),
758 ) 758 };
759 .unwrap_or_default(); 759 if tracks.is_empty() {
760 let display = format!(
761 "{} - {}",
762 db_track.artist_name.as_deref().unwrap_or("unknown"),
763 db_track.title,
764 );
765 let paths: Vec<PathBuf> =
766 album_tracks.into_iter().map(|t| t.path).collect();
767 (db_track.path.clone(), paths, display)
768 }
769 Ok(_) => {
770 return format!("No tracks found matching '{}'\n", query_str); 760 return format!("No tracks found matching '{}'\n", query_str);
771 } 761 }
772 Err(e) => return format!("Database error: {}\n", e), 762 let db_track = &tracks[0];
773 }, 763 let album_paths: Vec<PathBuf> = if tracks.len() > 1 {
764 // resolve_path returned full album — use remaining tracks
765 tracks[1..].iter().map(|t| t.path.clone()).collect()
766 } else {
767 db.get_album_tracks_after(
768 db_track.album_id,
769 db_track.track_number,
770 &db_track.path,
771 )
772 .unwrap_or_default()
773 .into_iter()
774 .map(|t| t.path)
775 .collect()
776 };
777 let display = format!(
778 "{} - {}",
779 db_track.artist_name.as_deref().unwrap_or("unknown"),
780 db_track.title,
781 );
782 (db_track.path.clone(), album_paths, display)
783 }
774 Err(e) => return format!("Database error: {}\n", e), 784 Err(e) => return format!("Database error: {}\n", e),
775 }, 785 },
776 Err(e) => return format!("Config error: {}\n", e), 786 Err(e) => return format!("Config error: {}\n", e),
@@ -862,6 +872,8 @@ fn process_command(
862 } else { 872 } else {
863 path_str.to_string() 873 path_str.to_string()
864 }; 874 };
875 // Strip trailing slash so autocompleted Artist/Album/ resolves cleanly
876 let path_str = path_str.trim_end_matches('/').to_string();
865 877
866 if path_str.is_empty() { 878 if path_str.is_empty() {
867 return "Usage: play [now|next|last] <path>\n".to_string(); 879 return "Usage: play [now|next|last] <path>\n".to_string();
@@ -1052,7 +1064,132 @@ fn process_command(
1052 _ => format!("Error: No audio files found in '{}'\n", path_str), 1064 _ => format!("Error: No audio files found in '{}'\n", path_str),
1053 } 1065 }
1054 } else { 1066 } else {
1055 format!("File not found: {}\n", path_str) 1067 match Config::load() {
1068 Ok(config) => match crate::database::Database::open(&config) {
1069 Ok(db) => {
1070 // Collect tracks: try hierarchical path first, fallback to search
1071 let tracks = match db.resolve_path(&path_str) {
1072 Ok(Some(t)) => t,
1073 Ok(None) => {
1074 let query = path_str
1075 .rsplit_once('/')
1076 .and_then(|(_, after)| {
1077 (!after.is_empty()).then_some(after)
1078 })
1079 .unwrap_or(&path_str);
1080 match db.search_tracks(query) {
1081 Ok(t) => t,
1082 Err(e) => return format!("Database error: {}\n", e),
1083 }
1084 }
1085 Err(e) => return format!("Database error: {}\n", e),
1086 };
1087
1088 if tracks.is_empty() {
1089 return format!("No tracks found matching '{}'\n", path_str);
1090 }
1091
1092 let is_album_play = tracks.len() > 1;
1093 if let Ok(mut q) = queue.lock() {
1094 let was_empty = q.is_empty();
1095 match position {
1096 "now" => {
1097 if let Ok(mut s) = scrobble_state.lock() {
1098 try_scrobble_current(scrobbler, &mut s);
1099 }
1100 for t in tracks.iter().rev() {
1101 q.insert_after_current(t.path.clone());
1102 }
1103 if !was_empty {
1104 let new_pos = q.position() + 1;
1105 q.set_position(new_pos);
1106 }
1107 if let Some(track) = q.track_at(q.position()) {
1108 audio.play(track.path.clone());
1109 send_now_playing(scrobbler, track);
1110 if let Ok(mut s) = scrobble_state.lock() {
1111 s.start(track.clone());
1112 }
1113 let fmt = Config::load()
1114 .ok()
1115 .and_then(|c| c.display_format.clone());
1116 notification::notify_track(track, fmt.as_deref());
1117 }
1118 if is_album_play {
1119 format!(
1120 "Playing now: {} tracks from {}\n",
1121 tracks.len(),
1122 path_str
1123 )
1124 } else {
1125 format!("Playing now: {}\n", path_str)
1126 }
1127 }
1128 "next" => {
1129 for t in tracks.iter().rev() {
1130 q.insert_after_current(t.path.clone());
1131 }
1132 if is_album_play {
1133 format!(
1134 "Queued next: {} tracks from {}\n",
1135 tracks.len(),
1136 path_str
1137 )
1138 } else {
1139 format!("Queued next: {}\n", path_str)
1140 }
1141 }
1142 _ => {
1143 let was_playing = audio.is_playing();
1144 for t in &tracks {
1145 q.add_track(t.path.clone());
1146 }
1147 if was_empty && !was_playing {
1148 if is_album_play {
1149 q.shuffle_initial();
1150 }
1151 if let Some(track) = q.current() {
1152 audio.play(track.path.clone());
1153 send_now_playing(scrobbler, track);
1154 if let Ok(mut s) = scrobble_state.lock() {
1155 s.start(track.clone());
1156 }
1157 let fmt = Config::load()
1158 .ok()
1159 .and_then(|c| c.display_format.clone());
1160 notification::notify_track(
1161 track,
1162 fmt.as_deref(),
1163 );
1164 }
1165 if is_album_play {
1166 format!(
1167 "Playing: {} tracks from {}\n",
1168 tracks.len(),
1169 path_str
1170 )
1171 } else {
1172 format!("Playing: {}\n", path_str)
1173 }
1174 } else if is_album_play {
1175 format!(
1176 "Queued {} tracks from: {}\n",
1177 tracks.len(),
1178 path_str
1179 )
1180 } else {
1181 format!("Queued: {}\n", path_str)
1182 }
1183 }
1184 }
1185 } else {
1186 "Error accessing queue\n".to_string()
1187 }
1188 }
1189 Err(e) => format!("Database error: {}\n", e),
1190 },
1191 Err(e) => format!("Config error: {}\n", e),
1192 }
1056 } 1193 }
1057 } 1194 }
1058 } 1195 }