mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-04-23 21:47:14 -04:00
add more sync buttons
This commit is contained in:
parent
e3484bdcc2
commit
e55ab989d2
46 changed files with 380 additions and 872 deletions
|
@ -185,7 +185,9 @@ namespace MediaBrowser.Api
|
|||
CompletionPercentage = percentComplete,
|
||||
Width = state.OutputWidth,
|
||||
Height = state.OutputHeight,
|
||||
AudioChannels = state.OutputAudioChannels
|
||||
AudioChannels = state.OutputAudioChannels,
|
||||
IsAudioDirect = string.Equals(state.OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase),
|
||||
IsVideoDirect = string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -302,6 +302,21 @@ namespace MediaBrowser.Api.Playback
|
|||
}
|
||||
}
|
||||
|
||||
protected string H264Encoder
|
||||
{
|
||||
get
|
||||
{
|
||||
var lib = ServerConfigurationManager.Configuration.H264Encoder;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(lib))
|
||||
{
|
||||
return lib;
|
||||
}
|
||||
|
||||
return "libx264";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the video bitrate to specify on the command line
|
||||
/// </summary>
|
||||
|
@ -318,7 +333,7 @@ namespace MediaBrowser.Api.Playback
|
|||
|
||||
var qualitySetting = GetQualitySetting();
|
||||
|
||||
if (string.Equals(videoCodec, "libx264", StringComparison.OrdinalIgnoreCase))
|
||||
if (string.Equals(videoCodec, H264Encoder, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
switch (qualitySetting)
|
||||
{
|
||||
|
@ -761,7 +776,7 @@ namespace MediaBrowser.Api.Playback
|
|||
{
|
||||
if (string.Equals(codec, "h264", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return "libx264";
|
||||
return H264Encoder;
|
||||
}
|
||||
if (string.Equals(codec, "vpx", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
|
@ -1562,9 +1577,6 @@ namespace MediaBrowser.Api.Playback
|
|||
mediaStreams = new List<MediaStream>();
|
||||
|
||||
state.DeInterlace = true;
|
||||
state.OutputAudioSync = "1000";
|
||||
state.InputVideoSync = "-1";
|
||||
state.InputAudioSync = "1";
|
||||
|
||||
// Just to prevent this from being null and causing other methods to fail
|
||||
state.MediaPath = string.Empty;
|
||||
|
@ -1696,6 +1708,13 @@ namespace MediaBrowser.Api.Playback
|
|||
state.InputFileSize = mediaSource.Size;
|
||||
state.ReadInputAtNativeFramerate = mediaSource.ReadAtNativeFramerate;
|
||||
|
||||
if (state.ReadInputAtNativeFramerate)
|
||||
{
|
||||
state.OutputAudioSync = "1000";
|
||||
state.InputVideoSync = "-1";
|
||||
state.InputAudioSync = "1";
|
||||
}
|
||||
|
||||
AttachMediaStreamInfo(state, mediaSource.MediaStreams, videoRequest, requestedUrl);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Channels;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
|
@ -6,7 +7,6 @@ using MediaBrowser.Controller.Dlna;
|
|||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.LiveTv;
|
||||
using MediaBrowser.Controller.MediaEncoding;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.IO;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -119,11 +119,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||
|
||||
if (isLive)
|
||||
{
|
||||
//var file = request.PlaylistId + Path.GetExtension(Request.PathInfo);
|
||||
|
||||
//file = Path.Combine(ServerConfigurationManager.ApplicationPaths.TranscodingTempPath, file);
|
||||
|
||||
return ResultFactory.GetStaticFileResult(Request, playlist, FileShare.ReadWrite);
|
||||
return ResultFactory.GetResult(GetLivePlaylistText(playlist, state.SegmentLength), MimeTypes.GetMimeType("playlist.m3u8"), new Dictionary<string, string>());
|
||||
}
|
||||
|
||||
var audioBitrate = state.OutputAudioBitrate ?? 0;
|
||||
|
@ -144,6 +140,22 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||
return ResultFactory.GetResult(playlistText, MimeTypes.GetMimeType("playlist.m3u8"), new Dictionary<string, string>());
|
||||
}
|
||||
|
||||
private string GetLivePlaylistText(string path, int segmentLength)
|
||||
{
|
||||
using (var stream = FileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
var text = reader.ReadToEnd();
|
||||
|
||||
var newDuration = "#EXT-X-TARGETDURATION:" + segmentLength.ToString(UsCulture) + Environment.NewLine + "#EXT-X-ALLOW-CACHE:NO";
|
||||
|
||||
// ffmpeg pads the reported length by a full second
|
||||
return text.Replace("#EXT-X-TARGETDURATION:" + (segmentLength + 1).ToString(UsCulture), newDuration, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string GetMasterPlaylistFileText(string firstPlaylist, int bitrate, bool includeBaselineStream, int baselineStreamBitrate)
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
|
|
|
@ -651,7 +651,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||
|
||||
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream;
|
||||
|
||||
var args = "-codec:v:0 " + codec + " " + GetVideoQualityParam(state, "libx264", true) + keyFrameArg;
|
||||
var args = "-codec:v:0 " + codec + " " + GetVideoQualityParam(state, H264Encoder, true) + keyFrameArg;
|
||||
|
||||
// Add resolution params, if specified
|
||||
if (!hasGraphicalSubs)
|
||||
|
|
|
@ -594,7 +594,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||
|
||||
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream;
|
||||
|
||||
var args = "-codec:v:0 " + codec + " " + GetVideoQualityParam(state, "libx264", true) + keyFrameArg;
|
||||
var args = "-codec:v:0 " + codec + " " + GetVideoQualityParam(state, H264Encoder, true) + keyFrameArg;
|
||||
|
||||
args += " -r 24 -g 24";
|
||||
|
||||
|
|
|
@ -9,8 +9,6 @@ using MediaBrowser.Model.IO;
|
|||
using ServiceStack;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Api.Playback.Hls
|
||||
{
|
||||
|
@ -147,7 +145,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||
|
||||
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream;
|
||||
|
||||
var args = "-codec:v:0 " + codec + " " + GetVideoQualityParam(state, "libx264", true) + keyFrameArg;
|
||||
var args = "-codec:v:0 " + codec + " " + GetVideoQualityParam(state, H264Encoder, true) + keyFrameArg;
|
||||
|
||||
// Add resolution params, if specified
|
||||
if (!hasGraphicalSubs)
|
||||
|
|
|
@ -55,8 +55,14 @@ namespace MediaBrowser.Api.Sync
|
|||
[ApiMember(Name = "UserId", Description = "UserId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string UserId { get; set; }
|
||||
|
||||
[ApiMember(Name = "ItemIds", Description = "ItemIds", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
[ApiMember(Name = "ItemIds", Description = "ItemIds", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string ItemIds { get; set; }
|
||||
|
||||
[ApiMember(Name = "ParentId", Description = "ParentId", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string ParentId { get; set; }
|
||||
|
||||
[ApiMember(Name = "Category", Description = "Category", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public SyncCategory? Category { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Sync/JobItems/{Id}/Transferred", "POST", Summary = "Reports that a sync job item has successfully been transferred.")]
|
||||
|
@ -155,19 +161,26 @@ namespace MediaBrowser.Api.Sync
|
|||
result.Targets = _syncManager.GetSyncTargets(request.UserId)
|
||||
.ToList();
|
||||
|
||||
var dtos = request.ItemIds.Split(',')
|
||||
.Select(_libraryManager.GetItemById)
|
||||
.Where(i => i != null)
|
||||
.Select(i => _dtoService.GetBaseItemDto(i, new DtoOptions
|
||||
{
|
||||
Fields = new List<ItemFields>
|
||||
if (request.Category.HasValue)
|
||||
{
|
||||
result.Options = SyncHelper.GetSyncOptions(request.Category.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
var dtos = request.ItemIds.Split(',')
|
||||
.Select(_libraryManager.GetItemById)
|
||||
.Where(i => i != null)
|
||||
.Select(i => _dtoService.GetBaseItemDto(i, new DtoOptions
|
||||
{
|
||||
Fields = new List<ItemFields>
|
||||
{
|
||||
ItemFields.SyncInfo
|
||||
}
|
||||
}))
|
||||
.ToList();
|
||||
}))
|
||||
.ToList();
|
||||
|
||||
result.Options = SyncHelper.GetSyncOptions(dtos);
|
||||
result.Options = SyncHelper.GetSyncOptions(dtos);
|
||||
}
|
||||
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ using MediaBrowser.Controller.Dto;
|
|||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Net;
|
||||
using MediaBrowser.Controller.Session;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Connect;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Users;
|
||||
|
@ -51,7 +52,7 @@ namespace MediaBrowser.Api
|
|||
/// </summary>
|
||||
/// <value>The id.</value>
|
||||
[ApiMember(Name = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
|
||||
public Guid Id { get; set; }
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -66,7 +67,7 @@ namespace MediaBrowser.Api
|
|||
/// </summary>
|
||||
/// <value>The id.</value>
|
||||
[ApiMember(Name = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
|
||||
public Guid Id { get; set; }
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -80,7 +81,7 @@ namespace MediaBrowser.Api
|
|||
/// </summary>
|
||||
/// <value>The id.</value>
|
||||
[ApiMember(Name = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
|
||||
public Guid Id { get; set; }
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the password.
|
||||
|
@ -125,7 +126,7 @@ namespace MediaBrowser.Api
|
|||
/// Gets or sets the id.
|
||||
/// </summary>
|
||||
/// <value>The id.</value>
|
||||
public Guid Id { get; set; }
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the password.
|
||||
|
@ -155,6 +156,28 @@ namespace MediaBrowser.Api
|
|||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class UpdateUser
|
||||
/// </summary>
|
||||
[Route("/Users/{Id}/Policy", "POST", Summary = "Updates a user policy")]
|
||||
[Authenticated(Roles = "admin")]
|
||||
public class UpdateUserPolicy : UserPolicy, IReturnVoid
|
||||
{
|
||||
[ApiMember(Name = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class UpdateUser
|
||||
/// </summary>
|
||||
[Route("/Users/{Id}/Configuration", "POST", Summary = "Updates a user configuration")]
|
||||
[Authenticated]
|
||||
public class UpdateUserConfiguration : UserConfiguration, IReturnVoid
|
||||
{
|
||||
[ApiMember(Name = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class CreateUser
|
||||
/// </summary>
|
||||
|
@ -196,12 +219,6 @@ namespace MediaBrowser.Api
|
|||
|
||||
public IAuthorizationContext AuthorizationContext { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UserService" /> class.
|
||||
/// </summary>
|
||||
/// <param name="userManager">The user manager.</param>
|
||||
/// <param name="dtoService">The dto service.</param>
|
||||
/// <param name="sessionMananger">The session mananger.</param>
|
||||
public UserService(IUserManager userManager, IDtoService dtoService, ISessionManager sessionMananger, IServerConfigurationManager config, INetworkManager networkManager)
|
||||
{
|
||||
_userManager = userManager;
|
||||
|
@ -495,5 +512,17 @@ namespace MediaBrowser.Api
|
|||
{
|
||||
return _userManager.RedeemPasswordResetPin(request.Pin);
|
||||
}
|
||||
|
||||
public void Post(UpdateUserConfiguration request)
|
||||
{
|
||||
var user = _userManager.GetUserById(request.Id);
|
||||
user.UpdateConfiguration(request);
|
||||
}
|
||||
|
||||
public void Post(UpdateUserPolicy request)
|
||||
{
|
||||
var task = _userManager.UpdateUserPolicy(request.Id, request);
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,8 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// </summary>
|
||||
public static readonly string[] SupportedImageExtensions = { ".png", ".jpg", ".jpeg", ".tbn" };
|
||||
|
||||
public static readonly List<string> SupportedImageExtensionsList = SupportedImageExtensions.ToList();
|
||||
|
||||
/// <summary>
|
||||
/// The trailer folder name
|
||||
/// </summary>
|
||||
|
|
|
@ -153,7 +153,14 @@ namespace MediaBrowser.Controller.Entities.Movies
|
|||
|
||||
public MovieInfo GetLookupInfo()
|
||||
{
|
||||
return GetItemLookupInfo<MovieInfo>();
|
||||
var info = GetItemLookupInfo<MovieInfo>();
|
||||
|
||||
if (!IsInMixedFolder)
|
||||
{
|
||||
info.Name = System.IO.Path.GetFileName(ContainingFolderPath);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
public override bool BeforeMetadataRefresh()
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
|
@ -301,51 +300,9 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh();
|
||||
|
||||
var locationType = LocationType;
|
||||
if (locationType == LocationType.FileSystem || locationType == LocationType.Offline)
|
||||
if (LibraryManager.FillMissingEpisodeNumbersFromPath(this))
|
||||
{
|
||||
if (!IndexNumber.HasValue && !string.IsNullOrEmpty(Path))
|
||||
{
|
||||
IndexNumber = LibraryManager.GetEpisodeNumberFromFile(Path, true);
|
||||
|
||||
// If a change was made record it
|
||||
if (IndexNumber.HasValue)
|
||||
{
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IndexNumberEnd.HasValue && !string.IsNullOrEmpty(Path))
|
||||
{
|
||||
IndexNumberEnd = LibraryManager.GetEndingEpisodeNumberFromFile(Path);
|
||||
|
||||
// If a change was made record it
|
||||
if (IndexNumberEnd.HasValue)
|
||||
{
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ParentIndexNumber.HasValue)
|
||||
{
|
||||
var season = Season;
|
||||
|
||||
if (season != null)
|
||||
{
|
||||
ParentIndexNumber = season.IndexNumber;
|
||||
}
|
||||
|
||||
if (!ParentIndexNumber.HasValue && !string.IsNullOrEmpty(Path))
|
||||
{
|
||||
ParentIndexNumber = LibraryManager.GetSeasonNumberFromEpisodeFile(Path);
|
||||
}
|
||||
|
||||
// If a change was made record it
|
||||
if (ParentIndexNumber.HasValue)
|
||||
{
|
||||
hasChanges = true;
|
||||
}
|
||||
hasChanges = true;
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Controller.Resolvers;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
|
@ -340,26 +341,11 @@ namespace MediaBrowser.Controller.Library
|
|||
int? GetSeasonNumberFromPath(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the season number from episode file.
|
||||
/// Fills the missing episode numbers from path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>System.Nullable<System.Int32>.</returns>
|
||||
int? GetSeasonNumberFromEpisodeFile(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ending episode number from file.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>System.Nullable<System.Int32>.</returns>
|
||||
int? GetEndingEpisodeNumberFromFile(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the episode number from file.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="considerSeasonless">if set to <c>true</c> [consider seasonless].</param>
|
||||
/// <returns>System.Nullable<System.Int32>.</returns>
|
||||
int? GetEpisodeNumberFromFile(string path, bool considerSeasonless);
|
||||
/// <param name="episode">The episode.</param>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||
bool FillMissingEpisodeNumbersFromPath(Episode episode);
|
||||
|
||||
/// <summary>
|
||||
/// Parses the name.
|
||||
|
|
|
@ -76,11 +76,14 @@ namespace MediaBrowser.LocalMetadata.Images
|
|||
{
|
||||
return directoryService.GetFileSystemEntries(path)
|
||||
.Where(i => BaseItem.SupportedImageExtensions.Contains(i.Extension, StringComparer.OrdinalIgnoreCase) ||
|
||||
(i.Attributes & FileAttributes.Directory) == FileAttributes.Directory);
|
||||
(i.Attributes & FileAttributes.Directory) == FileAttributes.Directory)
|
||||
|
||||
.OrderBy(i => BaseItem.SupportedImageExtensionsList.IndexOf(i.Extension ?? string.Empty));
|
||||
}
|
||||
|
||||
return directoryService.GetFiles(path)
|
||||
.Where(i => BaseItem.SupportedImageExtensions.Contains(i.Extension, StringComparer.OrdinalIgnoreCase));
|
||||
.Where(i => BaseItem.SupportedImageExtensions.Contains(i.Extension, StringComparer.OrdinalIgnoreCase))
|
||||
.OrderBy(i => BaseItem.SupportedImageExtensionsList.IndexOf(i.Extension ?? string.Empty));
|
||||
}
|
||||
|
||||
public List<LocalImageInfo> GetImages(IHasImages item, IDirectoryService directoryService)
|
||||
|
@ -109,6 +112,7 @@ namespace MediaBrowser.LocalMetadata.Images
|
|||
return !string.IsNullOrEmpty(ext) &&
|
||||
BaseItem.SupportedImageExtensions.Contains(ext, StringComparer.OrdinalIgnoreCase);
|
||||
})
|
||||
.OrderBy(i => BaseItem.SupportedImageExtensionsList.IndexOf(i.Extension ?? string.Empty))
|
||||
.ToList();
|
||||
|
||||
var list = new List<LocalImageInfo>();
|
||||
|
@ -402,13 +406,7 @@ namespace MediaBrowser.LocalMetadata.Images
|
|||
|
||||
private FileSystemInfo GetImage(IEnumerable<FileSystemInfo> files, string name)
|
||||
{
|
||||
var candidates = files
|
||||
.Where(i => string.Equals(name, _fileSystem.GetFileNameWithoutExtension(i), StringComparison.OrdinalIgnoreCase))
|
||||
.ToList();
|
||||
|
||||
return BaseItem.SupportedImageExtensions
|
||||
.Select(i => candidates.FirstOrDefault(c => string.Equals(c.Extension, i, StringComparison.OrdinalIgnoreCase)))
|
||||
.FirstOrDefault(i => i != null);
|
||||
return files.FirstOrDefault(i => ((i.Attributes & FileAttributes.Directory) != FileAttributes.Directory) && string.Equals(name, _fileSystem.GetFileNameWithoutExtension(i), StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -185,6 +185,14 @@ namespace MediaBrowser.Model.ApiClient
|
|||
/// <exception cref="ArgumentNullException">url</exception>
|
||||
Task<Stream> GetImageStreamAsync(string url, CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// Updates the user configuration.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user identifier.</param>
|
||||
/// <param name="configuration">The configuration.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task UpdateUserConfiguration(string userId, UserConfiguration configuration);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a BaseItem
|
||||
/// </summary>
|
||||
|
|
|
@ -144,12 +144,6 @@ namespace MediaBrowser.Model.Configuration
|
|||
/// <value>The image saving convention.</value>
|
||||
public ImageSavingConvention ImageSavingConvention { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [enable people prefix sub folders].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [enable people prefix sub folders]; otherwise, <c>false</c>.</value>
|
||||
public bool EnablePeoplePrefixSubFolders { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the encoding quality.
|
||||
/// </summary>
|
||||
|
@ -179,8 +173,7 @@ namespace MediaBrowser.Model.Configuration
|
|||
public string[] InsecureApps7 { get; set; }
|
||||
|
||||
public bool SaveMetadataHidden { get; set; }
|
||||
|
||||
public bool PlaylistImagesDeleted { get; set; }
|
||||
public string H264Encoder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
|
||||
|
@ -195,7 +188,6 @@ namespace MediaBrowser.Model.Configuration
|
|||
EnableDashboardResponseCaching = true;
|
||||
|
||||
EnableAutomaticRestart = true;
|
||||
EnablePeoplePrefixSubFolders = true;
|
||||
|
||||
EnableUPnP = true;
|
||||
DownMixAudioBoost = 2;
|
||||
|
@ -225,6 +217,7 @@ namespace MediaBrowser.Model.Configuration
|
|||
EnableRealtimeMonitor = true;
|
||||
|
||||
UICulture = "en-us";
|
||||
H264Encoder = "libx264";
|
||||
|
||||
PeopleMetadataOptions = new PeopleMetadataOptions();
|
||||
|
||||
|
|
|
@ -549,7 +549,13 @@ namespace MediaBrowser.Model.Dto
|
|||
/// Gets or sets a value indicating whether [supports playlists].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [supports playlists]; otherwise, <c>false</c>.</value>
|
||||
public bool SupportsPlaylists { get; set; }
|
||||
public bool SupportsPlaylists
|
||||
{
|
||||
get
|
||||
{
|
||||
return RunTimeTicks.HasValue || IsFolder || IsGenre || IsMusicGenre || IsArtist;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified type is type.
|
||||
|
|
|
@ -6,6 +6,11 @@ namespace MediaBrowser.Model.Querying
|
|||
/// </summary>
|
||||
public enum ItemFields
|
||||
{
|
||||
/// <summary>
|
||||
/// The air time
|
||||
/// </summary>
|
||||
AirTime,
|
||||
|
||||
/// <summary>
|
||||
/// The alternate episode numbers
|
||||
/// </summary>
|
||||
|
@ -151,6 +156,11 @@ namespace MediaBrowser.Model.Querying
|
|||
/// </summary>
|
||||
Revenue,
|
||||
|
||||
/// <summary>
|
||||
/// The season name
|
||||
/// </summary>
|
||||
SeasonName,
|
||||
|
||||
/// <summary>
|
||||
/// The short overview
|
||||
/// </summary>
|
||||
|
@ -181,6 +191,11 @@ namespace MediaBrowser.Model.Querying
|
|||
/// </summary>
|
||||
SortName,
|
||||
|
||||
/// <summary>
|
||||
/// The special episode numbers
|
||||
/// </summary>
|
||||
SpecialEpisodeNumbers,
|
||||
|
||||
/// <summary>
|
||||
/// The studios of the item
|
||||
/// </summary>
|
||||
|
|
|
@ -5,6 +5,8 @@ namespace MediaBrowser.Model.Session
|
|||
public string AudioCodec { get; set; }
|
||||
public string VideoCodec { get; set; }
|
||||
public string Container { get; set; }
|
||||
public bool IsVideoDirect { get; set; }
|
||||
public bool IsAudioDirect { get; set; }
|
||||
public int? Bitrate { get; set; }
|
||||
|
||||
public float? Framerate { get; set; }
|
||||
|
|
9
MediaBrowser.Model/Sync/SyncItem.cs
Normal file
9
MediaBrowser.Model/Sync/SyncItem.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
using MediaBrowser.Model.Dto;
|
||||
|
||||
namespace MediaBrowser.Model.Sync
|
||||
{
|
||||
public class SyncItem
|
||||
{
|
||||
public BaseItemDto Item { get; set; }
|
||||
}
|
||||
}
|
|
@ -72,26 +72,29 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||
var features = _channelManager.GetChannelFeatures(channelId);
|
||||
|
||||
const int currentRefreshLevel = 1;
|
||||
var maxRefreshLevel = features.AutoRefreshLevels ?? 1;
|
||||
var maxRefreshLevel = features.AutoRefreshLevels ?? 0;
|
||||
|
||||
var innerProgress = new ActionableProgress<double>();
|
||||
if (maxRefreshLevel > 0)
|
||||
{
|
||||
var innerProgress = new ActionableProgress<double>();
|
||||
|
||||
var startingNumberComplete = numComplete;
|
||||
innerProgress.RegisterAction(p =>
|
||||
{
|
||||
double innerPercent = startingNumberComplete;
|
||||
innerPercent += (p / 100);
|
||||
innerPercent /= numItems;
|
||||
progress.Report(innerPercent * 100);
|
||||
});
|
||||
var startingNumberComplete = numComplete;
|
||||
innerProgress.RegisterAction(p =>
|
||||
{
|
||||
double innerPercent = startingNumberComplete;
|
||||
innerPercent += (p / 100);
|
||||
innerPercent /= numItems;
|
||||
progress.Report(innerPercent * 100);
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
await GetAllItems(user, channelId, null, currentRefreshLevel, maxRefreshLevel, innerProgress, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting channel content", ex);
|
||||
try
|
||||
{
|
||||
await GetAllItems(user, channelId, null, currentRefreshLevel, maxRefreshLevel, innerProgress, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting channel content", ex);
|
||||
}
|
||||
}
|
||||
|
||||
numComplete++;
|
||||
|
|
|
@ -121,8 +121,6 @@ namespace MediaBrowser.Server.Implementations.Dto
|
|||
ServerId = _appHost.SystemId
|
||||
};
|
||||
|
||||
dto.SupportsPlaylists = item.SupportsAddingToPlaylist;
|
||||
|
||||
if (fields.Contains(ItemFields.People))
|
||||
{
|
||||
AttachPeople(dto, item);
|
||||
|
@ -1132,15 +1130,22 @@ namespace MediaBrowser.Server.Implementations.Dto
|
|||
dto.AbsoluteEpisodeNumber = episode.AbsoluteEpisodeNumber;
|
||||
}
|
||||
|
||||
dto.AirsAfterSeasonNumber = episode.AirsAfterSeasonNumber;
|
||||
dto.AirsBeforeEpisodeNumber = episode.AirsBeforeEpisodeNumber;
|
||||
dto.AirsBeforeSeasonNumber = episode.AirsBeforeSeasonNumber;
|
||||
//if (fields.Contains(ItemFields.SpecialEpisodeNumbers))
|
||||
{
|
||||
dto.AirsAfterSeasonNumber = episode.AirsAfterSeasonNumber;
|
||||
dto.AirsBeforeEpisodeNumber = episode.AirsBeforeEpisodeNumber;
|
||||
dto.AirsBeforeSeasonNumber = episode.AirsBeforeSeasonNumber;
|
||||
}
|
||||
|
||||
var episodeSeason = episode.Season;
|
||||
if (episodeSeason != null)
|
||||
{
|
||||
dto.SeasonId = episodeSeason.Id.ToString("N");
|
||||
dto.SeasonName = episodeSeason.Name;
|
||||
|
||||
if (fields.Contains(ItemFields.SeasonName))
|
||||
{
|
||||
dto.SeasonName = episodeSeason.Name;
|
||||
}
|
||||
}
|
||||
|
||||
if (fields.Contains(ItemFields.SeriesGenres))
|
||||
|
@ -1180,7 +1185,11 @@ namespace MediaBrowser.Server.Implementations.Dto
|
|||
{
|
||||
dto.SeriesId = GetDtoId(series);
|
||||
dto.SeriesName = series.Name;
|
||||
dto.AirTime = series.AirTime;
|
||||
|
||||
if (fields.Contains(ItemFields.AirTime))
|
||||
{
|
||||
dto.AirTime = series.AirTime;
|
||||
}
|
||||
|
||||
if (options.GetImageLimit(ImageType.Thumb) > 0)
|
||||
{
|
||||
|
|
|
@ -4,11 +4,11 @@ using MediaBrowser.Controller.Entities.TV;
|
|||
using MediaBrowser.Controller.FileOrganization;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Controller.Resolvers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.FileOrganization;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Naming.Common;
|
||||
using MediaBrowser.Naming.IO;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
|
@ -16,8 +16,6 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Server.Implementations.Library;
|
||||
using MediaBrowser.Server.Implementations.Library.Resolvers.TV;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.FileOrganization
|
||||
{
|
||||
|
@ -57,18 +55,23 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
FileSize = new FileInfo(path).Length
|
||||
};
|
||||
|
||||
var seriesName = SeriesResolver.GetSeriesNameFromEpisodeFile(path);
|
||||
var resolver = new Naming.TV.EpisodeResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
|
||||
|
||||
var episodeInfo = resolver.Resolve(path, FileInfoType.File) ??
|
||||
new Naming.TV.EpisodeInfo();
|
||||
|
||||
var seriesName = episodeInfo.SeriesName;
|
||||
|
||||
if (!string.IsNullOrEmpty(seriesName))
|
||||
{
|
||||
var season = SeriesResolver.GetSeasonNumberFromEpisodeFile(path);
|
||||
var season = episodeInfo.SeasonNumber;
|
||||
|
||||
result.ExtractedSeasonNumber = season;
|
||||
|
||||
if (season.HasValue)
|
||||
{
|
||||
// Passing in true will include a few extra regex's
|
||||
var episode = SeriesResolver.GetEpisodeNumberFromFile(path, true);
|
||||
var episode = episodeInfo.EpisodeNumber;
|
||||
|
||||
result.ExtractedEpisodeNumber = episode;
|
||||
|
||||
|
@ -76,7 +79,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
{
|
||||
_logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, season, episode);
|
||||
|
||||
var endingEpisodeNumber = SeriesResolver.GetEndingEpisodeNumberFromFile(path);
|
||||
var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber;
|
||||
|
||||
result.ExtractedEndingEpisodeNumber = endingEpisodeNumber;
|
||||
|
||||
|
@ -251,7 +254,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
|
||||
var folder = Path.GetDirectoryName(targetPath);
|
||||
var targetFileNameWithoutExtension = _fileSystem.GetFileNameWithoutExtension(targetPath);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
var filesOfOtherExtensions = Directory.EnumerateFiles(folder, "*", SearchOption.TopDirectoryOnly)
|
||||
|
|
|
@ -18,8 +18,8 @@ using MediaBrowser.Model.Logging;
|
|||
using MediaBrowser.Naming.Audio;
|
||||
using MediaBrowser.Naming.Common;
|
||||
using MediaBrowser.Naming.IO;
|
||||
using MediaBrowser.Naming.TV;
|
||||
using MediaBrowser.Naming.Video;
|
||||
using MediaBrowser.Server.Implementations.Library.Resolvers.TV;
|
||||
using MediaBrowser.Server.Implementations.Library.Validators;
|
||||
using MediaBrowser.Server.Implementations.ScheduledTasks;
|
||||
using System;
|
||||
|
@ -862,7 +862,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
|
||||
var type = typeof(T);
|
||||
|
||||
if (type == typeof(Person) && ConfigurationManager.Configuration.EnablePeoplePrefixSubFolders)
|
||||
if (type == typeof(Person))
|
||||
{
|
||||
subFolderPrefix = validFilename.Substring(0, 1);
|
||||
}
|
||||
|
@ -1708,22 +1708,69 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
|
||||
public int? GetSeasonNumberFromPath(string path)
|
||||
{
|
||||
return SeriesResolver.GetSeasonNumberFromPath(path, CollectionType.TvShows);
|
||||
return new SeasonPathParser(new ExtendedNamingOptions(), new RegexProvider()).Parse(path, true).SeasonNumber;
|
||||
}
|
||||
|
||||
public int? GetSeasonNumberFromEpisodeFile(string path)
|
||||
public bool FillMissingEpisodeNumbersFromPath(Episode episode)
|
||||
{
|
||||
return SeriesResolver.GetSeasonNumberFromEpisodeFile(path);
|
||||
}
|
||||
var resolver = new EpisodeResolver(new ExtendedNamingOptions(),
|
||||
new Naming.Logging.NullLogger());
|
||||
|
||||
public int? GetEndingEpisodeNumberFromFile(string path)
|
||||
{
|
||||
return SeriesResolver.GetEndingEpisodeNumberFromFile(path);
|
||||
}
|
||||
var locationType = episode.LocationType;
|
||||
|
||||
var fileType = /*args.IsDirectory ? FileInfoType.Directory :*/ FileInfoType.File;
|
||||
var episodeInfo = locationType == LocationType.FileSystem || locationType == LocationType.Offline ?
|
||||
resolver.Resolve(episode.Path, fileType) :
|
||||
new Naming.TV.EpisodeInfo();
|
||||
|
||||
public int? GetEpisodeNumberFromFile(string path, bool considerSeasonless)
|
||||
{
|
||||
return SeriesResolver.GetEpisodeNumberFromFile(path, considerSeasonless);
|
||||
if (episodeInfo == null)
|
||||
{
|
||||
episodeInfo = new Naming.TV.EpisodeInfo();
|
||||
}
|
||||
|
||||
var changed = false;
|
||||
|
||||
if (!episode.IndexNumber.HasValue)
|
||||
{
|
||||
episode.IndexNumber = episodeInfo.EpisodeNumber;
|
||||
|
||||
if (episode.IndexNumber.HasValue)
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!episode.IndexNumberEnd.HasValue)
|
||||
{
|
||||
episode.IndexNumberEnd = episodeInfo.EndingEpsiodeNumber;
|
||||
|
||||
if (episode.IndexNumberEnd.HasValue)
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!episode.ParentIndexNumber.HasValue)
|
||||
{
|
||||
episode.ParentIndexNumber = episodeInfo.SeasonNumber;
|
||||
|
||||
if (!episode.ParentIndexNumber.HasValue)
|
||||
{
|
||||
var season = episode.Season;
|
||||
|
||||
if (season != null)
|
||||
{
|
||||
episode.ParentIndexNumber = season.IndexNumber;
|
||||
}
|
||||
}
|
||||
|
||||
if (episode.ParentIndexNumber.HasValue)
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
public ItemLookupInfo ParseName(string name)
|
||||
|
|
|
@ -82,8 +82,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
|
|||
return ResolveVideos<Movie>(parent, files, directoryService, collectionType);
|
||||
}
|
||||
|
||||
if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(collectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
|
||||
if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return ResolveVideos<Movie>(parent, files, directoryService, collectionType);
|
||||
}
|
||||
|
@ -117,7 +116,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
|
|||
FullName = i.FullName,
|
||||
Type = FileInfoType.File
|
||||
|
||||
}).ToList()).ToList();
|
||||
}).ToList(), false).ToList();
|
||||
|
||||
var result = new MultiItemResolverResult
|
||||
{
|
||||
|
@ -168,12 +167,12 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
|
|||
{
|
||||
if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return FindMovie<MusicVideo>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, collectionType, false);
|
||||
return FindMovie<MusicVideo>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, collectionType);
|
||||
}
|
||||
|
||||
if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return FindMovie<Video>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, collectionType, false);
|
||||
return FindMovie<Video>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, collectionType);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(collectionType))
|
||||
|
@ -193,8 +192,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
|
|||
return FindMovie<Movie>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, collectionType);
|
||||
}
|
||||
|
||||
if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(collectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
|
||||
if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return FindMovie<Movie>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, collectionType);
|
||||
}
|
||||
|
@ -216,8 +214,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
|
|||
}
|
||||
|
||||
// To find a movie file, the collection type must be movies or boxsets
|
||||
else if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(collectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
|
||||
else if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
item = ResolveVideo<Movie>(args, true);
|
||||
}
|
||||
|
@ -277,9 +274,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
|
|||
/// <param name="fileSystemEntries">The file system entries.</param>
|
||||
/// <param name="directoryService">The directory service.</param>
|
||||
/// <param name="collectionType">Type of the collection.</param>
|
||||
/// <param name="supportMultiVersion">if set to <c>true</c> [support multi version].</param>
|
||||
/// <returns>Movie.</returns>
|
||||
private T FindMovie<T>(string path, Folder parent, List<FileSystemInfo> fileSystemEntries, IDirectoryService directoryService, string collectionType, bool supportMultiVersion = true)
|
||||
private T FindMovie<T>(string path, Folder parent, List<FileSystemInfo> fileSystemEntries, IDirectoryService directoryService, string collectionType)
|
||||
where T : Video, new()
|
||||
{
|
||||
var multiDiscFolders = new List<FileSystemInfo>();
|
||||
|
@ -328,8 +324,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
|
|||
|
||||
var result = ResolveVideos<T>(parent, fileSystemEntries, directoryService, collectionType);
|
||||
|
||||
var supportsMultiVersion = !string.Equals(collectionType, CollectionType.HomeVideos) &&
|
||||
!string.Equals(collectionType, CollectionType.MusicVideos);
|
||||
|
||||
// Test for multi-editions
|
||||
if (result.Items.Count > 1 && supportMultiVersion)
|
||||
if (result.Items.Count > 1 && supportsMultiVersion)
|
||||
{
|
||||
var filenamePrefix = Path.GetFileName(path);
|
||||
|
||||
|
@ -474,7 +473,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
|
|||
CollectionType.Movies,
|
||||
CollectionType.HomeVideos,
|
||||
CollectionType.MusicVideos,
|
||||
CollectionType.BoxSets,
|
||||
CollectionType.Movies
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Naming.Common;
|
||||
using MediaBrowser.Naming.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
|
||||
|
@ -37,23 +39,10 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
|
|||
}
|
||||
|
||||
// If the parent is a Season or Series, then this is an Episode if the VideoResolver returns something
|
||||
if (season != null || parent is Series || parent.Parents.OfType<Series>().Any())
|
||||
if (season != null || args.HasParent<Series>())
|
||||
{
|
||||
var episode = ResolveVideo<Episode>(args, false);
|
||||
|
||||
if (episode != null)
|
||||
{
|
||||
if (season != null)
|
||||
{
|
||||
episode.ParentIndexNumber = season.IndexNumber;
|
||||
}
|
||||
|
||||
if (episode.ParentIndexNumber == null)
|
||||
{
|
||||
episode.ParentIndexNumber = SeriesResolver.GetSeasonNumberFromEpisodeFile(args.Path);
|
||||
}
|
||||
}
|
||||
|
||||
return episode;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Naming.Common;
|
||||
using MediaBrowser.Naming.TV;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
|
||||
{
|
||||
|
@ -35,7 +36,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
|
|||
{
|
||||
var season = new Season
|
||||
{
|
||||
IndexNumber = SeriesResolver.GetSeasonNumberFromPath(args.Path, CollectionType.TvShows)
|
||||
IndexNumber = new SeasonPathParser(new ExtendedNamingOptions(), new RegexProvider()).Parse(args.Path, true).SeasonNumber
|
||||
};
|
||||
|
||||
if (season.IndexNumber.HasValue && season.IndexNumber.Value == 0)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
|
@ -9,10 +8,10 @@ using MediaBrowser.Model.Entities;
|
|||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using MediaBrowser.Naming.Common;
|
||||
using MediaBrowser.Naming.IO;
|
||||
using MediaBrowser.Naming.TV;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
|
||||
{
|
||||
|
@ -67,13 +66,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
|
|||
|
||||
var collectionType = args.GetCollectionType();
|
||||
|
||||
var isTvShowsFolder = string.Equals(collectionType, CollectionType.TvShows,
|
||||
StringComparison.OrdinalIgnoreCase);
|
||||
var isTvShowsFolder = string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
// If there's a collection type and it's not tv, it can't be a series
|
||||
if (!string.IsNullOrEmpty(collectionType) &&
|
||||
!isTvShowsFolder &&
|
||||
!string.Equals(collectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
|
||||
!isTvShowsFolder)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
@ -123,7 +120,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
|
|||
|
||||
if ((attributes & FileAttributes.Directory) == FileAttributes.Directory)
|
||||
{
|
||||
if (IsSeasonFolder(child.FullName, collectionType, directoryService, fileSystem))
|
||||
if (IsSeasonFolder(child.FullName, collectionType))
|
||||
{
|
||||
//logger.Debug("{0} is a series because of season folder {1}.", path, child.FullName);
|
||||
return true;
|
||||
|
@ -137,7 +134,17 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
|
|||
{
|
||||
var isTvShowsFolder = string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (GetEpisodeNumberFromFile(fullName, isTvShowsFolder).HasValue)
|
||||
// We can fast track this for known tv folders
|
||||
if (isTvShowsFolder)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var resolver = new Naming.TV.EpisodeResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
|
||||
|
||||
var episodeInfo = resolver.Resolve(fullName, FileInfoType.File, isTvShowsFolder, false);
|
||||
|
||||
if (episodeInfo != null && (episodeInfo.EpisodeNumber.HasValue || episodeInfo.IsByDate))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -172,351 +179,13 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
|
|||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="collectionType">Type of the collection.</param>
|
||||
/// <param name="directoryService">The directory service.</param>
|
||||
/// <param name="fileSystem">The file system.</param>
|
||||
/// <returns><c>true</c> if [is season folder] [the specified path]; otherwise, <c>false</c>.</returns>
|
||||
private static bool IsSeasonFolder(string path, string collectionType, IDirectoryService directoryService, IFileSystem fileSystem)
|
||||
private static bool IsSeasonFolder(string path, string collectionType)
|
||||
{
|
||||
var seasonNumber = GetSeasonNumberFromPath(path, collectionType);
|
||||
var hasSeasonNumber = seasonNumber != null;
|
||||
var isTvFolder = string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase);
|
||||
var seasonNumber = new SeasonPathParser(new ExtendedNamingOptions(), new RegexProvider()).Parse(path, isTvFolder).SeasonNumber;
|
||||
|
||||
if (!hasSeasonNumber)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//// It's a season folder if it's named as such and does not contain any audio files, apart from theme.mp3
|
||||
//foreach (var fileSystemInfo in directoryService.GetFileSystemEntries(path))
|
||||
//{
|
||||
// var attributes = fileSystemInfo.Attributes;
|
||||
|
||||
// if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// // Can't enforce this because files saved by Bitcasa are always marked System
|
||||
// //if ((attributes & FileAttributes.System) == FileAttributes.System)
|
||||
// //{
|
||||
// // continue;
|
||||
// //}
|
||||
|
||||
// if ((attributes & FileAttributes.Directory) == FileAttributes.Directory)
|
||||
// {
|
||||
// //if (IsBadFolder(fileSystemInfo.Name))
|
||||
// //{
|
||||
// // return false;
|
||||
// //}
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (EntityResolutionHelper.IsAudioFile(fileSystemInfo.FullName) &&
|
||||
// !string.Equals(fileSystem.GetFileNameWithoutExtension(fileSystemInfo), BaseItem.ThemeSongFilename))
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A season folder must contain one of these somewhere in the name
|
||||
/// </summary>
|
||||
private static readonly string[] SeasonFolderNames =
|
||||
{
|
||||
"season",
|
||||
"sæson",
|
||||
"temporada",
|
||||
"saison",
|
||||
"staffel",
|
||||
"series",
|
||||
"сезон"
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Used to detect paths that represent episodes, need to make sure they don't also
|
||||
/// match movie titles like "2001 A Space..."
|
||||
/// Currently we limit the numbers here to 2 digits to try and avoid this
|
||||
/// </summary>
|
||||
private static readonly Regex[] EpisodeExpressions =
|
||||
{
|
||||
new Regex(
|
||||
@".*(\\|\/)[sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3})[^\\\/]*$",
|
||||
RegexOptions.Compiled),
|
||||
new Regex(
|
||||
@".*(\\|\/)[sS](?<seasonnumber>\d{1,4})[x,X]?[eE](?<epnumber>\d{1,3})[^\\\/]*$",
|
||||
RegexOptions.Compiled),
|
||||
new Regex(
|
||||
@".*(\\|\/)(?<seriesname>((?![sS]?\d{1,4}[xX]\d{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3}))[^\\\/]*$",
|
||||
RegexOptions.Compiled),
|
||||
new Regex(
|
||||
@".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>\d{1,4})[xX\.]?[eE](?<epnumber>\d{1,3})[^\\\/]*$",
|
||||
RegexOptions.Compiled)
|
||||
};
|
||||
private static readonly Regex[] MultipleEpisodeExpressions =
|
||||
{
|
||||
new Regex(
|
||||
@".*(\\|\/)[sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3})((-| - )\d{1,4}[eExX](?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
||||
RegexOptions.Compiled),
|
||||
new Regex(
|
||||
@".*(\\|\/)[sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3})((-| - )\d{1,4}[xX][eE](?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
||||
RegexOptions.Compiled),
|
||||
new Regex(
|
||||
@".*(\\|\/)[sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3})((-| - )?[xXeE](?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
||||
RegexOptions.Compiled),
|
||||
new Regex(
|
||||
@".*(\\|\/)[sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3})(-[xE]?[eE]?(?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
||||
RegexOptions.Compiled),
|
||||
new Regex(
|
||||
@".*(\\|\/)(?<seriesname>((?![sS]?\d{1,4}[xX]\d{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3}))((-| - )\d{1,4}[xXeE](?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
||||
RegexOptions.Compiled),
|
||||
new Regex(
|
||||
@".*(\\|\/)(?<seriesname>((?![sS]?\d{1,4}[xX]\d{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3}))((-| - )\d{1,4}[xX][eE](?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
||||
RegexOptions.Compiled),
|
||||
new Regex(
|
||||
@".*(\\|\/)(?<seriesname>((?![sS]?\d{1,4}[xX]\d{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3}))((-| - )?[xXeE](?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
||||
RegexOptions.Compiled),
|
||||
new Regex(
|
||||
@".*(\\|\/)(?<seriesname>((?![sS]?\d{1,4}[xX]\d{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3}))(-[xX]?[eE]?(?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
||||
RegexOptions.Compiled),
|
||||
new Regex(
|
||||
@".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>\d{1,4})[xX\.]?[eE](?<epnumber>\d{1,3})((-| - )?[xXeE](?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
||||
RegexOptions.Compiled),
|
||||
new Regex(
|
||||
@".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>\d{1,4})[xX\.]?[eE](?<epnumber>\d{1,3})(-[xX]?[eE]?(?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
||||
RegexOptions.Compiled)
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// To avoid the following matching movies they are only valid when contained in a folder which has been matched as a being season, or the media type is TV series
|
||||
/// </summary>
|
||||
private static readonly Regex[] EpisodeExpressionsWithoutSeason =
|
||||
{
|
||||
new Regex(
|
||||
@".*[\\\/](?<epnumber>\d{1,3})(-(?<endingepnumber>\d{2,3}))*\.\w+$",
|
||||
RegexOptions.Compiled),
|
||||
// "01.avi"
|
||||
new Regex(
|
||||
@".*(\\|\/)(?<epnumber>\d{1,3})(-(?<endingepnumber>\d{2,3}))*\s?-\s?[^\\\/]*$",
|
||||
RegexOptions.Compiled),
|
||||
// "01 - blah.avi", "01-blah.avi"
|
||||
new Regex(
|
||||
@".*(\\|\/)(?<epnumber>\d{1,3})(-(?<endingepnumber>\d{2,3}))*\.[^\\\/]+$",
|
||||
RegexOptions.Compiled),
|
||||
// "01.blah.avi"
|
||||
new Regex(
|
||||
@".*[\\\/][^\\\/]* - (?<epnumber>\d{1,3})(-(?<endingepnumber>\d{2,3}))*[^\\\/]*$",
|
||||
RegexOptions.Compiled),
|
||||
// "blah - 01.avi", "blah 2 - 01.avi", "blah - 01 blah.avi", "blah 2 - 01 blah", "blah - 01 - blah.avi", "blah 2 - 01 - blah"
|
||||
};
|
||||
|
||||
public static int? GetSeasonNumberFromPath(string path)
|
||||
{
|
||||
return GetSeasonNumberFromPath(path, CollectionType.TvShows);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the season number from path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="collectionType">Type of the collection.</param>
|
||||
/// <returns>System.Nullable{System.Int32}.</returns>
|
||||
public static int? GetSeasonNumberFromPath(string path, string collectionType)
|
||||
{
|
||||
var filename = Path.GetFileName(path);
|
||||
|
||||
if (string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (string.Equals(filename, "specials", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int val;
|
||||
if (int.TryParse(filename, NumberStyles.Integer, CultureInfo.InvariantCulture, out val))
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
if (filename.StartsWith("s", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var testFilename = filename.Substring(1);
|
||||
|
||||
if (int.TryParse(testFilename, NumberStyles.Integer, CultureInfo.InvariantCulture, out val))
|
||||
{
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
// Look for one of the season folder names
|
||||
foreach (var name in SeasonFolderNames)
|
||||
{
|
||||
var index = filename.IndexOf(name, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
return GetSeasonNumberFromPathSubstring(filename.Substring(index + name.Length));
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts the season number from the second half of the Season folder name (everything after "Season", or "Staffel")
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>System.Nullable{System.Int32}.</returns>
|
||||
private static int? GetSeasonNumberFromPathSubstring(string path)
|
||||
{
|
||||
var numericStart = -1;
|
||||
var length = 0;
|
||||
|
||||
// Find out where the numbers start, and then keep going until they end
|
||||
for (var i = 0; i < path.Length; i++)
|
||||
{
|
||||
if (char.IsNumber(path, i))
|
||||
{
|
||||
if (numericStart == -1)
|
||||
{
|
||||
numericStart = i;
|
||||
}
|
||||
length++;
|
||||
}
|
||||
else if (numericStart != -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (numericStart == -1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return int.Parse(path.Substring(numericStart, length), CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Episodes the number from file.
|
||||
/// </summary>
|
||||
/// <param name="fullPath">The full path.</param>
|
||||
/// <param name="considerSeasonlessNames">if set to <c>true</c> [is in season].</param>
|
||||
/// <returns>System.String.</returns>
|
||||
public static int? GetEpisodeNumberFromFile(string fullPath, bool considerSeasonlessNames)
|
||||
{
|
||||
string fl = fullPath.ToLower();
|
||||
foreach (var r in EpisodeExpressions)
|
||||
{
|
||||
Match m = r.Match(fl);
|
||||
if (m.Success)
|
||||
return ParseEpisodeNumber(m.Groups["epnumber"].Value);
|
||||
}
|
||||
if (considerSeasonlessNames)
|
||||
{
|
||||
var match = EpisodeExpressionsWithoutSeason.Select(r => r.Match(fl))
|
||||
.FirstOrDefault(m => m.Success);
|
||||
|
||||
if (match != null)
|
||||
{
|
||||
return ParseEpisodeNumber(match.Groups["epnumber"].Value);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int? GetEndingEpisodeNumberFromFile(string fullPath)
|
||||
{
|
||||
var fl = fullPath.ToLower();
|
||||
foreach (var r in MultipleEpisodeExpressions)
|
||||
{
|
||||
var m = r.Match(fl);
|
||||
if (m.Success && !string.IsNullOrEmpty(m.Groups["endingepnumber"].Value))
|
||||
return ParseEpisodeNumber(m.Groups["endingepnumber"].Value);
|
||||
}
|
||||
foreach (var r in EpisodeExpressionsWithoutSeason)
|
||||
{
|
||||
var m = r.Match(fl);
|
||||
if (m.Success && !string.IsNullOrEmpty(m.Groups["endingepnumber"].Value))
|
||||
return ParseEpisodeNumber(m.Groups["endingepnumber"].Value);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Seasons the number from episode file.
|
||||
/// </summary>
|
||||
/// <param name="fullPath">The full path.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
public static int? GetSeasonNumberFromEpisodeFile(string fullPath)
|
||||
{
|
||||
string fl = fullPath.ToLower();
|
||||
foreach (var r in EpisodeExpressions)
|
||||
{
|
||||
Match m = r.Match(fl);
|
||||
if (m.Success)
|
||||
{
|
||||
Group g = m.Groups["seasonnumber"];
|
||||
if (g != null)
|
||||
{
|
||||
var val = g.Value;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
int num;
|
||||
|
||||
if (int.TryParse(val, NumberStyles.Integer, UsCulture, out num))
|
||||
{
|
||||
return num;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string GetSeriesNameFromEpisodeFile(string fullPath)
|
||||
{
|
||||
var fl = fullPath.ToLower();
|
||||
foreach (var r in EpisodeExpressions)
|
||||
{
|
||||
var m = r.Match(fl);
|
||||
if (m.Success)
|
||||
{
|
||||
var g = m.Groups["seriesname"];
|
||||
if (g != null)
|
||||
{
|
||||
var val = g.Value;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
private static int? ParseEpisodeNumber(string val)
|
||||
{
|
||||
int num;
|
||||
|
||||
if (!string.IsNullOrEmpty(val) && int.TryParse(val, NumberStyles.Integer, UsCulture, out num))
|
||||
{
|
||||
return num;
|
||||
}
|
||||
|
||||
return null;
|
||||
return seasonNumber.HasValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -781,20 +781,29 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
{
|
||||
lock (_policySyncLock)
|
||||
{
|
||||
return (UserPolicy)_xmlSerializer.DeserializeFromFile(typeof(UserPolicy), path);
|
||||
return (UserPolicy) _xmlSerializer.DeserializeFromFile(typeof (UserPolicy), path);
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
return GetDefaultPolicy(user);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error reading policy file: {0}", ex, path);
|
||||
|
||||
return new UserPolicy
|
||||
{
|
||||
EnableSync = !user.ConnectLinkType.HasValue || user.ConnectLinkType.Value != UserLinkType.Guest
|
||||
};
|
||||
return GetDefaultPolicy(user);
|
||||
}
|
||||
}
|
||||
|
||||
private UserPolicy GetDefaultPolicy(User user)
|
||||
{
|
||||
return new UserPolicy
|
||||
{
|
||||
EnableSync = true
|
||||
};
|
||||
}
|
||||
|
||||
private readonly object _policySyncLock = new object();
|
||||
public async Task UpdateUserPolicy(string userId, UserPolicy userPolicy)
|
||||
{
|
||||
|
|
|
@ -650,7 +650,7 @@
|
|||
"OptionLow": "Low",
|
||||
"HeaderSettings": "Settings",
|
||||
"OptionAutomaticallySyncNewContent": "Automatically sync new content",
|
||||
"OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
|
||||
"OptionAutomaticallySyncNewContentHelp": "New content added to this category will be automatically synced to the device.",
|
||||
"OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
|
||||
"OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched.",
|
||||
"LabelItemLimit": "Item limit:",
|
||||
|
|
|
@ -1295,5 +1295,6 @@
|
|||
"LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
|
||||
"LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
|
||||
"TabActivity": "Activity",
|
||||
"TitleSync": "Sync"
|
||||
"TitleSync": "Sync",
|
||||
"OptionAllowSyncContent": "Allow syncing media to devices"
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
</Reference>
|
||||
<Reference Include="MediaBrowser.Naming, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\MediaBrowser.Naming.1.0.0.18\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll</HintPath>
|
||||
<HintPath>..\packages\MediaBrowser.Naming.1.0.0.21\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Mono.Nat, Version=1.2.21.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
|||
|
||||
public bool IsHidden
|
||||
{
|
||||
get { return true; }
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public bool IsEnabled
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="MediaBrowser.Naming" version="1.0.0.18" targetFramework="net45" />
|
||||
<package id="MediaBrowser.Naming" version="1.0.0.21" targetFramework="net45" />
|
||||
<package id="Mono.Nat" version="1.2.21.0" targetFramework="net45" />
|
||||
<package id="morelinq" version="1.1.0" targetFramework="net45" />
|
||||
</packages>
|
|
@ -363,7 +363,6 @@ namespace MediaBrowser.Server.Startup.Common
|
|||
var migrations = new List<IVersionMigration>
|
||||
{
|
||||
new MigrateUserFolders(ApplicationPaths),
|
||||
new PlaylistImages(ServerConfigurationManager),
|
||||
new RenameXbmcOptions(ServerConfigurationManager),
|
||||
new RenameXmlOptions(ServerConfigurationManager),
|
||||
new DeprecatePlugins(ApplicationPaths),
|
||||
|
|
|
@ -67,7 +67,6 @@
|
|||
<Compile Include="Migrations\DeprecatePlugins.cs" />
|
||||
<Compile Include="Migrations\IVersionMigration.cs" />
|
||||
<Compile Include="Migrations\MigrateUserFolders.cs" />
|
||||
<Compile Include="Migrations\PlaylistImages.cs" />
|
||||
<Compile Include="Migrations\RenameXbmcOptions.cs" />
|
||||
<Compile Include="Migrations\RenameXmlOptions.cs" />
|
||||
<Compile Include="NativeEnvironment.cs" />
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Server.Startup.Common.Migrations
|
||||
{
|
||||
public class PlaylistImages : IVersionMigration
|
||||
{
|
||||
private readonly IServerConfigurationManager _config;
|
||||
|
||||
public PlaylistImages(IServerConfigurationManager config)
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
if (!_config.Configuration.PlaylistImagesDeleted)
|
||||
{
|
||||
DeletePlaylistImages();
|
||||
_config.Configuration.PlaylistImagesDeleted = true;
|
||||
_config.SaveConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
private void DeletePlaylistImages()
|
||||
{
|
||||
try
|
||||
{
|
||||
var path = Path.Combine(_config.ApplicationPaths.DataPath, "playlists");
|
||||
|
||||
var files = Directory.GetFiles(path, "*", SearchOption.AllDirectories)
|
||||
.Where(i => BaseItem.SupportedImageExtensions.Contains(Path.GetExtension(i) ?? string.Empty))
|
||||
.ToList();
|
||||
|
||||
foreach (var file in files)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(file);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -53,7 +53,6 @@
|
|||
<Compile Include="MediaEncoding\Subtitles\AssParserTests.cs" />
|
||||
<Compile Include="MediaEncoding\Subtitles\SrtParserTests.cs" />
|
||||
<Compile Include="MediaEncoding\Subtitles\VttWriterTest.cs" />
|
||||
<Compile Include="Resolvers\TvUtilTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,246 +0,0 @@
|
|||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Server.Implementations.Library.Resolvers.TV;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace MediaBrowser.Tests.Resolvers
|
||||
{
|
||||
[TestClass]
|
||||
public class TvUtilTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestGetEpisodeNumberFromFile()
|
||||
{
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 02\S02E03 blah.avi", true));
|
||||
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 1\01x02 blah.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 1\S01x02 blah.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 1\S01E02 blah.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 1\S01xE02 blah.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 1\seriesname 01x02 blah.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 1\seriesname S01x02 blah.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 1\seriesname S01E02 blah.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 1\seriesname S01xE02 blah.avi", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2\Elementary - 02x03 - 02x04 - 02x15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2\02x03 - 02x04 - 02x15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2\02x03-04-15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2\Elementary - 02x03-04-15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 02\02x03-E15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 02\Elementary - 02x03-E15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 02\02x03 - x04 - x15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 02\Elementary - 02x03 - x04 - x15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 02\02x03x04x15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 02\Elementary - 02x03x04x15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(23, SeriesResolver.GetEpisodeNumberFromFile(@"Season 1\Elementary - S01E23-E24-E26 - The Woman.mp4", true));
|
||||
Assert.AreEqual(23, SeriesResolver.GetEpisodeNumberFromFile(@"Season 1\S01E23-E24-E26 - The Woman.mp4", true));
|
||||
Assert.AreEqual(9, SeriesResolver.GetEpisodeNumberFromFile(@"Season 25\The Simpsons.S25E09.Steal this episode.mp4", true));
|
||||
Assert.AreEqual(8, SeriesResolver.GetEpisodeNumberFromFile(@"The Simpsons\The Simpsons.S25E08.Steal this episode.mp4", false));
|
||||
Assert.AreEqual(136, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2\[HorribleSubs] Hunter X Hunter - 136 [720p].mkv",true));
|
||||
|
||||
//Four Digits seasons
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\2009x02 blah.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\S2009x02 blah.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\S2009E02 blah.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\S2009xE02 blah.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\seriesname 2009x02 blah.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\seriesname S2009x02 blah.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\seriesname S2009E02 blah.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\seriesname S2009xE02 blah.avi", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03 - 2009x04 - 2009x15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\2009x03 - 2009x04 - 2009x15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\2009x03-04-15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03-04-15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\2009x03-E15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03-E15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\2009x03 - x04 - x15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03 - x04 - x15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\2009x03x04x15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(03, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03x04x15 - Ep Name.ext", true));
|
||||
Assert.AreEqual(23, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\Elementary - S2009E23-E24-E26 - The Woman.mp4", true));
|
||||
Assert.AreEqual(23, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2009\S2009E23-E24-E26 - The Woman.mp4", true));
|
||||
|
||||
//Without season number
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 1\02 - blah.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2\02 - blah 14 blah.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 1\02 - blah-02 a.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"Season 2\02.avi", true));
|
||||
|
||||
//Without seasons
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"The Simpsons\02.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"The Simpsons\02 - Ep Name.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"The Simpsons\02-Ep Name.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"The Simpsons\02.EpName.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"The Simpsons\The Simpsons - 02.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"The Simpsons\The Simpsons - 02 - Ep Name.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"The Simpsons\The Simpsons - 02 Ep Name.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"The Simpsons\The Simpsons 5 - 02 - Ep Name.avi", true));
|
||||
Assert.AreEqual(02, SeriesResolver.GetEpisodeNumberFromFile(@"The Simpsons\The Simpsons 5 - 02 Ep Name.avi", true));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestGetEndingEpisodeNumberFromFile()
|
||||
{
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 1\4x01 – 20 Hours in America (1).mkv"));
|
||||
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 1\01x02 blah.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 1\S01x02 blah.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 1\S01E02 blah.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 1\S01xE02 blah.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 1\seriesname 01x02 blah.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 1\seriesname S01x02 blah.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 1\seriesname S01E02 blah.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 1\seriesname S01xE02 blah.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2\02x03 - 04 Ep Name.ext"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2\My show name 02x03 - 04 Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2\Elementary - 02x03 - 02x04 - 02x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2\02x03 - 02x04 - 02x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2\02x03-04-15 - Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2\Elementary - 02x03-04-15 - Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 02\02x03-E15 - Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 02\Elementary - 02x03-E15 - Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 02\02x03 - x04 - x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 02\Elementary - 02x03 - x04 - x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 02\02x03x04x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 02\Elementary - 02x03x04x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(26, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 1\Elementary - S01E23-E24-E26 - The Woman.mp4"));
|
||||
Assert.AreEqual(26, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 1\S01E23-E24-E26 - The Woman.mp4"));
|
||||
|
||||
|
||||
//Four Digits seasons
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\2009x02 blah.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\S2009x02 blah.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\S2009E02 blah.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\S2009xE02 blah.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\seriesname 2009x02 blah.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\seriesname S2009x02 blah.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\seriesname S2009E02 blah.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\seriesname S2009xE02 blah.avi"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03 - 2009x04 - 2009x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\2009x03 - 2009x04 - 2009x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\2009x03-04-15 - Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03-04-15 - Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\2009x03-E15 - Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03-E15 - Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\2009x03 - x04 - x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03 - x04 - x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\2009x03x04x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(15, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03x04x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(26, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\Elementary - S2009E23-E24-E26 - The Woman.mp4"));
|
||||
Assert.AreEqual(26, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2009\S2009E23-E24-E26 - The Woman.mp4"));
|
||||
|
||||
//Without season number
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 1\02 - blah.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2\02 - blah 14 blah.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 1\02 - blah-02 a.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2\02.avi"));
|
||||
|
||||
Assert.AreEqual(3, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 1\02-03 - blah.avi"));
|
||||
Assert.AreEqual(4, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2\02-04 - blah 14 blah.avi"));
|
||||
Assert.AreEqual(5, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 1\02-05 - blah-02 a.avi"));
|
||||
Assert.AreEqual(4, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2\02-04.avi"));
|
||||
Assert.AreEqual(null, SeriesResolver.GetEndingEpisodeNumberFromFile(@"Season 2\[HorribleSubs] Hunter X Hunter - 136 [720p].mkv"));
|
||||
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestGetSeasonNumberFromPath() {
|
||||
|
||||
Assert.AreEqual(02, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"\Show\Season 02\S02E03 blah.avi"));
|
||||
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 1"));
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 1"));
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 1"));
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 1"));
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 1"));
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 1"));
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 1"));
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 1"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 02"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 02"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 02"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 02"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 02"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 02"));
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 1"));
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 1"));
|
||||
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Seinfeld\S02"));
|
||||
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Seinfeld\2"));
|
||||
|
||||
//Four Digits seasons
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestGetSeasonNumberFromEpisodeFile()
|
||||
{
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 1\01x02 blah.avi"));
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 1\S01x02 blah.avi"));
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 1\S01E02 blah.avi"));
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 1\S01xE02 blah.avi"));
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 1\seriesname 01x02 blah.avi"));
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 1\seriesname S01x02 blah.avi"));
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 1\seriesname S01E02 blah.avi"));
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 1\seriesname S01xE02 blah.avi"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2\Elementary - 02x03 - 02x04 - 02x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2\02x03 - 02x04 - 02x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2\02x03-04-15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2\Elementary - 02x03-04-15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 02\02x03-E15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 02\Elementary - 02x03-E15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 02\02x03 - x04 - x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 02\Elementary - 02x03 - x04 - x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 02\02x03x04x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 02\Elementary - 02x03x04x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 1\Elementary - S01E23-E24-E26 - The Woman.mp4"));
|
||||
Assert.AreEqual(1, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 1\S01E23-E24-E26 - The Woman.mp4"));
|
||||
|
||||
//Four Digits seasons
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\2009x02 blah.avi"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\S2009x02 blah.avi"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\S2009E02 blah.avi"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\S2009xE02 blah.avi"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\seriesname 2009x02 blah.avi"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\seriesname S2009x02 blah.avi"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\seriesname S2009E02 blah.avi"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\seriesname S2009xE02 blah.avi"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\Elementary - 2009x03 - 2009x04 - 2009x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\2009x03 - 2009x04 - 2009x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\2009x03-04-15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\Elementary - 2009x03-04-15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\2009x03-E15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\Elementary - 2009x03-E15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\2009x03 - x04 - x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\Elementary - 2009x03 - x04 - x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\2009x03x04x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\Elementary - 2009x03x04x15 - Ep Name.ext"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\Elementary - S2009E23-E24-E26 - The Woman.mp4"));
|
||||
Assert.AreEqual(2009, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 2009\S2009E23-E24-E26 - The Woman.mp4"));
|
||||
Assert.AreEqual(25, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"Season 25\The Simpsons.S25E09.Steal this episode.mp4"));
|
||||
Assert.AreEqual(25, SeriesResolver.GetSeasonNumberFromEpisodeFile(@"The Simpsons\The Simpsons.S25E09.Steal this episode.mp4"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -197,6 +197,7 @@ namespace MediaBrowser.WebDashboard.Api
|
|||
{
|
||||
"thirdparty/jquerymobile-1.4.5/jquery.mobile-1.4.5.min.css",
|
||||
"thirdparty/swipebox-master/css/swipebox.min.css" + versionString,
|
||||
"thirdparty/fontawesome/css/font-awesome.min.css" + versionString,
|
||||
"css/all.css" + versionString
|
||||
};
|
||||
|
||||
|
|
|
@ -963,6 +963,15 @@
|
|||
<Content Include="dashboard-ui\thirdparty\cast_sender.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\thirdparty\fontawesome\css\font-awesome.css">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\thirdparty\fontawesome\css\font-awesome.min.css">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\thirdparty\fontawesome\fonts\fontawesome-webfont.svg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\thirdparty\jquery-2.1.1.min.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
@ -2917,6 +2926,18 @@
|
|||
<None Include="dashboard-ui\css\fonts\RobotoThin.woff">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="dashboard-ui\thirdparty\fontawesome\fonts\fontawesome-webfont.eot">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="dashboard-ui\thirdparty\fontawesome\fonts\fontawesome-webfont.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="dashboard-ui\thirdparty\fontawesome\fonts\fontawesome-webfont.woff">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="dashboard-ui\thirdparty\fontawesome\fonts\FontAwesome.otf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="dashboard-ui\thirdparty\jquerymobile-1.4.4\jquery.mobile-1.4.3.min.map">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
|
|
@ -7,7 +7,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{F0E0E6
|
|||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8C5D6ABC-D277-407B-8061-3AA04251D539}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
Performance1.psess = Performance1.psess
|
||||
Performance19.psess = Performance19.psess
|
||||
Performance2.psess = Performance2.psess
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget (2)", ".nuget (2)", "{E60FB157-87E2-4A41-8B04-27EA49B63B4D}"
|
||||
|
@ -516,4 +518,7 @@ Global
|
|||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(Performance) = preSolution
|
||||
HasPerformanceSessions = true
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>MediaBrowser.Common.Internal</id>
|
||||
<version>3.0.521</version>
|
||||
<version>3.0.522</version>
|
||||
<title>MediaBrowser.Common.Internal</title>
|
||||
<authors>Luke</authors>
|
||||
<owners>ebr,Luke,scottisafool</owners>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
|
||||
<copyright>Copyright © Media Browser 2013</copyright>
|
||||
<dependencies>
|
||||
<dependency id="MediaBrowser.Common" version="3.0.521" />
|
||||
<dependency id="MediaBrowser.Common" version="3.0.522" />
|
||||
<dependency id="NLog" version="3.1.0.0" />
|
||||
<dependency id="SimpleInjector" version="2.6.1" />
|
||||
<dependency id="sharpcompress" version="0.10.2" />
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>MediaBrowser.Common</id>
|
||||
<version>3.0.521</version>
|
||||
<version>3.0.522</version>
|
||||
<title>MediaBrowser.Common</title>
|
||||
<authors>Media Browser Team</authors>
|
||||
<owners>ebr,Luke,scottisafool</owners>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>MediaBrowser.Model.Signed</id>
|
||||
<version>3.0.521</version>
|
||||
<version>3.0.522</version>
|
||||
<title>MediaBrowser.Model - Signed Edition</title>
|
||||
<authors>Media Browser Team</authors>
|
||||
<owners>ebr,Luke,scottisafool</owners>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>MediaBrowser.Server.Core</id>
|
||||
<version>3.0.521</version>
|
||||
<version>3.0.522</version>
|
||||
<title>Media Browser.Server.Core</title>
|
||||
<authors>Media Browser Team</authors>
|
||||
<owners>ebr,Luke,scottisafool</owners>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<description>Contains core components required to build plugins for Media Browser Server.</description>
|
||||
<copyright>Copyright © Media Browser 2013</copyright>
|
||||
<dependencies>
|
||||
<dependency id="MediaBrowser.Common" version="3.0.521" />
|
||||
<dependency id="MediaBrowser.Common" version="3.0.522" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System.Reflection;
|
||||
|
||||
//[assembly: AssemblyVersion("3.0.*")]
|
||||
[assembly: AssemblyVersion("3.0.5464.40000")]
|
||||
[assembly: AssemblyVersion("3.0.*")]
|
||||
//[assembly: AssemblyVersion("3.0.5464.40000")]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue