mirror of
https://github.com/lidarr/lidarr.git
synced 2025-08-20 13:33:34 -07:00
Merge conflicts
This commit is contained in:
commit
ee90d8021a
28 changed files with 834 additions and 64 deletions
|
@ -20,6 +20,10 @@ namespace NzbDrone.Api.Music
|
|||
//View Only
|
||||
public string Name { get; set; }
|
||||
public string ForeignArtistId { get; set; }
|
||||
public string MBId { get; set; }
|
||||
public int TADBId { get; set; }
|
||||
public int DiscogsId { get; set; }
|
||||
public string AMId { get; set; }
|
||||
public string Overview { get; set; }
|
||||
|
||||
public int AlbumCount
|
||||
|
@ -53,7 +57,7 @@ namespace NzbDrone.Api.Music
|
|||
public bool Monitored { get; set; }
|
||||
|
||||
public string RootFolderPath { get; set; }
|
||||
public string Certification { get; set; }
|
||||
//public string Certification { get; set; }
|
||||
public List<string> Genres { get; set; }
|
||||
public HashSet<int> Tags { get; set; }
|
||||
public DateTime Added { get; set; }
|
||||
|
@ -71,7 +75,10 @@ namespace NzbDrone.Api.Music
|
|||
return new ArtistResource
|
||||
{
|
||||
Id = model.Id,
|
||||
|
||||
MBId = model.MBId,
|
||||
TADBId = model.TADBId,
|
||||
DiscogsId = model.DiscogsId,
|
||||
AMId = model.AMId,
|
||||
Name = model.Name,
|
||||
//AlternateTitles
|
||||
//SortTitle = resource.SortTitle,
|
||||
|
@ -127,7 +134,10 @@ namespace NzbDrone.Api.Music
|
|||
Name = resource.Name,
|
||||
//AlternateTitles
|
||||
//SortTitle = resource.SortTitle,
|
||||
|
||||
MBId = resource.MBId,
|
||||
TADBId = resource.TADBId,
|
||||
DiscogsId = resource.DiscogsId,
|
||||
AMId = resource.AMId,
|
||||
//TotalEpisodeCount
|
||||
//EpisodeCount
|
||||
//EpisodeFileCount
|
||||
|
|
|
@ -104,6 +104,13 @@
|
|||
<Compile Include="ClientSchema\SelectOption.cs" />
|
||||
<Compile Include="Commands\CommandModule.cs" />
|
||||
<Compile Include="Commands\CommandResource.cs" />
|
||||
<Compile Include="TrackFiles\TrackFileModule.cs" />
|
||||
<Compile Include="TrackFiles\TrackFileResource.cs" />
|
||||
<Compile Include="Tracks\TrackModule.cs" />
|
||||
<Compile Include="Tracks\TrackModuleWithSignalR.cs" />
|
||||
<Compile Include="Tracks\TrackResource.cs" />
|
||||
<Compile Include="Tracks\RenameTrackModule.cs" />
|
||||
<Compile Include="Tracks\RenameTrackResource.cs" />
|
||||
<Compile Include="Extensions\AccessControlHeaders.cs" />
|
||||
<Compile Include="Extensions\Pipelines\CorsPipeline.cs" />
|
||||
<Compile Include="Extensions\Pipelines\RequestLoggingPipeline.cs" />
|
||||
|
|
101
src/NzbDrone.Api/TrackFiles/TrackFileModule.cs
Normal file
101
src/NzbDrone.Api/TrackFiles/TrackFileModule.cs
Normal file
|
@ -0,0 +1,101 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Datastore.Events;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.MediaFiles.Events;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Music;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.SignalR;
|
||||
using System;
|
||||
|
||||
namespace NzbDrone.Api.TrackFiles
|
||||
{
|
||||
public class TrackFileModule : NzbDroneRestModuleWithSignalR<TrackFileResource, TrackFile>,
|
||||
IHandle<TrackFileAddedEvent>
|
||||
{
|
||||
private readonly IMediaFileService _mediaFileService;
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IRecycleBinProvider _recycleBinProvider;
|
||||
private readonly ISeriesService _seriesService;
|
||||
private readonly IArtistService _artistService;
|
||||
private readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public TrackFileModule(IBroadcastSignalRMessage signalRBroadcaster,
|
||||
IMediaFileService mediaFileService,
|
||||
IDiskProvider diskProvider,
|
||||
IRecycleBinProvider recycleBinProvider,
|
||||
ISeriesService seriesService,
|
||||
IArtistService artistService,
|
||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||
Logger logger)
|
||||
: base(signalRBroadcaster)
|
||||
{
|
||||
_mediaFileService = mediaFileService;
|
||||
_diskProvider = diskProvider;
|
||||
_recycleBinProvider = recycleBinProvider;
|
||||
_seriesService = seriesService;
|
||||
_artistService = artistService;
|
||||
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
||||
_logger = logger;
|
||||
GetResourceById = GetTrackFile;
|
||||
GetResourceAll = GetTrackFiles;
|
||||
UpdateResource = SetQuality;
|
||||
DeleteResource = DeleteTrackFile;
|
||||
}
|
||||
|
||||
private TrackFileResource GetTrackFile(int id)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
//var episodeFile = _mediaFileService.Get(id);
|
||||
//var series = _seriesService.GetSeries(episodeFile.SeriesId);
|
||||
|
||||
//return episodeFile.ToResource(series, _qualityUpgradableSpecification);
|
||||
}
|
||||
|
||||
private List<TrackFileResource> GetTrackFiles()
|
||||
{
|
||||
if (!Request.Query.ArtistId.HasValue)
|
||||
{
|
||||
throw new BadRequestException("artistId is missing");
|
||||
}
|
||||
|
||||
var artistId = (int)Request.Query.ArtistId;
|
||||
|
||||
var artist = _artistService.GetArtist(artistId);
|
||||
|
||||
return _mediaFileService.GetFilesByArtist(artistId).ConvertAll(f => f.ToResource(artist, _qualityUpgradableSpecification));
|
||||
}
|
||||
|
||||
private void SetQuality(TrackFileResource trackFileResource)
|
||||
{
|
||||
var trackFile = _mediaFileService.Get(trackFileResource.Id);
|
||||
trackFile.Quality = trackFileResource.Quality;
|
||||
_mediaFileService.Update(trackFile);
|
||||
}
|
||||
|
||||
private void DeleteTrackFile(int id)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
//var episodeFile = _mediaFileService.Get(id);
|
||||
//var series = _seriesService.GetSeries(episodeFile.SeriesId);
|
||||
//var fullPath = Path.Combine(series.Path, episodeFile.RelativePath);
|
||||
//var subfolder = _diskProvider.GetParentFolder(series.Path).GetRelativePath(_diskProvider.GetParentFolder(fullPath));
|
||||
|
||||
//_logger.Info("Deleting episode file: {0}", fullPath);
|
||||
//_recycleBinProvider.DeleteFile(fullPath, subfolder);
|
||||
//_mediaFileService.Delete(episodeFile, DeleteMediaFileReason.Manual);
|
||||
}
|
||||
|
||||
public void Handle(TrackFileAddedEvent message)
|
||||
{
|
||||
BroadcastResourceChange(ModelAction.Updated, message.TrackFile.Id);
|
||||
}
|
||||
}
|
||||
}
|
64
src/NzbDrone.Api/TrackFiles/TrackFileResource.cs
Normal file
64
src/NzbDrone.Api/TrackFiles/TrackFileResource.cs
Normal file
|
@ -0,0 +1,64 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.Qualities;
|
||||
|
||||
namespace NzbDrone.Api.TrackFiles
|
||||
{
|
||||
public class TrackFileResource : RestResource
|
||||
{
|
||||
public int ArtistId { get; set; }
|
||||
public int AlbumId { get; set; }
|
||||
public string RelativePath { get; set; }
|
||||
public string Path { get; set; }
|
||||
public long Size { get; set; }
|
||||
public DateTime DateAdded { get; set; }
|
||||
//public string SceneName { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
|
||||
public bool QualityCutoffNotMet { get; set; }
|
||||
}
|
||||
|
||||
public static class TrackFileResourceMapper
|
||||
{
|
||||
private static TrackFileResource ToResource(this Core.MediaFiles.TrackFile model)
|
||||
{
|
||||
if (model == null) return null;
|
||||
|
||||
return new TrackFileResource
|
||||
{
|
||||
Id = model.Id,
|
||||
|
||||
ArtistId = model.ArtistId,
|
||||
AlbumId = model.AlbumId,
|
||||
RelativePath = model.RelativePath,
|
||||
//Path
|
||||
Size = model.Size,
|
||||
DateAdded = model.DateAdded,
|
||||
//SceneName = model.SceneName,
|
||||
Quality = model.Quality,
|
||||
//QualityCutoffNotMet
|
||||
};
|
||||
}
|
||||
|
||||
public static TrackFileResource ToResource(this Core.MediaFiles.TrackFile model, Core.Music.Artist artist, Core.DecisionEngine.IQualityUpgradableSpecification qualityUpgradableSpecification)
|
||||
{
|
||||
if (model == null) return null;
|
||||
|
||||
return new TrackFileResource
|
||||
{
|
||||
Id = model.Id,
|
||||
|
||||
ArtistId = model.ArtistId,
|
||||
AlbumId = model.AlbumId,
|
||||
RelativePath = model.RelativePath,
|
||||
Path = Path.Combine(artist.Path, model.RelativePath),
|
||||
Size = model.Size,
|
||||
DateAdded = model.DateAdded,
|
||||
//SceneName = model.SceneName,
|
||||
Quality = model.Quality,
|
||||
QualityCutoffNotMet = qualityUpgradableSpecification.CutoffNotMet(artist.Profile.Value, model.Quality)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
37
src/NzbDrone.Api/Tracks/RenameTrackModule.cs
Normal file
37
src/NzbDrone.Api/Tracks/RenameTrackModule.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
using System.Collections.Generic;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
|
||||
namespace NzbDrone.Api.Tracks
|
||||
{
|
||||
public class RenameTrackModule : NzbDroneRestModule<RenameTrackResource>
|
||||
{
|
||||
private readonly IRenameTrackFileService _renameTrackFileService;
|
||||
|
||||
public RenameTrackModule(IRenameTrackFileService renameTrackFileService)
|
||||
: base("rename")
|
||||
{
|
||||
_renameTrackFileService = renameTrackFileService;
|
||||
|
||||
GetResourceAll = GetTracks;
|
||||
}
|
||||
|
||||
private List<RenameTrackResource> GetTracks()
|
||||
{
|
||||
if (!Request.Query.ArtistId.HasValue)
|
||||
{
|
||||
throw new BadRequestException("artistId is missing");
|
||||
}
|
||||
|
||||
var artistId = (int)Request.Query.ArtistId;
|
||||
|
||||
if (Request.Query.AlbumId.HasValue)
|
||||
{
|
||||
var albumId = (int)Request.Query.AlbumId;
|
||||
return _renameTrackFileService.GetRenamePreviews(artistId, albumId).ToResource();
|
||||
}
|
||||
|
||||
return _renameTrackFileService.GetRenamePreviews(artistId).ToResource();
|
||||
}
|
||||
}
|
||||
}
|
39
src/NzbDrone.Api/Tracks/RenameTrackResource.cs
Normal file
39
src/NzbDrone.Api/Tracks/RenameTrackResource.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NzbDrone.Api.REST;
|
||||
|
||||
namespace NzbDrone.Api.Tracks
|
||||
{
|
||||
public class RenameTrackResource : RestResource
|
||||
{
|
||||
public int ArtistId { get; set; }
|
||||
public int AlbumId { get; set; }
|
||||
public List<int> TrackNumbers { get; set; }
|
||||
public int TrackFileId { get; set; }
|
||||
public string ExistingPath { get; set; }
|
||||
public string NewPath { get; set; }
|
||||
}
|
||||
|
||||
public static class RenameTrackResourceMapper
|
||||
{
|
||||
public static RenameTrackResource ToResource(this Core.MediaFiles.RenameTrackFilePreview model)
|
||||
{
|
||||
if (model == null) return null;
|
||||
|
||||
return new RenameTrackResource
|
||||
{
|
||||
ArtistId = model.ArtistId,
|
||||
AlbumId = model.AlbumId,
|
||||
TrackNumbers = model.TrackNumbers.ToList(),
|
||||
TrackFileId = model.TrackFileId,
|
||||
ExistingPath = model.ExistingPath,
|
||||
NewPath = model.NewPath
|
||||
};
|
||||
}
|
||||
|
||||
public static List<RenameTrackResource> ToResource(this IEnumerable<Core.MediaFiles.RenameTrackFilePreview> models)
|
||||
{
|
||||
return models.Select(ToResource).ToList();
|
||||
}
|
||||
}
|
||||
}
|
40
src/NzbDrone.Api/Tracks/TrackModule.cs
Normal file
40
src/NzbDrone.Api/Tracks/TrackModule.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
using System.Collections.Generic;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.Music;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.SignalR;
|
||||
|
||||
namespace NzbDrone.Api.Tracks
|
||||
{
|
||||
public class TrackModule : TrackModuleWithSignalR
|
||||
{
|
||||
public TrackModule(IArtistService artistService,
|
||||
ITrackService trackService,
|
||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||
IBroadcastSignalRMessage signalRBroadcaster)
|
||||
: base(trackService, artistService, qualityUpgradableSpecification, signalRBroadcaster)
|
||||
{
|
||||
GetResourceAll = GetTracks;
|
||||
UpdateResource = SetMonitored;
|
||||
}
|
||||
|
||||
private List<TrackResource> GetTracks()
|
||||
{
|
||||
if (!Request.Query.ArtistId.HasValue)
|
||||
{
|
||||
throw new BadRequestException("artistId is missing");
|
||||
}
|
||||
|
||||
var artistId = (int)Request.Query.ArtistId;
|
||||
|
||||
var resources = MapToResource(_trackService.GetTracksByArtist(artistId), false, true);
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
||||
private void SetMonitored(TrackResource trackResource)
|
||||
{
|
||||
_trackService.SetTrackMonitored(trackResource.Id, trackResource.Monitored);
|
||||
}
|
||||
}
|
||||
}
|
126
src/NzbDrone.Api/Tracks/TrackModuleWithSignalR.cs
Normal file
126
src/NzbDrone.Api/Tracks/TrackModuleWithSignalR.cs
Normal file
|
@ -0,0 +1,126 @@
|
|||
using System.Collections.Generic;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Api.TrackFiles;
|
||||
using NzbDrone.Api.Music;
|
||||
using NzbDrone.Core.Datastore.Events;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.MediaFiles.Events;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Music;
|
||||
using NzbDrone.SignalR;
|
||||
|
||||
namespace NzbDrone.Api.Tracks
|
||||
{
|
||||
public abstract class TrackModuleWithSignalR : NzbDroneRestModuleWithSignalR<TrackResource, Track>,
|
||||
IHandle<TrackDownloadedEvent>
|
||||
{
|
||||
protected readonly ITrackService _trackService;
|
||||
protected readonly IArtistService _artistService;
|
||||
protected readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
|
||||
|
||||
protected TrackModuleWithSignalR(ITrackService trackService,
|
||||
IArtistService artistService,
|
||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||
IBroadcastSignalRMessage signalRBroadcaster)
|
||||
: base(signalRBroadcaster)
|
||||
{
|
||||
_trackService = trackService;
|
||||
_artistService = artistService;
|
||||
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
||||
|
||||
GetResourceById = GetTrack;
|
||||
}
|
||||
|
||||
protected TrackModuleWithSignalR(ITrackService trackService,
|
||||
IArtistService artistService,
|
||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||
IBroadcastSignalRMessage signalRBroadcaster,
|
||||
string resource)
|
||||
: base(signalRBroadcaster, resource)
|
||||
{
|
||||
_trackService = trackService;
|
||||
_artistService = artistService;
|
||||
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
||||
|
||||
GetResourceById = GetTrack;
|
||||
}
|
||||
|
||||
protected TrackResource GetTrack(int id)
|
||||
{
|
||||
var track = _trackService.GetTrack(id);
|
||||
var resource = MapToResource(track, true, true);
|
||||
return resource;
|
||||
}
|
||||
|
||||
protected TrackResource MapToResource(Track track, bool includeArtist, bool includeTrackFile)
|
||||
{
|
||||
var resource = track.ToResource();
|
||||
|
||||
if (includeArtist || includeTrackFile)
|
||||
{
|
||||
var artist = track.Artist ?? _artistService.GetArtist(track.ArtistId);
|
||||
|
||||
if (includeArtist)
|
||||
{
|
||||
resource.Artist = artist.ToResource();
|
||||
}
|
||||
if (includeTrackFile && track.TrackFileId != 0)
|
||||
{
|
||||
resource.TrackFile = track.TrackFile.Value.ToResource(artist, _qualityUpgradableSpecification);
|
||||
}
|
||||
}
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
protected List<TrackResource> MapToResource(List<Track> tracks, bool includeArtist, bool includeTrackFile)
|
||||
{
|
||||
var result = tracks.ToResource();
|
||||
|
||||
if (includeArtist || includeTrackFile)
|
||||
{
|
||||
var artistDict = new Dictionary<int, Core.Music.Artist>();
|
||||
for (var i = 0; i < tracks.Count; i++)
|
||||
{
|
||||
var track = tracks[i];
|
||||
var resource = result[i];
|
||||
|
||||
var artist = track.Artist ?? artistDict.GetValueOrDefault(tracks[i].ArtistId) ?? _artistService.GetArtist(tracks[i].ArtistId);
|
||||
artistDict[artist.Id] = artist;
|
||||
|
||||
if (includeArtist)
|
||||
{
|
||||
resource.Artist = artist.ToResource();
|
||||
}
|
||||
if (includeTrackFile && tracks[i].TrackFileId != 0)
|
||||
{
|
||||
resource.TrackFile = tracks[i].TrackFile.Value.ToResource(artist, _qualityUpgradableSpecification);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//public void Handle(TrackGrabbedEvent message)
|
||||
//{
|
||||
// foreach (var track in message.Track.Tracks)
|
||||
// {
|
||||
// var resource = track.ToResource();
|
||||
// resource.Grabbed = true;
|
||||
|
||||
// BroadcastResourceChange(ModelAction.Updated, resource);
|
||||
// }
|
||||
//}
|
||||
|
||||
public void Handle(TrackDownloadedEvent message)
|
||||
{
|
||||
foreach (var track in message.Track.Tracks)
|
||||
{
|
||||
BroadcastResourceChange(ModelAction.Updated, track.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
78
src/NzbDrone.Api/Tracks/TrackResource.cs
Normal file
78
src/NzbDrone.Api/Tracks/TrackResource.cs
Normal file
|
@ -0,0 +1,78 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using NzbDrone.Api.TrackFiles;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Api.Music;
|
||||
using NzbDrone.Core.Music;
|
||||
|
||||
namespace NzbDrone.Api.Tracks
|
||||
{
|
||||
public class TrackResource : RestResource
|
||||
{
|
||||
public int ArtistId { get; set; }
|
||||
public int TrackFileId { get; set; }
|
||||
public int AlbumId { get; set; }
|
||||
//public int EpisodeNumber { get; set; }
|
||||
public string Title { get; set; }
|
||||
//public string AirDate { get; set; }
|
||||
//public DateTime? AirDateUtc { get; set; }
|
||||
//public string Overview { get; set; }
|
||||
public TrackFileResource TrackFile { get; set; }
|
||||
|
||||
public bool HasFile { get; set; }
|
||||
public bool Monitored { get; set; }
|
||||
//public int? AbsoluteEpisodeNumber { get; set; }
|
||||
//public int? SceneAbsoluteEpisodeNumber { get; set; }
|
||||
//public int? SceneEpisodeNumber { get; set; }
|
||||
//public int? SceneSeasonNumber { get; set; }
|
||||
//public bool UnverifiedSceneNumbering { get; set; }
|
||||
//public string SeriesTitle { get; set; }
|
||||
public ArtistResource Artist { get; set; }
|
||||
|
||||
//Hiding this so people don't think its usable (only used to set the initial state)
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public bool Grabbed { get; set; }
|
||||
}
|
||||
|
||||
public static class TrackResourceMapper
|
||||
{
|
||||
public static TrackResource ToResource(this Track model)
|
||||
{
|
||||
if (model == null) return null;
|
||||
|
||||
return new TrackResource
|
||||
{
|
||||
Id = model.Id,
|
||||
|
||||
ArtistId = model.ArtistId,
|
||||
TrackFileId = model.TrackFileId,
|
||||
AlbumId = model.AlbumId,
|
||||
//EpisodeNumber = model.EpisodeNumber,
|
||||
Title = model.Title,
|
||||
//AirDate = model.AirDate,
|
||||
//AirDateUtc = model.AirDateUtc,
|
||||
//Overview = model.Overview,
|
||||
//EpisodeFile
|
||||
|
||||
HasFile = model.HasFile,
|
||||
Monitored = model.Monitored,
|
||||
//AbsoluteEpisodeNumber = model.AbsoluteEpisodeNumber,
|
||||
//SceneAbsoluteEpisodeNumber = model.SceneAbsoluteEpisodeNumber,
|
||||
//SceneEpisodeNumber = model.SceneEpisodeNumber,
|
||||
//SceneSeasonNumber = model.SceneSeasonNumber,
|
||||
//UnverifiedSceneNumbering = model.UnverifiedSceneNumbering,
|
||||
//SeriesTitle = model.SeriesTitle,
|
||||
//Series = model.Series.MapToResource(),
|
||||
};
|
||||
}
|
||||
|
||||
public static List<TrackResource> ToResource(this IEnumerable<Track> models)
|
||||
{
|
||||
if (models == null) return null;
|
||||
|
||||
return models.Select(ToResource).ToList();
|
||||
}
|
||||
}
|
||||
}
|
16
src/NzbDrone.Core/MediaFiles/Commands/RenameArtistCommand.cs
Normal file
16
src/NzbDrone.Core/MediaFiles/Commands/RenameArtistCommand.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles.Commands
|
||||
{
|
||||
public class RenameArtistCommand : Command
|
||||
{
|
||||
public List<int> ArtistIds { get; set; }
|
||||
|
||||
public override bool SendUpdatesToClient => true;
|
||||
|
||||
public RenameArtistCommand()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ namespace NzbDrone.Core.MediaFiles
|
|||
void Update(TrackFile trackFile);
|
||||
void Delete(TrackFile trackFile, DeleteMediaFileReason reason);
|
||||
List<TrackFile> GetFilesByArtist(int artistId);
|
||||
List<TrackFile> GetFilesByAlbum(int artistId, int albumId);
|
||||
List<TrackFile> GetFilesWithoutMediaInfo();
|
||||
List<string> FilterExistingFiles(List<string> files, Artist artist);
|
||||
TrackFile Get(int id);
|
||||
|
@ -98,5 +99,10 @@ namespace NzbDrone.Core.MediaFiles
|
|||
{
|
||||
return _mediaFileRepository.GetFilesByArtist(artistId);
|
||||
}
|
||||
|
||||
public List<TrackFile> GetFilesByAlbum(int artistId, int albumId)
|
||||
{
|
||||
return _mediaFileRepository.GetFilesByArtist(artistId);
|
||||
}
|
||||
}
|
||||
}
|
14
src/NzbDrone.Core/MediaFiles/RenameTrackFilePreview.cs
Normal file
14
src/NzbDrone.Core/MediaFiles/RenameTrackFilePreview.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles
|
||||
{
|
||||
public class RenameTrackFilePreview
|
||||
{
|
||||
public int ArtistId { get; set; }
|
||||
public int AlbumId { get; set; }
|
||||
public List<int> TrackNumbers { get; set; }
|
||||
public int TrackFileId { get; set; }
|
||||
public string ExistingPath { get; set; }
|
||||
public string NewPath { get; set; }
|
||||
}
|
||||
}
|
185
src/NzbDrone.Core/MediaFiles/RenameTrackFileService.cs
Normal file
185
src/NzbDrone.Core/MediaFiles/RenameTrackFileService.cs
Normal file
|
@ -0,0 +1,185 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Instrumentation.Extensions;
|
||||
using NzbDrone.Core.MediaFiles.Commands;
|
||||
using NzbDrone.Core.MediaFiles.Events;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Organizer;
|
||||
using NzbDrone.Core.Music;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles
|
||||
{
|
||||
public interface IRenameTrackFileService
|
||||
{
|
||||
List<RenameTrackFilePreview> GetRenamePreviews(int artistId);
|
||||
List<RenameTrackFilePreview> GetRenamePreviews(int artistId, int albumId);
|
||||
}
|
||||
|
||||
public class RenameTrackFileService : IRenameTrackFileService,
|
||||
IExecute<RenameFilesCommand>,
|
||||
IExecute<RenameArtistCommand>
|
||||
{
|
||||
private readonly IArtistService _artistService;
|
||||
private readonly IAlbumService _albumService;
|
||||
private readonly IMediaFileService _mediaFileService;
|
||||
private readonly IMoveTrackFiles _trackFileMover;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly ITrackService _trackService;
|
||||
private readonly IBuildFileNames _filenameBuilder;
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public RenameTrackFileService(IArtistService artistService,
|
||||
IAlbumService albumService,
|
||||
IMediaFileService mediaFileService,
|
||||
IMoveTrackFiles trackFileMover,
|
||||
IEventAggregator eventAggregator,
|
||||
ITrackService trackService,
|
||||
IBuildFileNames filenameBuilder,
|
||||
IDiskProvider diskProvider,
|
||||
Logger logger)
|
||||
{
|
||||
_artistService = artistService;
|
||||
_albumService = albumService;
|
||||
_mediaFileService = mediaFileService;
|
||||
_trackFileMover = trackFileMover;
|
||||
_eventAggregator = eventAggregator;
|
||||
_trackService = trackService;
|
||||
_filenameBuilder = filenameBuilder;
|
||||
_diskProvider = diskProvider;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public List<RenameTrackFilePreview> GetRenamePreviews(int artistId)
|
||||
{
|
||||
// TODO
|
||||
throw new NotImplementedException();
|
||||
//var artist = _artistService.GetArtist(artistId);
|
||||
//var tracks = _trackService.GetTracksByArtist(artistId);
|
||||
//var files = _mediaFileService.GetFilesByArtist(artistId);
|
||||
|
||||
//return GetPreviews(artist, tracks, files)
|
||||
// .OrderByDescending(e => e.SeasonNumber)
|
||||
// .ThenByDescending(e => e.TrackNumbers.First())
|
||||
// .ToList();
|
||||
}
|
||||
|
||||
public List<RenameTrackFilePreview> GetRenamePreviews(int artistId, int albumId)
|
||||
{
|
||||
// TODO
|
||||
//throw new NotImplementedException();
|
||||
var artist = _artistService.GetArtist(artistId);
|
||||
var album = _albumService.GetAlbum(albumId);
|
||||
var tracks = _trackService.GetTracksByAlbum(artistId, albumId);
|
||||
var files = _mediaFileService.GetFilesByAlbum(artistId, albumId);
|
||||
|
||||
return GetPreviews(artist, album, tracks, files)
|
||||
.OrderByDescending(e => e.TrackNumbers.First()).ToList();
|
||||
}
|
||||
|
||||
private IEnumerable<RenameTrackFilePreview> GetPreviews(Artist artist, Album album, List<Track> tracks, List<TrackFile> files)
|
||||
{
|
||||
foreach (var f in files)
|
||||
{
|
||||
var file = f;
|
||||
var tracksInFile = tracks.Where(e => e.TrackFileId == file.Id).ToList();
|
||||
var trackFilePath = Path.Combine(artist.Path, file.RelativePath);
|
||||
|
||||
if (!tracksInFile.Any())
|
||||
{
|
||||
_logger.Warn("File ({0}) is not linked to any tracks", trackFilePath);
|
||||
continue;
|
||||
}
|
||||
|
||||
var albumId = tracksInFile.First().AlbumId;
|
||||
var newName = _filenameBuilder.BuildTrackFileName(tracksInFile, artist, album, file);
|
||||
var newPath = _filenameBuilder.BuildTrackFilePath(artist, album, newName, Path.GetExtension(trackFilePath));
|
||||
|
||||
if (!trackFilePath.PathEquals(newPath, StringComparison.Ordinal))
|
||||
{
|
||||
yield return new RenameTrackFilePreview
|
||||
{
|
||||
ArtistId = artist.Id,
|
||||
AlbumId = albumId,
|
||||
TrackNumbers = tracksInFile.Select(e => e.TrackNumber).ToList(),
|
||||
TrackFileId = file.Id,
|
||||
ExistingPath = file.RelativePath,
|
||||
NewPath = artist.Path.GetRelativePath(newPath)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RenameFiles(List<TrackFile> trackFiles, Artist artist)
|
||||
{
|
||||
// TODO
|
||||
throw new NotImplementedException();
|
||||
//var renamed = new List<TrackFile>();
|
||||
|
||||
//foreach (var trackFile in trackFiles)
|
||||
//{
|
||||
// var trackFilePath = Path.Combine(artist.Path, trackFile.RelativePath);
|
||||
|
||||
// try
|
||||
// {
|
||||
// _logger.Debug("Renaming track file: {0}", trackFile);
|
||||
// _trackFileMover.MoveTrackFile(trackFile, artist);
|
||||
|
||||
// _mediaFileService.Update(trackFile);
|
||||
// renamed.Add(trackFile);
|
||||
|
||||
// _logger.Debug("Renamed track file: {0}", trackFile);
|
||||
// }
|
||||
// catch (SameFilenameException ex)
|
||||
// {
|
||||
// _logger.Debug("File not renamed, source and destination are the same: {0}", ex.Filename);
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// _logger.Error(ex, "Failed to rename file {0}", trackFilePath);
|
||||
// }
|
||||
//}
|
||||
|
||||
//if (renamed.Any())
|
||||
//{
|
||||
// _diskProvider.RemoveEmptySubfolders(artist.Path);
|
||||
|
||||
// _eventAggregator.PublishEvent(new ArtistRenamedEvent(artist));
|
||||
//}
|
||||
}
|
||||
|
||||
public void Execute(RenameFilesCommand message)
|
||||
{
|
||||
// TODO
|
||||
throw new NotImplementedException();
|
||||
//var artist = _artistService.GetArtist(message.ArtistId);
|
||||
//var trackFiles = _mediaFileService.Get(message.Files);
|
||||
|
||||
//_logger.ProgressInfo("Renaming {0} files for {1}", trackFiles.Count, artist.Title);
|
||||
//RenameFiles(trackFiles, artist);
|
||||
//_logger.ProgressInfo("Selected track files renamed for {0}", artist.Title);
|
||||
}
|
||||
|
||||
public void Execute(RenameArtistCommand message)
|
||||
{
|
||||
// TODO
|
||||
throw new NotImplementedException();
|
||||
//_logger.Debug("Renaming all files for selected artist");
|
||||
//var artistToRename = _artistService.GetArtist(message.ArtistIds);
|
||||
|
||||
//foreach (var artist in artistToRename)
|
||||
//{
|
||||
// var trackFiles = _mediaFileService.GetFilesByArtist(artist.Id);
|
||||
// _logger.ProgressInfo("Renaming all files in artist: {0}", artist.Title);
|
||||
// RenameFiles(trackFiles, artist);
|
||||
// _logger.ProgressInfo("All track files renamed for {0}", artist.Title);
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,6 +23,10 @@ namespace NzbDrone.Core.Music
|
|||
}
|
||||
|
||||
public string ForeignArtistId { get; set; }
|
||||
public string MBId { get; set; }
|
||||
public int TADBId { get; set; }
|
||||
public int DiscogsId { get; set; }
|
||||
public string AMId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string NameSlug { get; set; }
|
||||
public string CleanName { get; set; }
|
||||
|
@ -52,6 +56,10 @@ namespace NzbDrone.Core.Music
|
|||
{
|
||||
|
||||
ForeignArtistId = otherArtist.ForeignArtistId;
|
||||
MBId = otherArtist.MBId;
|
||||
TADBId = otherArtist.TADBId;
|
||||
DiscogsId = otherArtist.DiscogsId;
|
||||
AMId = otherArtist.AMId;
|
||||
Name = otherArtist.Name;
|
||||
NameSlug = otherArtist.NameSlug;
|
||||
CleanName = otherArtist.CleanName;
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace NzbDrone.Core.Music
|
|||
|
||||
public string ForeignTrackId { get; set; }
|
||||
public int AlbumId { get; set; }
|
||||
public LazyLoaded<Artist> Artist { get; set; }
|
||||
public Artist Artist { get; set; }
|
||||
|
||||
public int ArtistId { get; set; } // This is the DB Id of the Artist, not the SpotifyId
|
||||
//public int CompilationId { get; set; }
|
||||
|
|
|
@ -724,7 +724,10 @@
|
|||
<Compile Include="MediaFiles\Commands\BackendCommandAttribute.cs" />
|
||||
<Compile Include="MediaFiles\Commands\CleanUpRecycleBinCommand.cs" />
|
||||
<Compile Include="MediaFiles\Commands\DownloadedEpisodesScanCommand.cs" />
|
||||
<Compile Include="MediaFiles\Commands\RenameArtistCommand.cs" />
|
||||
<Compile Include="MediaFiles\Events\TrackDownloadedEvent.cs" />
|
||||
<Compile Include="MediaFiles\RenameTrackFilePreview.cs" />
|
||||
<Compile Include="MediaFiles\RenameTrackFileService.cs" />
|
||||
<Compile Include="MediaFiles\TrackFileMovingService.cs" />
|
||||
<Compile Include="MediaFiles\TrackFileMoveResult.cs" />
|
||||
<Compile Include="MediaFiles\TrackImport\ImportMode.cs" />
|
||||
|
|
|
@ -20,7 +20,9 @@ namespace NzbDrone.Core.Organizer
|
|||
string BuildFileName(List<Episode> episodes, Series series, EpisodeFile episodeFile, NamingConfig namingConfig = null);
|
||||
string BuildTrackFileName(List<Track> tracks, Artist artist, Album album, TrackFile trackFile, NamingConfig namingConfig = null);
|
||||
string BuildFilePath(Series series, int seasonNumber, string fileName, string extension);
|
||||
string BuildTrackFilePath(Artist artist, Album album, string fileName, string extension);
|
||||
string BuildSeasonPath(Series series, int seasonNumber);
|
||||
string BuildAlbumPath(Artist artist, Album album);
|
||||
BasicNamingConfig GetBasicNamingConfig(NamingConfig nameSpec);
|
||||
string GetSeriesFolder(Series series, NamingConfig namingConfig = null);
|
||||
string GetArtistFolder(Artist artist, NamingConfig namingConfig = null);
|
||||
|
@ -202,6 +204,15 @@ namespace NzbDrone.Core.Organizer
|
|||
return Path.Combine(path, fileName + extension);
|
||||
}
|
||||
|
||||
public string BuildTrackFilePath(Artist artist, Album album, string fileName, string extension)
|
||||
{
|
||||
Ensure.That(extension, () => extension).IsNotNullOrWhiteSpace();
|
||||
|
||||
var path = BuildAlbumPath(artist, album);
|
||||
|
||||
return Path.Combine(path, fileName + extension);
|
||||
}
|
||||
|
||||
public string BuildSeasonPath(Series series, int seasonNumber)
|
||||
{
|
||||
var path = series.Path;
|
||||
|
@ -225,6 +236,24 @@ namespace NzbDrone.Core.Organizer
|
|||
return path;
|
||||
}
|
||||
|
||||
public string BuildAlbumPath(Artist artist, Album album)
|
||||
{
|
||||
var path = artist.Path;
|
||||
|
||||
if (artist.AlbumFolder)
|
||||
{
|
||||
|
||||
var albumFolder = GetAlbumFolder(artist, album);
|
||||
|
||||
albumFolder = CleanFileName(albumFolder);
|
||||
|
||||
path = Path.Combine(path, albumFolder);
|
||||
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
public BasicNamingConfig GetBasicNamingConfig(NamingConfig nameSpec)
|
||||
{
|
||||
var episodeFormat = GetEpisodeFormat(nameSpec.StandardEpisodeFormat).LastOrDefault();
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row new-artist-overview x-overview">
|
||||
<!--<div class="row new-artist-overview x-overview">
|
||||
<div class="col-md-12 overview-internal">
|
||||
{{overview}}
|
||||
</div>
|
||||
</div>
|
||||
</div>-->
|
||||
<div class="row">
|
||||
{{#unless existing}}
|
||||
{{#unless path}}
|
||||
|
|
|
@ -29,20 +29,18 @@
|
|||
</div>
|
||||
<div class="col-md-3">
|
||||
<span class="artist-info-links">
|
||||
<a href="{{traktUrl}}" class="label label-info">Trakt</a>
|
||||
<a href="{{MBUrl}}" class="label label-info">MusicBrainz</a>
|
||||
|
||||
<a href="{{tvdbUrl}}" class="label label-info">The TVDB</a>
|
||||
|
||||
{{#if imdbId}}
|
||||
<a href="{{imdbUrl}}" class="label label-info">IMDB</a>
|
||||
{{#if tadbId}}
|
||||
<a href="{{TADBUrl}}" class="label label-info">The AudioDB</a>
|
||||
{{/if}}
|
||||
|
||||
{{#if tvRageId}}
|
||||
<a href="{{tvRageUrl}}" class="label label-info">TV Rage</a>
|
||||
{{#if discogsId}}
|
||||
<a href="{{discogsUrl}}" class="label label-info">Discogs</a>
|
||||
{{/if}}
|
||||
|
||||
{{#if tvMazeId}}
|
||||
<a href="{{tvMazeUrl}}" class="label label-info">TV Maze</a>
|
||||
{{#if amId}}
|
||||
<a href="{{allMusicUrl}}" class="label label-info">AllMusic</a>
|
||||
{{/if}}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -321,15 +321,17 @@ module.exports = Marionette.Layout.extend({
|
|||
_showFooter : function() {
|
||||
var footerModel = new FooterModel();
|
||||
var artist = this.artistCollection.models.length;
|
||||
var episodes = 0;
|
||||
var episodeFiles = 0;
|
||||
var albums = 0;
|
||||
var tracks = 0;
|
||||
var trackFiles = 0;
|
||||
var ended = 0;
|
||||
var continuing = 0;
|
||||
var monitored = 0;
|
||||
|
||||
_.each(this.artistCollection.models, function(model) {
|
||||
episodes += model.get('episodeCount'); // TODO: Refactor to Seasons and Tracks
|
||||
episodeFiles += model.get('episodeFileCount');
|
||||
albums += model.get('albumCount');
|
||||
tracks += model.get('episodeCount'); // TODO: Refactor to Seasons and Tracks
|
||||
trackFiles += model.get('episodeFileCount');
|
||||
|
||||
/*if (model.get('status').toLowerCase() === 'ended') {
|
||||
ended++;
|
||||
|
@ -348,8 +350,9 @@ module.exports = Marionette.Layout.extend({
|
|||
continuing : continuing,
|
||||
monitored : monitored,
|
||||
unmonitored : artist - monitored,
|
||||
episodes : episodes,
|
||||
episodeFiles : episodeFiles
|
||||
albums : albums,
|
||||
tracks : tracks,
|
||||
trackFiles : trackFiles
|
||||
});
|
||||
|
||||
this.footer.show(new FooterView({ model : footerModel }));
|
||||
|
|
|
@ -34,11 +34,14 @@
|
|||
|
||||
<div class="artist-stats col-sm-4">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Albums</dt>
|
||||
<dd>{{albums}}</dd>
|
||||
|
||||
<dt>Tracks</dt>
|
||||
<dd>{{episodes}}</dd>
|
||||
<dd>{{tracks}}</dd>
|
||||
|
||||
<dt>Files</dt>
|
||||
<dd>{{episodeFiles}}</dd>
|
||||
<dd>{{trackFiles}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div class="progress episode-progress">
|
||||
<span class="progressbar-back-text">{{episodeFileCount}} / {{episodeCount}}</span>
|
||||
<div class="progress-bar {{EpisodeProgressClass}} episode-progress" style="width:{{percentOfEpisodes}}%"><span class="progressbar-front-text">{{episodeFileCount}} / {{episodeCount}}</span></div>
|
||||
<div class="progress track-progress">
|
||||
<span class="progressbar-back-text">{{trackFileCount}} / {{trackCount}}</span>
|
||||
<div class="progress-bar {{TrackProgressClass}} track-progress" style="width:{{percentOfTracks}}%"><span class="progressbar-front-text">{{trackFileCount}} / {{trackCount}}</span></div>
|
||||
</div>
|
|
@ -4,11 +4,11 @@ var TrackModel = require('./TrackModel');
|
|||
require('./TrackCollection');
|
||||
|
||||
module.exports = PageableCollection.extend({
|
||||
url : window.NzbDrone.ApiRoot + '/episode',
|
||||
url : window.NzbDrone.ApiRoot + '/track',
|
||||
model : TrackModel,
|
||||
|
||||
state : {
|
||||
sortKey : 'episodeNumber',
|
||||
sortKey : 'trackNumber',
|
||||
order : 1,
|
||||
pageSize : 100000
|
||||
},
|
||||
|
@ -18,28 +18,28 @@ module.exports = PageableCollection.extend({
|
|||
originalFetch : Backbone.Collection.prototype.fetch,
|
||||
|
||||
initialize : function(options) {
|
||||
this.seriesId = options.seriesId;
|
||||
this.artistId = options.artistId;
|
||||
},
|
||||
|
||||
bySeason : function(season) {
|
||||
var filtered = this.filter(function(episode) {
|
||||
return episode.get('seasonNumber') === season;
|
||||
bySeason : function(album) {
|
||||
var filtered = this.filter(function(track) {
|
||||
return track.get('albumId') === album;
|
||||
});
|
||||
|
||||
var EpisodeCollection = require('./TrackCollection');
|
||||
var TrackCollection = require('./TrackCollection');
|
||||
|
||||
return new EpisodeCollection(filtered);
|
||||
return new TrackCollection(filtered);
|
||||
},
|
||||
|
||||
comparator : function(model1, model2) {
|
||||
var episode1 = model1.get('episodeNumber');
|
||||
var episode2 = model2.get('episodeNumber');
|
||||
var track1 = model1.get('trackNumber');
|
||||
var track2 = model2.get('trackNumber');
|
||||
|
||||
if (episode1 < episode2) {
|
||||
if (track1 < track2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (episode1 > episode2) {
|
||||
if (track1 > track2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -47,15 +47,15 @@ module.exports = PageableCollection.extend({
|
|||
},
|
||||
|
||||
fetch : function(options) {
|
||||
if (!this.seriesId) {
|
||||
throw 'seriesId is required';
|
||||
if (!this.artistId) {
|
||||
throw 'artistId is required';
|
||||
}
|
||||
|
||||
if (!options) {
|
||||
options = {};
|
||||
}
|
||||
|
||||
options.data = { seriesId : this.seriesId };
|
||||
options.data = { artistId : this.artistId };
|
||||
|
||||
return this.originalFetch.call(this, options);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ var Backbone = require('backbone');
|
|||
var TrackFileModel = require('./TrackFileModel');
|
||||
|
||||
module.exports = Backbone.Collection.extend({
|
||||
url : window.NzbDrone.ApiRoot + '/episodefile',
|
||||
url : window.NzbDrone.ApiRoot + '/trackfile',
|
||||
model : TrackFileModel,
|
||||
|
||||
originalFetch : Backbone.Collection.prototype.fetch,
|
||||
|
@ -21,7 +21,7 @@ module.exports = Backbone.Collection.extend({
|
|||
options = {};
|
||||
}
|
||||
|
||||
options.data = { seriesId : this.seriesId };
|
||||
options.data = { artistId : this.artistId };
|
||||
|
||||
return this.originalFetch.call(this, options);
|
||||
}
|
||||
|
|
|
@ -2,12 +2,12 @@ var Backbone = require('backbone');
|
|||
|
||||
module.exports = Backbone.Model.extend({
|
||||
defaults : {
|
||||
seasonNumber : 0,
|
||||
albumId : 0,
|
||||
status : 0
|
||||
},
|
||||
|
||||
methodUrls : {
|
||||
'update' : window.NzbDrone.ApiRoot + '/episode'
|
||||
'update' : window.NzbDrone.ApiRoot + '/track'
|
||||
},
|
||||
|
||||
sync : function(method, model, options) {
|
||||
|
|
|
@ -19,11 +19,6 @@ module.exports = NzbDroneController.extend({
|
|||
this.showMainRegion(new AddArtistLayout({ action : action }));
|
||||
},
|
||||
|
||||
artistDetails: function(query) {
|
||||
this.setTitle('Artist Detail');
|
||||
this.showMainRegion(new SeriesDetailsLayout());
|
||||
},
|
||||
|
||||
calendar : function() {
|
||||
this.setTitle('Calendar');
|
||||
this.showMainRegion(new CalendarLayout());
|
||||
|
|
|
@ -19,24 +19,20 @@ Handlebars.registerHelper('poster', function() {
|
|||
return new Handlebars.SafeString('<img class="series-poster placeholder-image" src="{0}">'.format(placeholder));
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('traktUrl', function() {
|
||||
return 'http://trakt.tv/search/tvdb/' + this.tvdbId + '?id_type=show';
|
||||
Handlebars.registerHelper('MBUrl', function() {
|
||||
return 'https://musicbrainz.org/artist/' + this.mbId;
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('imdbUrl', function() {
|
||||
return 'http://imdb.com/title/' + this.imdbId;
|
||||
Handlebars.registerHelper('TADBUrl', function() {
|
||||
return 'http://www.theaudiodb.com/artist/' + this.tadbId;
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('tvdbUrl', function() {
|
||||
return 'http://www.thetvdb.com/?tab=series&id=' + this.tvdbId;
|
||||
Handlebars.registerHelper('discogsUrl', function() {
|
||||
return 'https://www.discogs.com/artist/' + this.discogsId;
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('tvRageUrl', function() {
|
||||
return 'http://www.tvrage.com/shows/id-' + this.tvRageId;
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('tvMazeUrl', function() {
|
||||
return 'http://www.tvmaze.com/shows/' + this.tvMazeId + '/_';
|
||||
Handlebars.registerHelper('allMusicUrl', function() {
|
||||
return 'http://www.allmusic.com/artist/' + this.amId;
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('route', function() {
|
||||
|
@ -56,6 +52,19 @@ Handlebars.registerHelper('percentOfEpisodes', function() {
|
|||
return percent;
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('percentOfTracks', function() {
|
||||
var trackCount = this.trackCount;
|
||||
var trackFileCount = this.trackFileCount;
|
||||
|
||||
var percent = 100;
|
||||
|
||||
if (trackCount > 0) {
|
||||
percent = trackFileCount / trackCount * 100;
|
||||
}
|
||||
|
||||
return percent;
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('seasonCountHelper', function() {
|
||||
var seasonCount = this.seasonCount;
|
||||
var continuing = this.status === 'continuing';
|
||||
|
@ -87,7 +96,7 @@ Handlebars.registerHelper('albumCountHelper', function() {
|
|||
var albumCount = this.albumCount;
|
||||
|
||||
if (albumCount === 1) {
|
||||
return new Handlebars.SafeString('<span class="label label-info">{0} Albums</span>'.format(albumCount));
|
||||
return new Handlebars.SafeString('<span class="label label-info">{0} Album</span>'.format(albumCount));
|
||||
}
|
||||
|
||||
return new Handlebars.SafeString('<span class="label label-info">{0} Albums</span>'.format(albumCount));
|
||||
|
|
|
@ -18,7 +18,6 @@ module.exports = Marionette.AppRouter.extend({
|
|||
'rss' : 'rss',
|
||||
'system' : 'system',
|
||||
'system/:action' : 'system',
|
||||
'artist/:query' : 'artistDetails',
|
||||
'seasonpass' : 'seasonPass',
|
||||
'artisteditor' : 'artistEditor',
|
||||
':whatever' : 'showNotFound'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue