Skip to content

Commit

Permalink
Merge branch 'release-0.2.8.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
Otiel committed Apr 25, 2019
2 parents a011d37 + 0ce56ea commit cd91c47
Show file tree
Hide file tree
Showing 9 changed files with 246 additions and 138 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 0.2.8.2

## Bug fixes

* Fixed the track path stored in playlist files. [#82](https://github.com/Otiel/BandcampDownloader/issues/82)

# 0.2.8.1

## Bug fixes
Expand Down
4 changes: 4 additions & 0 deletions src/BandcampDownloader/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
namespace BandcampDownloader {

public partial class App: Application {
/// <summary>
/// Random class used to create random numbers.
/// </summary>
public static readonly Random Random = new Random();

/// <summary>
/// The settings chosen by the user.
Expand Down
8 changes: 4 additions & 4 deletions src/BandcampDownloader/Helpers/PlaylistHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ private static String CreateM3uPlaylist(Album album) {
Album = album.Title,
AlbumArtist = album.Artist,
Duration = TimeSpan.FromSeconds(track.Duration),
Path = track.Title + ".mp3",
Path = Path.GetFileName(track.Path),
Title = track.Title,
});
}
Expand All @@ -88,7 +88,7 @@ private static String CreatePlsPlaylist(Album album) {
foreach (Track track in album.Tracks) {
playlist.PlaylistEntries.Add(new PlsPlaylistEntry() {
Length = TimeSpan.FromSeconds(track.Duration),
Path = track.Title + ".mp3",
Path = Path.GetFileName(track.Path),
Title = track.Title,
});
}
Expand All @@ -110,7 +110,7 @@ private static String CreateWplPlaylist(Album album) {
AlbumArtist = album.Artist,
AlbumTitle = album.Title,
Duration = TimeSpan.FromSeconds(track.Duration),
Path = track.Title + ".mp3",
Path = Path.GetFileName(track.Path),
TrackArtist = album.Artist,
TrackTitle = track.Title,
});
Expand All @@ -133,7 +133,7 @@ private static String CreateZplPlaylist(Album album) {
AlbumArtist = album.Artist,
AlbumTitle = album.Title,
Duration = TimeSpan.FromSeconds(track.Duration),
Path = track.Title + ".mp3",
Path = Path.GetFileName(track.Path),
TrackArtist = album.Artist,
TrackTitle = track.Title,
});
Expand Down
111 changes: 111 additions & 0 deletions src/BandcampDownloader/Model/Album.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,128 @@
namespace BandcampDownloader {

internal class Album {

/// <summary>
/// The album artist.
/// </summary>
public String Artist { get; set; }

/// <summary>
/// The local path (full path with file name) where the artwork file should be saved.
/// </summary>
public String ArtworkPath { get; private set; }

/// <summary>
/// The local path (full path with file name) to the %TEMP% folder where the artwork file should be saved.
/// </summary>
public String ArtworkTempPath { get; private set; }

/// <summary>
/// The URL where the artwork should be downloaded from.
/// </summary>
public String ArtworkUrl { get; set; }

/// <summary>
/// True if the album has an artwork; false otherwise.
/// </summary>
public Boolean HasArtwork {
get {
return ArtworkUrl != null;
}
}

/// <summary>
/// The local path (full path) to the folder where the album should be saved.
/// </summary>
public String Path { get; private set; }

/// <summary>
/// The release date of the album.
/// </summary>
public DateTime ReleaseDate { get; set; }

/// <summary>
/// The album title.
/// </summary>
public String Title { get; set; }

/// <summary>
/// The list of tracks contained in the album.
/// </summary>
public List<Track> Tracks { get; set; }

/// <summary>
/// Initializes a new Album.
/// </summary>
public Album(String artist, String artworkUrl, DateTime releaseDate, String title) {
Artist = artist;
ArtworkUrl = artworkUrl;
ReleaseDate = releaseDate;
Title = title;
// Must be done after other properties are filled!
Path = ParseFolderPath(App.UserSettings.DownloadsPath);
SetArtworkPaths();
}

/// <summary>
/// Returns the file name to be used for the cover art of the specified album from the file name format saved in
/// the UserSettings, by replacing the placeholders strings with their corresponding values.
/// The returned file name does NOT contain the extension.
/// </summary>
private String ParseCoverArtFileName() {
String fileName = App.UserSettings.CoverArtFileNameFormat
.Replace("{year}", ReleaseDate.Year.ToString())
.Replace("{month}", ReleaseDate.Month.ToString("00"))
.Replace("{day}", ReleaseDate.Day.ToString("00"))
.Replace("{album}", Title)
.Replace("{artist}", Artist);
return fileName.ToAllowedFileName();
}

/// <summary>
/// Returns the folder path from the specified path format, by replacing the placeholders strings with their
/// corresponding values. If the path is too long (&gt; 247 characters), it will be stripped.
/// </summary>
/// <param name="downloadPath">The download path to parse.</param>
private String ParseFolderPath(String downloadPath) {
downloadPath = downloadPath.Replace("{year}", ReleaseDate.Year.ToString().ToAllowedFileName());
downloadPath = downloadPath.Replace("{month}", ReleaseDate.Month.ToString("00").ToAllowedFileName());
downloadPath = downloadPath.Replace("{day}", ReleaseDate.Day.ToString("00").ToAllowedFileName());
downloadPath = downloadPath.Replace("{artist}", Artist.ToAllowedFileName());
downloadPath = downloadPath.Replace("{album}", Title.ToAllowedFileName());

if (downloadPath.Length >= 248) {
// Windows doesn't do well with path >= 248 characters (and path + filename >= 260 characters)
downloadPath = downloadPath.Substring(0, 247);
}

return downloadPath;
}

/// <summary>
/// Sets the ArtworkPath and ArtworkTempPath properties.
/// </summary>
private void SetArtworkPaths() {
if (HasArtwork) {
String artworkFileExt = System.IO.Path.GetExtension(ArtworkUrl);

// In order to prevent #54 (artworkTempPath used at the same time by another downloading thread), we'll add a random number to the name of the artwork file saved in Temp directory
String randomNumber = App.Random.Next(1, 1000).ToString("00#");

// Compute paths where to save artwork
ArtworkTempPath = System.IO.Path.GetTempPath() + "\\" + ParseCoverArtFileName() + randomNumber + artworkFileExt;
ArtworkPath = Path + "\\" + ParseCoverArtFileName() + artworkFileExt;

if (ArtworkTempPath.Length >= 260 || ArtworkPath.Length >= 260) {
// Windows doesn't do well with path + filename >= 260 characters (and path >= 248 characters)
// Path has been shorten to 247 characters before, so we have 12 characters max left for filename.ext
// There may be only one path needed to shorten, but it's better to use the same file name in both places
int fileNameInTempMaxLength = 12 - randomNumber.Length - artworkFileExt.Length;
int fileNameInFolderMaxLength = 12 - artworkFileExt.Length;
ArtworkTempPath = System.IO.Path.GetTempPath() + "\\" + ParseCoverArtFileName().Substring(0, fileNameInTempMaxLength) + randomNumber + artworkFileExt;
ArtworkPath = Path + "\\" + ParseCoverArtFileName().Substring(0, fileNameInFolderMaxLength) + artworkFileExt;
}
}
}
}
}
20 changes: 10 additions & 10 deletions src/BandcampDownloader/Model/JSON/JsonAlbum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@ internal class JsonAlbum {
public List<JsonTrack> Tracks { get; set; }

public Album ToAlbum() {
return new Album() {
Artist = Artist,
// Some albums do not have a cover art
ArtworkUrl = ArtId == null ? null : _urlStart + ArtId.PadLeft(10, '0') + _urlEnd,
ReleaseDate = ReleaseDate,
Title = AlbumData.AlbumTitle,
// Some tracks do not have their URL filled on some albums (pre-release...)
// Forget those tracks here
Tracks = Tracks.Where(t => t.File != null).Select(t => t.ToTrack()).ToList()
};
// Some albums do not have a cover art
String artworkUrl = ArtId == null ? null : _urlStart + ArtId.PadLeft(10, '0') + _urlEnd;

var album = new Album(Artist, artworkUrl, ReleaseDate, AlbumData.AlbumTitle);

// Some tracks do not have their URL filled on some albums (pre-release...)
// Forget those tracks here
album.Tracks = Tracks.Where(t => t.File != null).Select(t => t.ToTrack(album)).ToList();

return album;
}
}
}
13 changes: 5 additions & 8 deletions src/BandcampDownloader/Model/JSON/JsonTrack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,11 @@ internal class JsonTrack {
[JsonProperty("title")]
public String Title { get; set; }

public Track ToTrack() {
return new Track() {
Duration = Duration,
Mp3Url = (File.Url.StartsWith("//") ? "http:" : "") + File.Url, // "//example.com" Uri lacks protocol
Number = Number == 0 ? 1 : Number, // For bandcamp track pages, Number will be 0. Set 1 instead
Title = Title,
Lyrics = Lyrics
};
public Track ToTrack(Album album) {
String mp3Url = (File.Url.StartsWith("//") ? "http:" : "") + File.Url; // "//example.com" Uri lacks protocol
int number = Number == 0 ? 1 : Number; // For bandcamp track pages, Number will be 0. Set 1 instead

return new Track(album, Duration, Lyrics, mp3Url, number, Title);
}
}
}
80 changes: 79 additions & 1 deletion src/BandcampDownloader/Model/Track.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,88 @@
namespace BandcampDownloader {

internal class Track {
public Double Duration { get; set; } // In seconds

/// <summary>
/// The track album.
/// </summary>
public Album Album { get; set; }

/// <summary>
/// The track length (in seconds).
/// </summary>
public Double Duration { get; set; }

/// <summary>
/// The track lyrics.
/// </summary>
public String Lyrics { get; set; }

/// <summary>
/// The URL where the track should be downloaded from.
/// </summary>
public String Mp3Url { get; set; }

/// <summary>
/// The track number.
/// </summary>
public int Number { get; set; }

/// <summary>
/// The local path (full path with file name) where the track file should be saved.
/// </summary>
public String Path { get; private set; }

/// <summary>
/// The track title.
/// </summary>
public String Title { get; set; }

/// <summary>
/// Initializes a new Track.
/// </summary>
public Track(Album album, Double duration, String lyrics, String mp3Url, int number, String title) {
Album = album;
Duration = duration;
Lyrics = lyrics;
Mp3Url = mp3Url;
Number = number;
Title = title;
// Must be done after other properties are filled!
Path = ParseTrackFilePath();
}

/// <summary>
/// Returns the file name to be used for the track from the file name format saved in the UserSettings, by
/// replacing the placeholders strings with their corresponding values. The returned file name DOES contain the extension.
/// </summary>
private String ParseTrackFileName() {
String fileName = App.UserSettings.FileNameFormat
.Replace("{year}", Album.ReleaseDate.Year.ToString())
.Replace("{month}", Album.ReleaseDate.Month.ToString("00"))
.Replace("{day}", Album.ReleaseDate.Day.ToString("00"))
.Replace("{album}", Album.Title)
.Replace("{artist}", Album.Artist)
.Replace("{title}", Title)
.Replace("{tracknum}", Number.ToString("00"));
return fileName.ToAllowedFileName();
}

/// <summary>
/// Returns the file path to be used for the track from the file name format saved in the UserSettings, by
/// replacing the placeholders strings with their corresponding values. The returned file path DOES contain the extension.
/// </summary>
private String ParseTrackFilePath() {
String fileName = ParseTrackFileName();

String path = Album.Path + "\\" + fileName;
if (path.Length >= 260) {
// Windows doesn't do well with path + filename >= 260 characters (and path >= 248 characters)
// album.Path has been shorten to 247 characters before, so we have 12 characters max left for filename.ext
int fileNameMaxLength = 12 - System.IO.Path.GetExtension(path).Length;
path = Album.Path + "\\" + fileName.Substring(0, fileNameMaxLength) + System.IO.Path.GetExtension(path);
}

return path;
}
}
}
4 changes: 2 additions & 2 deletions src/BandcampDownloader/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.2.8.1")]
[assembly: AssemblyFileVersion("0.2.8.1")]
[assembly: AssemblyVersion("0.2.8.2")]
[assembly: AssemblyFileVersion("0.2.8.2")]
[assembly: GuidAttribute("8C171C7F-9BAC-4EC0-A287-59908B48953F")]
Loading

0 comments on commit cd91c47

Please sign in to comment.