mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-11-03 19:17:24 -05:00 
			
		
		
		
	live tv stream adjustments, add additional dlna params
This commit is contained in:
		
							parent
							
								
									a5b807e433
								
							
						
					
					
						commit
						c4f587dd94
					
				@ -155,7 +155,7 @@ namespace MediaBrowser.Api
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            var games = items.OfType<Game>().ToList();
 | 
					            var games = items.OfType<Game>().ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            summary.ClientInstalledGameCount = games.Count(i => !i.IsPlaceHolder);
 | 
					            summary.ClientInstalledGameCount = games.Count(i => i.IsPlaceHolder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            summary.GameCount = games.Count;
 | 
					            summary.GameCount = games.Count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -174,7 +174,7 @@ namespace MediaBrowser.Api.Movies
 | 
				
			|||||||
                .OrderBy(i => Guid.NewGuid())
 | 
					                .OrderBy(i => Guid.NewGuid())
 | 
				
			||||||
                .ToList();
 | 
					                .ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var similarToRecentlyPlayed = GetSimilarTo(user, allMovies, recentlyPlayedMovies.Take(10).OrderBy(i => Guid.NewGuid()), itemLimit, fields, RecommendationType.SimilarToRecentlyPlayed).GetEnumerator();
 | 
					            var similarToRecentlyPlayed = GetSimilarTo(user, allMovies, recentlyPlayedMovies.Take(7).OrderBy(i => Guid.NewGuid()), itemLimit, fields, RecommendationType.SimilarToRecentlyPlayed).GetEnumerator();
 | 
				
			||||||
            var similarToLiked = GetSimilarTo(user, allMovies, likedMovies, itemLimit, fields, RecommendationType.SimilarToLikedItem).GetEnumerator();
 | 
					            var similarToLiked = GetSimilarTo(user, allMovies, likedMovies, itemLimit, fields, RecommendationType.SimilarToLikedItem).GetEnumerator();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var hasDirectorFromRecentlyPlayed = GetWithDirector(user, allMovies, recentDirectors, itemLimit, fields, RecommendationType.HasDirectorFromRecentlyPlayed).GetEnumerator();
 | 
					            var hasDirectorFromRecentlyPlayed = GetWithDirector(user, allMovies, recentDirectors, itemLimit, fields, RecommendationType.HasDirectorFromRecentlyPlayed).GetEnumerator();
 | 
				
			||||||
 | 
				
			|||||||
@ -279,8 +279,19 @@ namespace MediaBrowser.Api.Playback
 | 
				
			|||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <returns>System.Int32.</returns>
 | 
					        /// <returns>System.Int32.</returns>
 | 
				
			||||||
        /// <exception cref="System.Exception">Unrecognized MediaEncodingQuality value.</exception>
 | 
					        /// <exception cref="System.Exception">Unrecognized MediaEncodingQuality value.</exception>
 | 
				
			||||||
        protected int GetNumberOfThreads(bool isWebm)
 | 
					        protected int GetNumberOfThreads(StreamState state, bool isWebm)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            // Use more when this is true. -re will keep cpu usage under control
 | 
				
			||||||
 | 
					            if (state.ReadInputAtNativeFramerate)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (isWebm)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return Math.Max(Environment.ProcessorCount - 1, 1);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Webm: http://www.webmproject.org/docs/encoder-parameters/
 | 
					            // Webm: http://www.webmproject.org/docs/encoder-parameters/
 | 
				
			||||||
            // The decoder will usually automatically use an appropriate number of threads according to how many cores are available but it can only use multiple threads 
 | 
					            // The decoder will usually automatically use an appropriate number of threads according to how many cores are available but it can only use multiple threads 
 | 
				
			||||||
            // for the coefficient data if the encoder selected --token-parts > 0 at encode time.
 | 
					            // for the coefficient data if the encoder selected --token-parts > 0 at encode time.
 | 
				
			||||||
@ -1191,66 +1202,74 @@ namespace MediaBrowser.Api.Playback
 | 
				
			|||||||
                    request.DeviceId = val;
 | 
					                    request.DeviceId = val;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (i == 1)
 | 
					                else if (i == 1)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    request.Static = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else if (i == 2)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (videoRequest != null)
 | 
					                    if (videoRequest != null)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        videoRequest.VideoCodec = (VideoCodecs)Enum.Parse(typeof(VideoCodecs), val, true);
 | 
					                        videoRequest.VideoCodec = (VideoCodecs)Enum.Parse(typeof(VideoCodecs), val, true);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (i == 2)
 | 
					                else if (i == 3)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    request.AudioCodec = (AudioCodecs)Enum.Parse(typeof(AudioCodecs), val, true);
 | 
					                    request.AudioCodec = (AudioCodecs)Enum.Parse(typeof(AudioCodecs), val, true);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (i == 3)
 | 
					                else if (i == 4)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (videoRequest != null)
 | 
					                    if (videoRequest != null)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        videoRequest.AudioStreamIndex = int.Parse(val, UsCulture);
 | 
					                        videoRequest.AudioStreamIndex = int.Parse(val, UsCulture);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (i == 4)
 | 
					                else if (i == 5)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (videoRequest != null)
 | 
					                    if (videoRequest != null)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        videoRequest.SubtitleStreamIndex = int.Parse(val, UsCulture);
 | 
					                        videoRequest.SubtitleStreamIndex = int.Parse(val, UsCulture);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (i == 5)
 | 
					                else if (i == 6)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (videoRequest != null)
 | 
					                    if (videoRequest != null)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        videoRequest.VideoBitRate = int.Parse(val, UsCulture);
 | 
					                        videoRequest.VideoBitRate = int.Parse(val, UsCulture);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (i == 6)
 | 
					                else if (i == 7)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    request.AudioBitRate = int.Parse(val, UsCulture);
 | 
					                    request.AudioBitRate = int.Parse(val, UsCulture);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (i == 7)
 | 
					                else if (i == 8)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    request.AudioChannels = int.Parse(val, UsCulture);
 | 
					                    request.AudioChannels = int.Parse(val, UsCulture);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (i == 8)
 | 
					                else if (i == 9)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (videoRequest != null)
 | 
					                    if (videoRequest != null)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        request.StartTimeTicks = long.Parse(val, UsCulture);
 | 
					                        request.StartTimeTicks = long.Parse(val, UsCulture);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (i == 9)
 | 
					                else if (i == 10)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (videoRequest != null)
 | 
					                    if (videoRequest != null)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        videoRequest.Profile = val;
 | 
					                        videoRequest.Profile = val;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (i == 10)
 | 
					                else if (i == 11)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (videoRequest != null)
 | 
					                    if (videoRequest != null)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        videoRequest.Level = val;
 | 
					                        videoRequest.Level = val;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                else if (i == 12)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    request.ForcedMimeType = val;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1334,6 +1353,7 @@ namespace MediaBrowser.Api.Playback
 | 
				
			|||||||
                    await Task.Delay(1000, cancellationToken).ConfigureAwait(false);
 | 
					                    await Task.Delay(1000, cancellationToken).ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                state.ReadInputAtNativeFramerate = recording.RecordingInfo.Status == RecordingStatus.InProgress;
 | 
				
			||||||
                state.AudioSync = "1000";
 | 
					                state.AudioSync = "1000";
 | 
				
			||||||
                state.DeInterlace = true;
 | 
					                state.DeInterlace = true;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -1420,8 +1440,8 @@ namespace MediaBrowser.Api.Playback
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            state.HasMediaStreams = mediaStreams.Count > 0;
 | 
					            state.HasMediaStreams = mediaStreams.Count > 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            state.SegmentLength = state.ReadInputAtNativeFramerate ? 3 : 10;
 | 
					            state.SegmentLength = state.ReadInputAtNativeFramerate ? 5 : 10;
 | 
				
			||||||
            state.HlsListSize = state.ReadInputAtNativeFramerate ? 20 : 1440;
 | 
					            state.HlsListSize = state.ReadInputAtNativeFramerate ? 100 : 1440;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return state;
 | 
					            return state;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -278,7 +278,7 @@ namespace MediaBrowser.Api.Playback.Hls
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            var itsOffset = itsOffsetMs == 0 ? string.Empty : string.Format("-itsoffset {0} ", TimeSpan.FromMilliseconds(itsOffsetMs).TotalSeconds);
 | 
					            var itsOffset = itsOffsetMs == 0 ? string.Empty : string.Format("-itsoffset {0} ", TimeSpan.FromMilliseconds(itsOffsetMs).TotalSeconds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var threads = GetNumberOfThreads(false);
 | 
					            var threads = GetNumberOfThreads(state, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var inputModifier = GetInputModifier(state);
 | 
					            var inputModifier = GetInputModifier(state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -102,7 +102,7 @@ namespace MediaBrowser.Api.Playback.Progressive
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            const string vn = " -vn";
 | 
					            const string vn = " -vn";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var threads = GetNumberOfThreads(false);
 | 
					            var threads = GetNumberOfThreads(state, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var inputModifier = GetInputModifier(state);
 | 
					            var inputModifier = GetInputModifier(state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -214,12 +214,16 @@ namespace MediaBrowser.Api.Playback.Progressive
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if (request.Static)
 | 
					            if (request.Static)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return ResultFactory.GetStaticFileResult(Request, state.MediaPath, FileShare.Read, responseHeaders, isHeadRequest);
 | 
					                var contentType = state.GetMimeType(state.MediaPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return ResultFactory.GetStaticFileResult(Request, state.MediaPath, contentType, FileShare.Read, responseHeaders, isHeadRequest);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (outputPathExists && !ApiEntryPoint.Instance.HasActiveTranscodingJob(outputPath, TranscodingJobType.Progressive))
 | 
					            if (outputPathExists && !ApiEntryPoint.Instance.HasActiveTranscodingJob(outputPath, TranscodingJobType.Progressive))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return ResultFactory.GetStaticFileResult(Request, outputPath, FileShare.Read, responseHeaders, isHeadRequest);
 | 
					                var contentType = state.GetMimeType(outputPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return ResultFactory.GetStaticFileResult(Request, outputPath, contentType, FileShare.Read, responseHeaders, isHeadRequest);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return GetStreamResult(state, responseHeaders, isHeadRequest).Result;
 | 
					            return GetStreamResult(state, responseHeaders, isHeadRequest).Result;
 | 
				
			||||||
@ -287,7 +291,7 @@ namespace MediaBrowser.Api.Playback.Progressive
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            responseHeaders["Accept-Ranges"] = "none";
 | 
					            responseHeaders["Accept-Ranges"] = "none";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var contentType = MimeTypes.GetMimeType(outputPath);
 | 
					            var contentType = state.GetMimeType(outputPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Headers only
 | 
					            // Headers only
 | 
				
			||||||
            if (isHeadRequest)
 | 
					            if (isHeadRequest)
 | 
				
			||||||
 | 
				
			|||||||
@ -102,7 +102,7 @@ namespace MediaBrowser.Api.Playback.Progressive
 | 
				
			|||||||
                format = " -f mp4 -movflags frag_keyframe+empty_moov";
 | 
					                format = " -f mp4 -movflags frag_keyframe+empty_moov";
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var threads = GetNumberOfThreads(string.Equals(videoCodec, "libvpx", StringComparison.OrdinalIgnoreCase));
 | 
					            var threads = GetNumberOfThreads(state, string.Equals(videoCodec, "libvpx", StringComparison.OrdinalIgnoreCase));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var inputModifier = GetInputModifier(state);
 | 
					            var inputModifier = GetInputModifier(state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -66,6 +66,8 @@ namespace MediaBrowser.Api.Playback
 | 
				
			|||||||
        public bool ThrowDebugError { get; set; }
 | 
					        public bool ThrowDebugError { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public string Params { get; set; }
 | 
					        public string Params { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string ForcedMimeType { get; set; }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public class VideoStreamRequest : StreamRequest
 | 
					    public class VideoStreamRequest : StreamRequest
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,5 @@
 | 
				
			|||||||
using MediaBrowser.Model.Entities;
 | 
					using MediaBrowser.Common.Net;
 | 
				
			||||||
 | 
					using MediaBrowser.Model.Entities;
 | 
				
			||||||
using MediaBrowser.Model.IO;
 | 
					using MediaBrowser.Model.IO;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.IO;
 | 
					using System.IO;
 | 
				
			||||||
@ -72,5 +73,20 @@ namespace MediaBrowser.Api.Playback
 | 
				
			|||||||
        public string InputVideoCodec { get; set; }
 | 
					        public string InputVideoCodec { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public string InputAudioCodec { get; set; }
 | 
					        public string InputAudioCodec { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string GetMimeType(string outputPath)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (!string.IsNullOrWhiteSpace(Request.ForcedMimeType))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (VideoRequest == null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return "audio/" + Request.ForcedMimeType;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return "video/" + Request.ForcedMimeType;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return MimeTypes.GetMimeType(outputPath);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1184,7 +1184,7 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
            return GetImageInfo(type, imageIndex) != null;
 | 
					            return GetImageInfo(type, imageIndex) != null;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public void SetImagePath(ImageType type, int index, FileInfo file)
 | 
					        public void SetImagePath(ImageType type, int index, FileSystemInfo file)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (type == ImageType.Chapter)
 | 
					            if (type == ImageType.Chapter)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@ -1339,7 +1339,7 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
        /// <param name="images">The images.</param>
 | 
					        /// <param name="images">The images.</param>
 | 
				
			||||||
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
 | 
					        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
 | 
				
			||||||
        /// <exception cref="System.ArgumentException">Cannot call AddImages with chapter images</exception>
 | 
					        /// <exception cref="System.ArgumentException">Cannot call AddImages with chapter images</exception>
 | 
				
			||||||
        public bool AddImages(ImageType imageType, IEnumerable<FileInfo> images)
 | 
					        public bool AddImages(ImageType imageType, IEnumerable<FileSystemInfo> images)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (imageType == ImageType.Chapter)
 | 
					            if (imageType == ImageType.Chapter)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 | 
				
			|||||||
@ -62,7 +62,7 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
        /// <param name="type">The type.</param>
 | 
					        /// <param name="type">The type.</param>
 | 
				
			||||||
        /// <param name="index">The index.</param>
 | 
					        /// <param name="index">The index.</param>
 | 
				
			||||||
        /// <param name="file">The file.</param>
 | 
					        /// <param name="file">The file.</param>
 | 
				
			||||||
        void SetImagePath(ImageType type, int index, FileInfo file);
 | 
					        void SetImagePath(ImageType type, int index, FileSystemInfo file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Determines whether the specified type has image.
 | 
					        /// Determines whether the specified type has image.
 | 
				
			||||||
@ -129,7 +129,7 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
        /// <param name="imageType">Type of the image.</param>
 | 
					        /// <param name="imageType">Type of the image.</param>
 | 
				
			||||||
        /// <param name="images">The images.</param>
 | 
					        /// <param name="images">The images.</param>
 | 
				
			||||||
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
 | 
					        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
 | 
				
			||||||
        bool AddImages(ImageType imageType, IEnumerable<FileInfo> images);
 | 
					        bool AddImages(ImageType imageType, IEnumerable<FileSystemInfo> images);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Determines whether [is save local metadata enabled].
 | 
					        /// Determines whether [is save local metadata enabled].
 | 
				
			||||||
@ -180,7 +180,7 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
        /// <param name="item">The item.</param>
 | 
					        /// <param name="item">The item.</param>
 | 
				
			||||||
        /// <param name="imageType">Type of the image.</param>
 | 
					        /// <param name="imageType">Type of the image.</param>
 | 
				
			||||||
        /// <param name="file">The file.</param>
 | 
					        /// <param name="file">The file.</param>
 | 
				
			||||||
        public static void SetImagePath(this IHasImages item, ImageType imageType, FileInfo file)
 | 
					        public static void SetImagePath(this IHasImages item, ImageType imageType, FileSystemInfo file)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            item.SetImagePath(imageType, 0, file);
 | 
					            item.SetImagePath(imageType, 0, file);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -27,7 +27,7 @@ namespace MediaBrowser.Controller.Library
 | 
				
			|||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// A season folder must contain one of these somewhere in the name
 | 
					        /// A season folder must contain one of these somewhere in the name
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        private static readonly string[] SeasonFolderNames = new[]
 | 
					        private static readonly string[] SeasonFolderNames =
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "season",
 | 
					            "season",
 | 
				
			||||||
            "sæson",
 | 
					            "sæson",
 | 
				
			||||||
@ -43,7 +43,7 @@ namespace MediaBrowser.Controller.Library
 | 
				
			|||||||
        /// match movie titles like "2001 A Space..."
 | 
					        /// match movie titles like "2001 A Space..."
 | 
				
			||||||
        /// Currently we limit the numbers here to 2 digits to try and avoid this
 | 
					        /// Currently we limit the numbers here to 2 digits to try and avoid this
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        private static readonly Regex[] EpisodeExpressions = new[]
 | 
					        private static readonly Regex[] EpisodeExpressions =
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            new Regex(
 | 
					            new Regex(
 | 
				
			||||||
                @".*(\\|\/)[sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3})[^\\\/]*$",
 | 
					                @".*(\\|\/)[sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3})[^\\\/]*$",
 | 
				
			||||||
@ -58,7 +58,7 @@ namespace MediaBrowser.Controller.Library
 | 
				
			|||||||
                @".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>\d{1,4})[xX\.]?[eE](?<epnumber>\d{1,3})[^\\\/]*$",
 | 
					                @".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>\d{1,4})[xX\.]?[eE](?<epnumber>\d{1,3})[^\\\/]*$",
 | 
				
			||||||
                RegexOptions.Compiled)
 | 
					                RegexOptions.Compiled)
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        private static readonly Regex[] MultipleEpisodeExpressions = new[]
 | 
					        private static readonly Regex[] MultipleEpisodeExpressions =
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            new Regex(
 | 
					            new Regex(
 | 
				
			||||||
                @".*(\\|\/)[sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3})((-| - )\d{1,4}[eExX](?<endingepnumber>\d{1,3}))+[^\\\/]*$",
 | 
					                @".*(\\|\/)[sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3})((-| - )\d{1,4}[eExX](?<endingepnumber>\d{1,3}))+[^\\\/]*$",
 | 
				
			||||||
@ -95,7 +95,7 @@ namespace MediaBrowser.Controller.Library
 | 
				
			|||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// To avoid the following matching movies they are only valid when contained in a folder which has been matched as a being season
 | 
					        /// To avoid the following matching movies they are only valid when contained in a folder which has been matched as a being season
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        private static readonly Regex[] EpisodeExpressionsInASeasonFolder = new[]
 | 
					        private static readonly Regex[] EpisodeExpressionsInASeasonFolder =
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            new Regex(
 | 
					            new Regex(
 | 
				
			||||||
                @".*(\\|\/)(?<epnumber>\d{1,2})\s?-\s?[^\\\/]*$",
 | 
					                @".*(\\|\/)(?<epnumber>\d{1,2})\s?-\s?[^\\\/]*$",
 | 
				
			||||||
@ -151,8 +151,8 @@ namespace MediaBrowser.Controller.Library
 | 
				
			|||||||
        /// <returns>System.Nullable{System.Int32}.</returns>
 | 
					        /// <returns>System.Nullable{System.Int32}.</returns>
 | 
				
			||||||
        private static int? GetSeasonNumberFromPathSubstring(string path)
 | 
					        private static int? GetSeasonNumberFromPathSubstring(string path)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            int numericStart = -1;
 | 
					            var numericStart = -1;
 | 
				
			||||||
            int length = 0;
 | 
					            var length = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Find out where the numbers start, and then keep going until they end
 | 
					            // Find out where the numbers start, and then keep going until they end
 | 
				
			||||||
            for (var i = 0; i < path.Length; i++)
 | 
					            for (var i = 0; i < path.Length; i++)
 | 
				
			||||||
 | 
				
			|||||||
@ -95,6 +95,18 @@ namespace MediaBrowser.Controller.Net
 | 
				
			|||||||
        /// <returns>System.Object.</returns>
 | 
					        /// <returns>System.Object.</returns>
 | 
				
			||||||
        object GetStaticFileResult(IRequest requestContext, string path, FileShare fileShare = FileShare.Read, IDictionary<string, string> responseHeaders = null, bool isHeadRequest = false);
 | 
					        object GetStaticFileResult(IRequest requestContext, string path, FileShare fileShare = FileShare.Read, IDictionary<string, string> responseHeaders = null, bool isHeadRequest = false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Gets the static file result.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="requestContext">The request context.</param>
 | 
				
			||||||
 | 
					        /// <param name="path">The path.</param>
 | 
				
			||||||
 | 
					        /// <param name="contentType">Type of the content.</param>
 | 
				
			||||||
 | 
					        /// <param name="fileShare">The file share.</param>
 | 
				
			||||||
 | 
					        /// <param name="responseHeaders">The response headers.</param>
 | 
				
			||||||
 | 
					        /// <param name="isHeadRequest">if set to <c>true</c> [is head request].</param>
 | 
				
			||||||
 | 
					        /// <returns>System.Object.</returns>
 | 
				
			||||||
 | 
					        object GetStaticFileResult(IRequest requestContext, string path, string contentType, FileShare fileShare = FileShare.Read, IDictionary<string, string> responseHeaders = null, bool isHeadRequest = false);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Gets the optimized serialized result using cache.
 | 
					        /// Gets the optimized serialized result using cache.
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
using System.Collections.Concurrent;
 | 
					using MediaBrowser.Model.Logging;
 | 
				
			||||||
using MediaBrowser.Model.Logging;
 | 
					 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Concurrent;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.IO;
 | 
					using System.IO;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
@ -10,10 +10,8 @@ namespace MediaBrowser.Controller.Providers
 | 
				
			|||||||
    public interface IDirectoryService
 | 
					    public interface IDirectoryService
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        List<FileSystemInfo> GetFileSystemEntries(string path);
 | 
					        List<FileSystemInfo> GetFileSystemEntries(string path);
 | 
				
			||||||
        IEnumerable<FileInfo> GetFiles(string path);
 | 
					        IEnumerable<FileSystemInfo> GetFiles(string path);
 | 
				
			||||||
        IEnumerable<DirectoryInfo> GetDirectories(string path);
 | 
					        FileSystemInfo GetFile(string path);
 | 
				
			||||||
        FileInfo GetFile(string path);
 | 
					 | 
				
			||||||
        DirectoryInfo GetDirectory(string path);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public class DirectoryService : IDirectoryService
 | 
					    public class DirectoryService : IDirectoryService
 | 
				
			||||||
@ -50,31 +48,17 @@ namespace MediaBrowser.Controller.Providers
 | 
				
			|||||||
            return entries;
 | 
					            return entries;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public IEnumerable<FileInfo> GetFiles(string path)
 | 
					        public IEnumerable<FileSystemInfo> GetFiles(string path)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return GetFileSystemEntries(path).OfType<FileInfo>();
 | 
					            return GetFileSystemEntries(path).Where(i => (i.Attributes & FileAttributes.Directory) != FileAttributes.Directory);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public IEnumerable<DirectoryInfo> GetDirectories(string path)
 | 
					        public FileSystemInfo GetFile(string path)
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return GetFileSystemEntries(path).OfType<DirectoryInfo>();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public FileInfo GetFile(string path)
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var directory = Path.GetDirectoryName(path);
 | 
					            var directory = Path.GetDirectoryName(path);
 | 
				
			||||||
            var filename = Path.GetFileName(path);
 | 
					            var filename = Path.GetFileName(path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return GetFiles(directory).FirstOrDefault(i => string.Equals(i.Name, filename, StringComparison.OrdinalIgnoreCase));
 | 
					            return GetFiles(directory).FirstOrDefault(i => string.Equals(i.Name, filename, StringComparison.OrdinalIgnoreCase));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public DirectoryInfo GetDirectory(string path)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            var directory = Path.GetDirectoryName(path);
 | 
					 | 
				
			||||||
            var name = Path.GetFileName(path);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return GetDirectories(directory).FirstOrDefault(i => string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -23,7 +23,7 @@ namespace MediaBrowser.Controller.Providers
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public class LocalImageInfo
 | 
					    public class LocalImageInfo
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public FileInfo FileInfo { get; set; }
 | 
					        public FileSystemInfo FileInfo { get; set; }
 | 
				
			||||||
        public ImageType Type { get; set; }
 | 
					        public ImageType Type { get; set; }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -23,7 +23,7 @@ namespace MediaBrowser.Providers.AdultVideos
 | 
				
			|||||||
            new MovieXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
 | 
					            new MovieXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
					        protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return MovieXmlProvider.GetXmlFileInfo(info, FileSystem);
 | 
					            return MovieXmlProvider.GetXmlFileInfo(info, FileSystem);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -201,7 +201,7 @@ namespace MediaBrowser.Providers.All
 | 
				
			|||||||
            PopulateBackdrops(images, files, imagePrefix, "background", "background-", ImageType.Backdrop);
 | 
					            PopulateBackdrops(images, files, imagePrefix, "background", "background-", ImageType.Backdrop);
 | 
				
			||||||
            PopulateBackdrops(images, files, imagePrefix, "art", "art-", ImageType.Backdrop);
 | 
					            PopulateBackdrops(images, files, imagePrefix, "art", "art-", ImageType.Backdrop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var extraFanartFolder = files.OfType<DirectoryInfo>()
 | 
					            var extraFanartFolder = files
 | 
				
			||||||
                .FirstOrDefault(i => string.Equals(i.Name, "extrafanart", StringComparison.OrdinalIgnoreCase));
 | 
					                .FirstOrDefault(i => string.Equals(i.Name, "extrafanart", StringComparison.OrdinalIgnoreCase));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (extraFanartFolder != null)
 | 
					            if (extraFanartFolder != null)
 | 
				
			||||||
 | 
				
			|||||||
@ -59,7 +59,7 @@ namespace MediaBrowser.Providers
 | 
				
			|||||||
            FileSystem = fileSystem;
 | 
					            FileSystem = fileSystem;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected abstract FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService);
 | 
					        protected abstract FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
 | 
					        public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
				
			|||||||
@ -25,7 +25,7 @@ namespace MediaBrowser.Providers.BoxSets
 | 
				
			|||||||
            new BoxSetXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
 | 
					            new BoxSetXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
					        protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return directoryService.GetFile(Path.Combine(info.Path, "collection.xml"));
 | 
					            return directoryService.GetFile(Path.Combine(info.Path, "collection.xml"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -25,7 +25,7 @@ namespace MediaBrowser.Providers.Folders
 | 
				
			|||||||
            new BaseItemXmlParser<Folder>(_logger).Fetch(result.Item, path, cancellationToken);
 | 
					            new BaseItemXmlParser<Folder>(_logger).Fetch(result.Item, path, cancellationToken);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
					        protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return new FileInfo(Path.Combine(info.Path, "folder.xml"));
 | 
					            return new FileInfo(Path.Combine(info.Path, "folder.xml"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Games
 | 
				
			|||||||
            new GameSystemXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
 | 
					            new GameSystemXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
					        protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return directoryService.GetFile(Path.Combine(info.Path, "gamesystem.xml"));
 | 
					            return directoryService.GetFile(Path.Combine(info.Path, "gamesystem.xml"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Games
 | 
				
			|||||||
            new GameXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
 | 
					            new GameXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
					        protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var fileInfo = FileSystem.GetFileSystemInfo(info.Path);
 | 
					            var fileInfo = FileSystem.GetFileSystemInfo(info.Path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.LiveTv
 | 
				
			|||||||
            new BaseItemXmlParser<LiveTvChannel>(_logger).Fetch(result.Item, path, cancellationToken);
 | 
					            new BaseItemXmlParser<LiveTvChannel>(_logger).Fetch(result.Item, path, cancellationToken);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
					        protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return directoryService.GetFile(Path.Combine(info.Path, "channel.xml"));
 | 
					            return directoryService.GetFile(Path.Combine(info.Path, "channel.xml"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -357,7 +357,7 @@ namespace MediaBrowser.Providers.MediaInfo
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public IEnumerable<FileInfo> GetSubtitleFiles(Video video, IDirectoryService directoryService)
 | 
					        public IEnumerable<FileSystemInfo> GetSubtitleFiles(Video video, IDirectoryService directoryService)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var containingPath = video.ContainingFolderPath;
 | 
					            var containingPath = video.ContainingFolderPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Movies
 | 
				
			|||||||
            new MovieXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
 | 
					            new MovieXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
					        protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return GetXmlFileInfo(info, FileSystem);
 | 
					            return GetXmlFileInfo(info, FileSystem);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Movies
 | 
				
			|||||||
            new MovieXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
 | 
					            new MovieXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
					        protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return MovieXmlProvider.GetXmlFileInfo(info, FileSystem);
 | 
					            return MovieXmlProvider.GetXmlFileInfo(info, FileSystem);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Music
 | 
				
			|||||||
            new BaseItemXmlParser<MusicAlbum>(_logger).Fetch(result.Item, path, cancellationToken);
 | 
					            new BaseItemXmlParser<MusicAlbum>(_logger).Fetch(result.Item, path, cancellationToken);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
					        protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return directoryService.GetFile(Path.Combine(info.Path, "album.xml"));
 | 
					            return directoryService.GetFile(Path.Combine(info.Path, "album.xml"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Music
 | 
				
			|||||||
            new BaseItemXmlParser<MusicArtist>(_logger).Fetch(result.Item, path, cancellationToken);
 | 
					            new BaseItemXmlParser<MusicArtist>(_logger).Fetch(result.Item, path, cancellationToken);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
					        protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return directoryService.GetFile(Path.Combine(info.Path, "artist.xml"));
 | 
					            return directoryService.GetFile(Path.Combine(info.Path, "artist.xml"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -24,7 +24,7 @@ namespace MediaBrowser.Providers.Music
 | 
				
			|||||||
            new MusicVideoXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
 | 
					            new MusicVideoXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
					        protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return MovieXmlProvider.GetXmlFileInfo(info, FileSystem);
 | 
					            return MovieXmlProvider.GetXmlFileInfo(info, FileSystem);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.People
 | 
				
			|||||||
            new BaseItemXmlParser<Person>(_logger).Fetch(result.Item, path, cancellationToken);
 | 
					            new BaseItemXmlParser<Person>(_logger).Fetch(result.Item, path, cancellationToken);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
					        protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return directoryService.GetFile(Path.Combine(info.Path, "person.xml"));
 | 
					            return directoryService.GetFile(Path.Combine(info.Path, "person.xml"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -27,7 +27,7 @@ namespace MediaBrowser.Providers.TV
 | 
				
			|||||||
            result.Images = images;
 | 
					            result.Images = images;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
					        protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var metadataPath = Path.GetDirectoryName(info.Path);
 | 
					            var metadataPath = Path.GetDirectoryName(info.Path);
 | 
				
			||||||
            metadataPath = Path.Combine(metadataPath, "metadata");
 | 
					            metadataPath = Path.Combine(metadataPath, "metadata");
 | 
				
			||||||
 | 
				
			|||||||
@ -25,7 +25,7 @@ namespace MediaBrowser.Providers.TV
 | 
				
			|||||||
            new BaseItemXmlParser<Season>(_logger).Fetch(result.Item, path, cancellationToken);
 | 
					            new BaseItemXmlParser<Season>(_logger).Fetch(result.Item, path, cancellationToken);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
					        protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return directoryService.GetFile(Path.Combine(info.Path, "season.xml"));
 | 
					            return directoryService.GetFile(Path.Combine(info.Path, "season.xml"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -25,7 +25,7 @@ namespace MediaBrowser.Providers.TV
 | 
				
			|||||||
            new SeriesXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
 | 
					            new SeriesXmlParser(_logger).Fetch(result.Item, path, cancellationToken);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override FileInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
					        protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return directoryService.GetFile(Path.Combine(info.Path, "series.xml"));
 | 
					            return directoryService.GetFile(Path.Combine(info.Path, "series.xml"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -173,14 +173,6 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if (!overwriteExisting)
 | 
					            if (!overwriteExisting)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (fileExists || otherDuplicatePaths.Count > 0)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    result.Status = FileSortingStatus.SkippedExisting;
 | 
					 | 
				
			||||||
                    result.StatusMessage = string.Empty;
 | 
					 | 
				
			||||||
                    result.DuplicatePaths = otherDuplicatePaths;
 | 
					 | 
				
			||||||
                    return;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (options.CopyOriginalFile && fileExists && IsSameEpisode(sourcePath, newPath))
 | 
					                if (options.CopyOriginalFile && fileExists && IsSameEpisode(sourcePath, newPath))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    _logger.Info("File {0} already copied to new path {1}, stopping organization", sourcePath, newPath);
 | 
					                    _logger.Info("File {0} already copied to new path {1}, stopping organization", sourcePath, newPath);
 | 
				
			||||||
@ -188,9 +180,15 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
 | 
				
			|||||||
                    result.StatusMessage = string.Empty;
 | 
					                    result.StatusMessage = string.Empty;
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                if (fileExists || otherDuplicatePaths.Count > 0)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    result.Status = FileSortingStatus.SkippedExisting;
 | 
				
			||||||
 | 
					                    result.StatusMessage = string.Empty;
 | 
				
			||||||
 | 
					                    result.DuplicatePaths = otherDuplicatePaths;
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					 | 
				
			||||||
   
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            PerformFileSorting(options, result);
 | 
					            PerformFileSorting(options, result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -306,6 +306,18 @@ namespace MediaBrowser.Server.Implementations.HttpServer
 | 
				
			|||||||
                throw new ArgumentNullException("path");
 | 
					                throw new ArgumentNullException("path");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return GetStaticFileResult(requestContext, path, MimeTypes.GetMimeType(path), fileShare, responseHeaders, isHeadRequest);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public object GetStaticFileResult(IRequest requestContext, string path, string contentType,
 | 
				
			||||||
 | 
					            FileShare fileShare = FileShare.Read, IDictionary<string, string> responseHeaders = null,
 | 
				
			||||||
 | 
					            bool isHeadRequest = false)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (string.IsNullOrEmpty(path))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new ArgumentNullException("path");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (fileShare != FileShare.Read && fileShare != FileShare.ReadWrite)
 | 
					            if (fileShare != FileShare.Read && fileShare != FileShare.ReadWrite)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                throw new ArgumentException("FileShare must be either Read or ReadWrite");
 | 
					                throw new ArgumentException("FileShare must be either Read or ReadWrite");
 | 
				
			||||||
@ -315,7 +327,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            var cacheKey = path + dateModified.Ticks;
 | 
					            var cacheKey = path + dateModified.Ticks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return GetStaticResult(requestContext, cacheKey.GetMD5(), dateModified, null, MimeTypes.GetMimeType(path), () => Task.FromResult(GetFileStream(path, fileShare)), responseHeaders, isHeadRequest);
 | 
					            return GetStaticResult(requestContext, cacheKey.GetMD5(), dateModified, null, contentType, () => Task.FromResult(GetFileStream(path, fileShare)), responseHeaders, isHeadRequest);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
 | 
				
			|||||||
@ -56,21 +56,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    return null;
 | 
					                    return null;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					 | 
				
			||||||
                // If the parent is not a boxset, the only other allowed parent type is Folder		
 | 
					 | 
				
			||||||
                if (!(args.Parent is BoxSet))
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    if (args.Parent.GetType() != typeof(Folder))
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        return null;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Since the looping is expensive, this is an optimization to help us avoid it
 | 
					 | 
				
			||||||
            if (args.Path.IndexOf("[tvdbid", StringComparison.OrdinalIgnoreCase) != -1)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                return null;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var isDirectory = args.IsDirectory;
 | 
					            var isDirectory = args.IsDirectory;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user