1
0
Fork 0
mirror of https://github.com/fiso64/slsk-batchdl.git synced 2024-12-22 14:32:40 +00:00
This commit is contained in:
fiso64 2024-08-30 22:01:10 +02:00
parent 8cf3016e6b
commit 95d6cb7493
8 changed files with 54 additions and 24 deletions

View file

@ -56,6 +56,7 @@ Usage: sldl <input> [OPTIONS]
'index' (default): Write a line indexing all downloaded 'index' (default): Write a line indexing all downloaded
files, required for skip-not-found or skip-existing=m3u files, required for skip-not-found or skip-existing=m3u
'all': Write the index and a list of paths and fails 'all': Write the index and a list of paths and fails
--m3u-path <path> Override default m3u path
-s, --skip-existing Skip if a track matching file conditions is found in the -s, --skip-existing Skip if a track matching file conditions is found in the
output folder or your music library (if provided) output folder or your music library (if provided)
@ -558,7 +559,7 @@ sldl "title=MC MENTAL @ HIS BEST,length=242" --pref-format "flac,wav"
Interactive album download: Interactive album download:
``` ```
sldl "album=Some Album" --interactive sldl "Some Album" --album --interactive
``` ```
<br> <br>
@ -568,10 +569,23 @@ sldl "artist=MC MENTAL" --aggregate --skip-existing --music-dir "path/to/music"
``` ```
<br> <br>
Download all albums by an artist that are on soulseek: Download all albums by an artist found on soulseek:
``` ```
sldl "artist=MC MENTAL" --aggregate --album sldl "artist=MC MENTAL" --aggregate --album
``` ```
<hr style="height:0px; visibility:hidden;" />
#### Advanced example: Automatic wishlist downloader
Create a file named wishlist.txt, and add your wishlist items:
```bash
echo title=My Favorite Song, artist=Artist >> wishlist.txt
echo https://spotify/album/url >> wishlist.txt
```
Set up a cron job (or scheduled task on windows) to periodically run sldl on every line of the wishlist file with the following options:
```
--skip-existing --skip-mode m3u --m3u index --m3u-path wishlist-archive.sldl
```
You can also use m3u-cond and specify some preferred conditions to e.g only stop searching for an item once a lossless version is downloaded.
## Notes ## Notes
- For macOS builds you can use publish.sh to build the app. Download dotnet from https://dotnet.microsoft.com/en-us/download/dotnet/6.0, then run `chmod +x publish.sh && sh publish.sh`. For intel macs, uncomment the x64 and comment the arm64 section in publish.sh. - For macOS builds you can use publish.sh to build the app. Download dotnet from https://dotnet.microsoft.com/en-us/download/dotnet/6.0, then run `chmod +x publish.sh && sh publish.sh`. For intel macs, uncomment the x64 and comment the arm64 section in publish.sh.

View file

@ -1,8 +0,0 @@
- configuration profiles, auto-profiles
- album aggregate download mode
- automatically browse user shares during album downloads to guarantee that all files from the parent folder are downloaded
- skip-existing is now much faster. Default mode is now m3u as it is more reliable. Changed how m3u skip-existing works (not backward compatible). Added `m3u-cond` skip mode. m3u modes can now skip album downloads.
- can now download entire bandcamp artist discographies
- added `--on-complete` to run a command whenever a file is downloaded
- now also looks in the user config directories for `sldl.conf`
- many bug fixes

View file

@ -846,6 +846,10 @@ static class Config
_ => throw new ArgumentException($"Invalid m3u option '{args[i]}'"), _ => throw new ArgumentException($"Invalid m3u option '{args[i]}'"),
}; };
break; break;
case "--m3up":
case "--m3u-path":
m3uFilePath = args[++i];
break;
case "--lp": case "--lp":
case "--port": case "--port":
case "--listen-port": case "--listen-port":

View file

@ -47,7 +47,7 @@ namespace Data
Other = other.Other; Other = other.Other;
MinAlbumTrackCount = other.MinAlbumTrackCount; MinAlbumTrackCount = other.MinAlbumTrackCount;
MaxAlbumTrackCount = other.MaxAlbumTrackCount; MaxAlbumTrackCount = other.MaxAlbumTrackCount;
CsvRow = other.CsvRow; //CsvRow = other.CsvRow;
} }
public string ToKey() public string ToKey()

View file

@ -47,12 +47,19 @@ namespace Extractors
{ {
if (File.Exists(Config.input)) if (File.Exists(Config.input))
{ {
string[] lines = File.ReadAllLines(Config.input, System.Text.Encoding.UTF8); try
if (lines.Length > track.CsvRow)
{ {
lines[track.CsvRow] = new string(',', Math.Max(0, csvColumnCount - 1)); string[] lines = File.ReadAllLines(Config.input, System.Text.Encoding.UTF8);
Utils.WriteAllLines(Config.input, lines, '\n');
if (track.CsvRow > -1 && track.CsvRow < lines.Length)
{
lines[track.CsvRow] = new string(',', Math.Max(0, csvColumnCount - 1));
Utils.WriteAllLines(Config.input, lines, '\n');
}
}
catch (Exception e)
{
Printing.WriteLine($"Error removing from source: {e}", debugOnly: true);
} }
} }
} }

View file

@ -106,8 +106,15 @@ namespace Extractors
public async Task RemoveTrackFromSource(Track track) public async Task RemoveTrackFromSource(Track track)
{ {
if (playlistUri.Length > 0 && track.URI.Length > 0) try
await spotifyClient.RemoveTrackFromPlaylist(playlistUri, track.URI); {
if (playlistUri.Length > 0 && track.URI.Length > 0)
await spotifyClient.RemoveTrackFromPlaylist(playlistUri, track.URI);
}
catch (Exception e)
{
Printing.WriteLine($"Error removing from source: {e}", debugOnly: true);
}
} }
} }

View file

@ -34,6 +34,7 @@ public static class Help
'index' (default): Write a line indexing all downloaded 'index' (default): Write a line indexing all downloaded
files, required for skip-not-found or skip-existing=m3u files, required for skip-not-found or skip-existing=m3u
'all': Write the index and a list of paths and fails 'all': Write the index and a list of paths and fails
--m3u-path <path> Override default m3u path
-s, --skip-existing Skip if a track matching file conditions is found in the -s, --skip-existing Skip if a track matching file conditions is found in the
output folder or your music library (if provided) output folder or your music library (if provided)

View file

@ -416,7 +416,7 @@ static partial class Program
var downloadTasks = tracks.Select(async (track, index) => var downloadTasks = tracks.Select(async (track, index) =>
{ {
await DownloadTask(tle, track, semaphore, organizer, null, false); await DownloadTask(tle, track, semaphore, organizer, null, false, true);
m3uEditor.Update(); m3uEditor.Update();
}); });
@ -469,7 +469,7 @@ static partial class Program
{ {
var downloadTasks = tracks.Select(async track => var downloadTasks = tracks.Select(async track =>
{ {
await DownloadTask(tle, track, semaphore, organizer, cts, cancelOnFail: !Config.albumIgnoreFails); await DownloadTask(tle, track, semaphore, organizer, cts, cancelOnFail: !Config.albumIgnoreFails, true);
}); });
await Task.WhenAll(downloadTasks); await Task.WhenAll(downloadTasks);
@ -491,7 +491,7 @@ static partial class Program
tle.list.RemoveAt(index); tle.list.RemoveAt(index);
} }
if (tracks != null) if (tracks != null && succeeded)
{ {
var downloadedAudio = tracks.Where(t => !t.IsNotAudio && t.State == TrackState.Downloaded && t.DownloadPath.Length > 0); var downloadedAudio = tracks.Where(t => !t.IsNotAudio && t.State == TrackState.Downloaded && t.DownloadPath.Length > 0);
@ -499,6 +499,11 @@ static partial class Program
{ {
tle.source.State = TrackState.Downloaded; tle.source.State = TrackState.Downloaded;
tle.source.DownloadPath = Utils.GreatestCommonDirectory(downloadedAudio.Select(t => t.DownloadPath)); tle.source.DownloadPath = Utils.GreatestCommonDirectory(downloadedAudio.Select(t => t.DownloadPath));
if (Config.removeTracksFromSource)
{
await extractor.RemoveTrackFromSource(tle.source);
}
} }
} }
@ -620,7 +625,7 @@ static partial class Program
foreach (var track in tracks) foreach (var track in tracks)
{ {
await DownloadTask(null, track, semaphore, organizer, null, false); await DownloadTask(null, track, semaphore, organizer, null, false, false);
if (track.State == TrackState.Downloaded) if (track.State == TrackState.Downloaded)
downloadedImages.Add(track); downloadedImages.Add(track);
@ -636,7 +641,7 @@ static partial class Program
} }
static async Task DownloadTask(TrackListEntry? tle, Track track, SemaphoreSlim semaphore, FileManager organizer, CancellationTokenSource? cts, bool cancelOnFail) static async Task DownloadTask(TrackListEntry? tle, Track track, SemaphoreSlim semaphore, FileManager organizer, CancellationTokenSource? cts, bool cancelOnFail, bool removeFromSource)
{ {
if (track.State != TrackState.Initial) if (track.State != TrackState.Initial)
return; return;
@ -706,7 +711,7 @@ static partial class Program
track.DownloadPath = savedFilePath; track.DownloadPath = savedFilePath;
} }
if (Config.removeTracksFromSource) if (removeFromSource && Config.removeTracksFromSource)
{ {
try try
{ {