mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-07-09 03:04:24 -04:00
commit
3e8303bd4b
@ -192,13 +192,13 @@ namespace MediaBrowser.Api
|
|||||||
|
|
||||||
_activeTranscodingJobs.Add(job);
|
_activeTranscodingJobs.Add(job);
|
||||||
|
|
||||||
ReportTranscodingProgress(job, state, null, null, null, null);
|
ReportTranscodingProgress(job, state, null, null, null, null, null);
|
||||||
|
|
||||||
return job;
|
return job;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReportTranscodingProgress(TranscodingJob job, StreamState state, TimeSpan? transcodingPosition, float? framerate, double? percentComplete, long? bytesTranscoded)
|
public void ReportTranscodingProgress(TranscodingJob job, StreamState state, TimeSpan? transcodingPosition, float? framerate, double? percentComplete, long? bytesTranscoded, int? bitRate)
|
||||||
{
|
{
|
||||||
var ticks = transcodingPosition.HasValue ? transcodingPosition.Value.Ticks : (long?)null;
|
var ticks = transcodingPosition.HasValue ? transcodingPosition.Value.Ticks : (long?)null;
|
||||||
|
|
||||||
@ -208,6 +208,7 @@ namespace MediaBrowser.Api
|
|||||||
job.CompletionPercentage = percentComplete;
|
job.CompletionPercentage = percentComplete;
|
||||||
job.TranscodingPositionTicks = ticks;
|
job.TranscodingPositionTicks = ticks;
|
||||||
job.BytesTranscoded = bytesTranscoded;
|
job.BytesTranscoded = bytesTranscoded;
|
||||||
|
job.BitRate = bitRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
var deviceId = state.Request.DeviceId;
|
var deviceId = state.Request.DeviceId;
|
||||||
@ -219,7 +220,7 @@ namespace MediaBrowser.Api
|
|||||||
|
|
||||||
_sessionManager.ReportTranscodingInfo(deviceId, new TranscodingInfo
|
_sessionManager.ReportTranscodingInfo(deviceId, new TranscodingInfo
|
||||||
{
|
{
|
||||||
Bitrate = state.TotalOutputBitrate,
|
Bitrate = bitRate ?? state.TotalOutputBitrate,
|
||||||
AudioCodec = audioCodec,
|
AudioCodec = audioCodec,
|
||||||
VideoCodec = videoCodec,
|
VideoCodec = videoCodec,
|
||||||
Container = state.OutputContainer,
|
Container = state.OutputContainer,
|
||||||
@ -694,6 +695,7 @@ namespace MediaBrowser.Api
|
|||||||
|
|
||||||
public long? BytesDownloaded { get; set; }
|
public long? BytesDownloaded { get; set; }
|
||||||
public long? BytesTranscoded { get; set; }
|
public long? BytesTranscoded { get; set; }
|
||||||
|
public int? BitRate { get; set; }
|
||||||
|
|
||||||
public long? TranscodingPositionTicks { get; set; }
|
public long? TranscodingPositionTicks { get; set; }
|
||||||
public long? DownloadPositionTicks { get; set; }
|
public long? DownloadPositionTicks { get; set; }
|
||||||
|
@ -22,6 +22,8 @@ using System.Text;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using CommonIO;
|
using CommonIO;
|
||||||
|
using MediaBrowser.Common.Net;
|
||||||
|
using MediaBrowser.Controller;
|
||||||
|
|
||||||
namespace MediaBrowser.Api.Playback
|
namespace MediaBrowser.Api.Playback
|
||||||
{
|
{
|
||||||
@ -69,6 +71,9 @@ namespace MediaBrowser.Api.Playback
|
|||||||
protected IZipClient ZipClient { get; private set; }
|
protected IZipClient ZipClient { get; private set; }
|
||||||
protected IJsonSerializer JsonSerializer { get; private set; }
|
protected IJsonSerializer JsonSerializer { get; private set; }
|
||||||
|
|
||||||
|
public static IServerApplicationHost AppHost;
|
||||||
|
public static IHttpClient HttpClient;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="BaseStreamingService" /> class.
|
/// Initializes a new instance of the <see cref="BaseStreamingService" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -1112,6 +1117,7 @@ namespace MediaBrowser.Api.Playback
|
|||||||
}
|
}
|
||||||
|
|
||||||
StartThrottler(state, transcodingJob);
|
StartThrottler(state, transcodingJob);
|
||||||
|
ReportUsage(state);
|
||||||
|
|
||||||
return transcodingJob;
|
return transcodingJob;
|
||||||
}
|
}
|
||||||
@ -1172,6 +1178,7 @@ namespace MediaBrowser.Api.Playback
|
|||||||
double? percent = null;
|
double? percent = null;
|
||||||
TimeSpan? transcodingPosition = null;
|
TimeSpan? transcodingPosition = null;
|
||||||
long? bytesTranscoded = null;
|
long? bytesTranscoded = null;
|
||||||
|
int? bitRate = null;
|
||||||
|
|
||||||
var parts = line.Split(' ');
|
var parts = line.Split(' ');
|
||||||
|
|
||||||
@ -1235,11 +1242,32 @@ namespace MediaBrowser.Api.Playback
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (part.StartsWith("bitrate=", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
var rate = part.Split(new[] { '=' }, 2).Last();
|
||||||
|
|
||||||
|
int? scale = null;
|
||||||
|
if (rate.IndexOf("kbits/s", StringComparison.OrdinalIgnoreCase) != -1)
|
||||||
|
{
|
||||||
|
scale = 1024;
|
||||||
|
rate = rate.Replace("kbits/s", string.Empty, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scale.HasValue)
|
||||||
|
{
|
||||||
|
float val;
|
||||||
|
|
||||||
|
if (float.TryParse(rate, NumberStyles.Any, UsCulture, out val))
|
||||||
|
{
|
||||||
|
bitRate = (int)Math.Ceiling(val * scale.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (framerate.HasValue || percent.HasValue)
|
if (framerate.HasValue || percent.HasValue)
|
||||||
{
|
{
|
||||||
ApiEntryPoint.Instance.ReportTranscodingProgress(transcodingJob, state, transcodingPosition, framerate, percent, bytesTranscoded);
|
ApiEntryPoint.Instance.ReportTranscodingProgress(transcodingJob, state, transcodingPosition, framerate, percent, bytesTranscoded, bitRate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2197,6 +2225,121 @@ namespace MediaBrowser.Api.Playback
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void ReportUsage(StreamState state)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await ReportUsageInternal(state).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task ReportUsageInternal(StreamState state)
|
||||||
|
{
|
||||||
|
if (!ServerConfigurationManager.Configuration.EnableAnonymousUsageReporting)
|
||||||
|
{
|
||||||
|
return Task.FromResult(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.Equals(MediaEncoder.EncoderLocationType, "Default", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return Task.FromResult(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
var dict = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
var outputAudio = GetAudioEncoder(state);
|
||||||
|
if (!string.IsNullOrWhiteSpace(outputAudio))
|
||||||
|
{
|
||||||
|
dict["outputAudio"] = outputAudio;
|
||||||
|
}
|
||||||
|
|
||||||
|
var outputVideo = GetVideoEncoder(state);
|
||||||
|
if (!string.IsNullOrWhiteSpace(outputVideo))
|
||||||
|
{
|
||||||
|
dict["outputVideo"] = outputVideo;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ServerConfigurationManager.Configuration.CodecsUsed.Contains(outputAudio ?? string.Empty, StringComparer.OrdinalIgnoreCase) &&
|
||||||
|
ServerConfigurationManager.Configuration.CodecsUsed.Contains(outputVideo ?? string.Empty, StringComparer.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return Task.FromResult(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
dict["id"] = AppHost.SystemId;
|
||||||
|
dict["type"] = state.VideoRequest == null ? "Audio" : "Video";
|
||||||
|
|
||||||
|
var audioStream = state.AudioStream;
|
||||||
|
if (audioStream != null && !string.IsNullOrWhiteSpace(audioStream.Codec))
|
||||||
|
{
|
||||||
|
dict["inputAudio"] = audioStream.Codec;
|
||||||
|
}
|
||||||
|
|
||||||
|
var videoStream = state.VideoStream;
|
||||||
|
if (videoStream != null && !string.IsNullOrWhiteSpace(videoStream.Codec))
|
||||||
|
{
|
||||||
|
dict["inputVideo"] = videoStream.Codec;
|
||||||
|
}
|
||||||
|
|
||||||
|
var cert = GetType().Assembly.GetModules().First().GetSignerCertificate();
|
||||||
|
if (cert != null)
|
||||||
|
{
|
||||||
|
dict["assemblySig"] = cert.GetCertHashString();
|
||||||
|
dict["certSubject"] = cert.Subject ?? string.Empty;
|
||||||
|
dict["certIssuer"] = cert.Issuer ?? string.Empty;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Task.FromResult(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.SupportedAudioCodecs.Count > 0)
|
||||||
|
{
|
||||||
|
dict["supportedAudioCodecs"] = string.Join(",", state.SupportedAudioCodecs.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
var auth = AuthorizationContext.GetAuthorizationInfo(Request);
|
||||||
|
|
||||||
|
dict["appName"] = auth.Client ?? string.Empty;
|
||||||
|
dict["appVersion"] = auth.Version ?? string.Empty;
|
||||||
|
dict["device"] = auth.Device ?? string.Empty;
|
||||||
|
dict["deviceId"] = auth.DeviceId ?? string.Empty;
|
||||||
|
dict["context"] = "streaming";
|
||||||
|
|
||||||
|
//Logger.Info(JsonSerializer.SerializeToString(dict));
|
||||||
|
if (!ServerConfigurationManager.Configuration.CodecsUsed.Contains(outputAudio ?? string.Empty, StringComparer.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
var list = ServerConfigurationManager.Configuration.CodecsUsed.ToList();
|
||||||
|
list.Add(outputAudio);
|
||||||
|
ServerConfigurationManager.Configuration.CodecsUsed = list.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ServerConfigurationManager.Configuration.CodecsUsed.Contains(outputVideo ?? string.Empty, StringComparer.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
var list = ServerConfigurationManager.Configuration.CodecsUsed.ToList();
|
||||||
|
list.Add(outputVideo);
|
||||||
|
ServerConfigurationManager.Configuration.CodecsUsed = list.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerConfigurationManager.SaveConfiguration();
|
||||||
|
|
||||||
|
//Logger.Info(JsonSerializer.SerializeToString(dict));
|
||||||
|
var options = new HttpRequestOptions()
|
||||||
|
{
|
||||||
|
Url = "https://mb3admin.com/admin/service/transcoding/report",
|
||||||
|
CancellationToken = CancellationToken.None,
|
||||||
|
LogRequest = false,
|
||||||
|
LogErrors = false
|
||||||
|
};
|
||||||
|
options.RequestContent = JsonSerializer.SerializeToString(dict);
|
||||||
|
options.RequestContentType = "application/json";
|
||||||
|
|
||||||
|
return HttpClient.Post(options);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the dlna headers.
|
/// Adds the dlna headers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -171,8 +171,10 @@ namespace MediaBrowser.Controller.Persistence
|
|||||||
QueryResult<Tuple<BaseItem, ItemCounts>> GetAlbumArtists(InternalItemsQuery query);
|
QueryResult<Tuple<BaseItem, ItemCounts>> GetAlbumArtists(InternalItemsQuery query);
|
||||||
QueryResult<Tuple<BaseItem, ItemCounts>> GetAllArtists(InternalItemsQuery query);
|
QueryResult<Tuple<BaseItem, ItemCounts>> GetAllArtists(InternalItemsQuery query);
|
||||||
|
|
||||||
|
List<string> GetGameGenreNames();
|
||||||
|
List<string> GetMusicGenreNames();
|
||||||
List<string> GetStudioNames();
|
List<string> GetStudioNames();
|
||||||
|
List<string> GetGenreNames();
|
||||||
List<string> GetAllArtistNames();
|
List<string> GetAllArtistNames();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,14 +65,26 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
{
|
{
|
||||||
new DirectPlayProfile
|
new DirectPlayProfile
|
||||||
{
|
{
|
||||||
Container = "mp3,wma",
|
Container = "m4v,ts,mkv,avi,mpg,mpeg,mp4",
|
||||||
Type = DlnaProfileType.Audio
|
VideoCodec = "h264",
|
||||||
|
AudioCodec = "aac,mp3,ac3",
|
||||||
|
Type = DlnaProfileType.Video
|
||||||
},
|
},
|
||||||
|
|
||||||
new DirectPlayProfile
|
new DirectPlayProfile
|
||||||
{
|
{
|
||||||
Container = "avi,mp4",
|
Container = "mp3,wma,aac,wav",
|
||||||
Type = DlnaProfileType.Video
|
Type = DlnaProfileType.Audio
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ResponseProfiles = new[]
|
||||||
|
{
|
||||||
|
new ResponseProfile
|
||||||
|
{
|
||||||
|
Container = "m4v",
|
||||||
|
Type = DlnaProfileType.Video,
|
||||||
|
MimeType = "video/mp4"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,8 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
Type = DlnaProfileType.Audio
|
Type = DlnaProfileType.Audio
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ResponseProfiles = new ResponseProfile[] { };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,8 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ResponseProfiles = new ResponseProfile[] { };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,8 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
Type = DlnaProfileType.Audio
|
Type = DlnaProfileType.Audio
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ResponseProfiles = new ResponseProfile[] { };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,6 +198,8 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
Method = SubtitleDeliveryMethod.External
|
Method = SubtitleDeliveryMethod.External
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ResponseProfiles = new ResponseProfile[] { };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,8 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
Type = DlnaProfileType.Video
|
Type = DlnaProfileType.Video
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ResponseProfiles = new ResponseProfile[] { };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,8 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
Type = DlnaProfileType.Audio
|
Type = DlnaProfileType.Audio
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ResponseProfiles = new ResponseProfile[] { };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,6 +200,8 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ResponseProfiles = new ResponseProfile[] { };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,6 +181,8 @@ namespace MediaBrowser.Dlna.Profiles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ResponseProfiles = new ResponseProfile[] { };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,8 @@
|
|||||||
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
|
||||||
<XmlRootAttributes />
|
<XmlRootAttributes />
|
||||||
<DirectPlayProfiles>
|
<DirectPlayProfiles>
|
||||||
<DirectPlayProfile container="mp3,wma" type="Audio" />
|
<DirectPlayProfile container="m4v,ts,mkv,avi,mpg,mpeg,mp4" audioCodec="aac,mp3,ac3" videoCodec="h264" type="Video" />
|
||||||
<DirectPlayProfile container="avi,mp4" type="Video" />
|
<DirectPlayProfile container="mp3,wma,aac,wav" type="Audio" />
|
||||||
</DirectPlayProfiles>
|
</DirectPlayProfiles>
|
||||||
<TranscodingProfiles>
|
<TranscodingProfiles>
|
||||||
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" forceLiveStream="false" enableSubtitlesInManifest="false" />
|
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" forceLiveStream="false" enableSubtitlesInManifest="false" />
|
||||||
@ -39,6 +39,10 @@
|
|||||||
</TranscodingProfiles>
|
</TranscodingProfiles>
|
||||||
<ContainerProfiles />
|
<ContainerProfiles />
|
||||||
<CodecProfiles />
|
<CodecProfiles />
|
||||||
<ResponseProfiles />
|
<ResponseProfiles>
|
||||||
|
<ResponseProfile container="m4v" type="Video" mimeType="video/mp4">
|
||||||
|
<Conditions />
|
||||||
|
</ResponseProfile>
|
||||||
|
</ResponseProfiles>
|
||||||
<SubtitleProfiles />
|
<SubtitleProfiles />
|
||||||
</Profile>
|
</Profile>
|
@ -51,7 +51,10 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
var metadata = string.Empty;
|
var metadata = string.Empty;
|
||||||
var vn = string.Empty;
|
var vn = string.Empty;
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(state.AlbumCoverPath))
|
var hasArt = !string.IsNullOrWhiteSpace(state.AlbumCoverPath);
|
||||||
|
hasArt = false;
|
||||||
|
|
||||||
|
if (hasArt)
|
||||||
{
|
{
|
||||||
albumCoverInput = " -i \"" + state.AlbumCoverPath + "\"";
|
albumCoverInput = " -i \"" + state.AlbumCoverPath + "\"";
|
||||||
mapArgs = " -map 0:a -map 1:v -c:v copy";
|
mapArgs = " -map 0:a -map 1:v -c:v copy";
|
||||||
|
@ -123,10 +123,22 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
return "System";
|
return "System";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsDefaultPath(FFMpegPath))
|
||||||
|
{
|
||||||
|
return "Default";
|
||||||
|
}
|
||||||
|
|
||||||
return "Custom";
|
return "Custom";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsDefaultPath(string path)
|
||||||
|
{
|
||||||
|
var parentPath = Path.Combine(ConfigurationManager.ApplicationPaths.ProgramDataPath, "ffmpeg", "20160410");
|
||||||
|
|
||||||
|
return FileSystem.ContainsSubPath(parentPath, path);
|
||||||
|
}
|
||||||
|
|
||||||
private bool IsSystemInstalledPath(string path)
|
private bool IsSystemInstalledPath(string path)
|
||||||
{
|
{
|
||||||
if (path.IndexOf("/", StringComparison.Ordinal) == -1 && path.IndexOf("\\", StringComparison.Ordinal) == -1)
|
if (path.IndexOf("/", StringComparison.Ordinal) == -1 && path.IndexOf("\\", StringComparison.Ordinal) == -1)
|
||||||
|
@ -202,6 +202,7 @@ namespace MediaBrowser.Model.Configuration
|
|||||||
public bool DisplaySpecialsWithinSeasons { get; set; }
|
public bool DisplaySpecialsWithinSeasons { get; set; }
|
||||||
public bool DisplayCollectionsView { get; set; }
|
public bool DisplayCollectionsView { get; set; }
|
||||||
public string[] LocalNetworkAddresses { get; set; }
|
public string[] LocalNetworkAddresses { get; set; }
|
||||||
|
public string[] CodecsUsed { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
|
/// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
|
||||||
@ -210,6 +211,7 @@ namespace MediaBrowser.Model.Configuration
|
|||||||
{
|
{
|
||||||
LocalNetworkAddresses = new string[] { };
|
LocalNetworkAddresses = new string[] { };
|
||||||
Migrations = new string[] { };
|
Migrations = new string[] { };
|
||||||
|
CodecsUsed = new string[] { };
|
||||||
SqliteCacheSize = 0;
|
SqliteCacheSize = 0;
|
||||||
|
|
||||||
EnableLocalizedGuids = true;
|
EnableLocalizedGuids = true;
|
||||||
|
@ -43,13 +43,6 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||||||
_providerManager = providerManager;
|
_providerManager = providerManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<FileOrganizationResult> OrganizeEpisodeFile(string path, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var options = _config.GetAutoOrganizeOptions();
|
|
||||||
|
|
||||||
return OrganizeEpisodeFile(path, options, false, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<FileOrganizationResult> OrganizeEpisodeFile(string path, AutoOrganizeOptions options, bool overwriteExisting, CancellationToken cancellationToken)
|
public async Task<FileOrganizationResult> OrganizeEpisodeFile(string path, AutoOrganizeOptions options, bool overwriteExisting, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_logger.Info("Sorting file {0}", path);
|
_logger.Info("Sorting file {0}", path);
|
||||||
@ -63,6 +56,8 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||||||
FileSize = new FileInfo(path).Length
|
FileSize = new FileInfo(path).Length
|
||||||
};
|
};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
if (_libraryMonitor.IsPathLocked(path))
|
if (_libraryMonitor.IsPathLocked(path))
|
||||||
{
|
{
|
||||||
result.Status = FileSortingStatus.Failure;
|
result.Status = FileSortingStatus.Failure;
|
||||||
@ -148,6 +143,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||||||
}
|
}
|
||||||
|
|
||||||
await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false);
|
await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result.Status = FileSortingStatus.Failure;
|
||||||
|
result.StatusMessage = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -156,6 +157,8 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||||||
{
|
{
|
||||||
var result = _organizationService.GetResult(request.ResultId);
|
var result = _organizationService.GetResult(request.ResultId);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
Series series = null;
|
Series series = null;
|
||||||
|
|
||||||
if (request.NewSeriesProviderIds.Count > 0)
|
if (request.NewSeriesProviderIds.Count > 0)
|
||||||
@ -207,6 +210,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||||||
cancellationToken).ConfigureAwait(false);
|
cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false);
|
await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result.Status = FileSortingStatus.Failure;
|
||||||
|
result.StatusMessage = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -263,16 +272,15 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||||||
|
|
||||||
var originalExtractedSeriesString = result.ExtractedName;
|
var originalExtractedSeriesString = result.ExtractedName;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
// Proceed to sort the file
|
// Proceed to sort the file
|
||||||
var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, premiereDate, options.TvOptions, cancellationToken).ConfigureAwait(false);
|
var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, premiereDate, options.TvOptions, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(newPath))
|
if (string.IsNullOrEmpty(newPath))
|
||||||
{
|
{
|
||||||
var msg = string.Format("Unable to sort {0} because target path could not be determined.", sourcePath);
|
var msg = string.Format("Unable to sort {0} because target path could not be determined.", sourcePath);
|
||||||
result.Status = FileSortingStatus.Failure;
|
throw new Exception(msg);
|
||||||
result.StatusMessage = msg;
|
|
||||||
_logger.Warn(msg);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Info("Sorting file {0} to new path {1}", sourcePath, newPath);
|
_logger.Info("Sorting file {0} to new path {1}", sourcePath, newPath);
|
||||||
@ -347,6 +355,14 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result.Status = FileSortingStatus.Failure;
|
||||||
|
result.StatusMessage = ex.Message;
|
||||||
|
_logger.Warn(ex.Message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (rememberCorrection)
|
if (rememberCorrection)
|
||||||
{
|
{
|
||||||
@ -505,7 +521,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
var errorMsg = string.Format("Failed to move file from {0} to {1}", result.OriginalPath, result.TargetPath);
|
var errorMsg = string.Format("Failed to move file from {0} to {1}: {2}", result.OriginalPath, result.TargetPath, ex.Message);
|
||||||
|
|
||||||
result.Status = FileSortingStatus.Failure;
|
result.Status = FileSortingStatus.Failure;
|
||||||
result.StatusMessage = errorMsg;
|
result.StatusMessage = errorMsg;
|
||||||
@ -616,7 +632,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||||||
{
|
{
|
||||||
var msg = string.Format("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber);
|
var msg = string.Format("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber);
|
||||||
_logger.Warn(msg);
|
_logger.Warn(msg);
|
||||||
return null;
|
throw new Exception(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
var episodeName = episode.Name;
|
var episodeName = episode.Name;
|
||||||
@ -715,6 +731,11 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||||||
|
|
||||||
var pattern = endingEpisodeNumber.HasValue ? options.MultiEpisodeNamePattern : options.EpisodeNamePattern;
|
var pattern = endingEpisodeNumber.HasValue ? options.MultiEpisodeNamePattern : options.EpisodeNamePattern;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(pattern))
|
||||||
|
{
|
||||||
|
throw new Exception("GetEpisodeFileName: Configured episode name pattern is empty!");
|
||||||
|
}
|
||||||
|
|
||||||
var result = pattern.Replace("%sn", seriesName)
|
var result = pattern.Replace("%sn", seriesName)
|
||||||
.Replace("%s.n", seriesName.Replace(" ", "."))
|
.Replace("%s.n", seriesName.Replace(" ", "."))
|
||||||
.Replace("%s_n", seriesName.Replace(" ", "_"))
|
.Replace("%s_n", seriesName.Replace(" ", "_"))
|
||||||
@ -759,8 +780,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||||||
// There may be cases where reducing the title length may still not be sufficient to
|
// There may be cases where reducing the title length may still not be sufficient to
|
||||||
// stay below maxLength
|
// stay below maxLength
|
||||||
var msg = string.Format("Unable to generate an episode file name shorter than {0} characters to constrain to the max path limit", maxLength);
|
var msg = string.Format("Unable to generate an episode file name shorter than {0} characters to constrain to the max path limit", maxLength);
|
||||||
_logger.Warn(msg);
|
throw new Exception(msg);
|
||||||
return string.Empty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -112,8 +112,13 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||||||
var organizer = new EpisodeFileOrganizer(this, _config, _fileSystem, _logger, _libraryManager,
|
var organizer = new EpisodeFileOrganizer(this, _config, _fileSystem, _logger, _libraryManager,
|
||||||
_libraryMonitor, _providerManager);
|
_libraryMonitor, _providerManager);
|
||||||
|
|
||||||
await organizer.OrganizeEpisodeFile(result.OriginalPath, GetAutoOrganizeOptions(), true, CancellationToken.None)
|
var organizeResult = await organizer.OrganizeEpisodeFile(result.OriginalPath, GetAutoOrganizeOptions(), true, CancellationToken.None)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (organizeResult.Status != FileSortingStatus.Success)
|
||||||
|
{
|
||||||
|
throw new Exception(result.StatusMessage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task ClearLog()
|
public Task ClearLog()
|
||||||
@ -126,7 +131,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||||||
var organizer = new EpisodeFileOrganizer(this, _config, _fileSystem, _logger, _libraryManager,
|
var organizer = new EpisodeFileOrganizer(this, _config, _fileSystem, _logger, _libraryManager,
|
||||||
_libraryMonitor, _providerManager);
|
_libraryMonitor, _providerManager);
|
||||||
|
|
||||||
await organizer.OrganizeWithCorrection(request, GetAutoOrganizeOptions(), CancellationToken.None).ConfigureAwait(false);
|
var result = await organizer.OrganizeWithCorrection(request, GetAutoOrganizeOptions(), CancellationToken.None).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (result.Status != FileSortingStatus.Success)
|
||||||
|
{
|
||||||
|
throw new Exception(result.StatusMessage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryResult<SmartMatchInfo> GetSmartMatchInfos(FileOrganizationResultQuery query)
|
public QueryResult<SmartMatchInfo> GetSmartMatchInfos(FileOrganizationResultQuery query)
|
||||||
|
@ -3,6 +3,7 @@ using MediaBrowser.Model.Logging;
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Controller.Persistence;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.Library.Validators
|
namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
{
|
{
|
||||||
@ -16,16 +17,18 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
private readonly IItemRepository _itemRepo;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="GameGenresPostScanTask" /> class.
|
/// Initializes a new instance of the <see cref="GameGenresPostScanTask" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="libraryManager">The library manager.</param>
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
/// <param name="logger">The logger.</param>
|
/// <param name="logger">The logger.</param>
|
||||||
public GameGenresPostScanTask(ILibraryManager libraryManager, ILogger logger)
|
public GameGenresPostScanTask(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_itemRepo = itemRepo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -36,7 +39,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return new GameGenresValidator(_libraryManager, _logger).Run(progress, cancellationToken);
|
return new GameGenresValidator(_libraryManager, _logger, _itemRepo).Run(progress, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ using System;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Controller.Persistence;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.Library.Validators
|
namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
{
|
{
|
||||||
@ -19,11 +20,13 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||||||
/// The _logger
|
/// The _logger
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
private readonly IItemRepository _itemRepo;
|
||||||
|
|
||||||
public GameGenresValidator(ILibraryManager libraryManager, ILogger logger)
|
public GameGenresValidator(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_itemRepo = itemRepo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -34,21 +37,17 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var items = _libraryManager.GetGameGenres(new InternalItemsQuery
|
var names = _itemRepo.GetGameGenreNames();
|
||||||
{
|
|
||||||
IncludeItemTypes = new[] { typeof(Game).Name }
|
|
||||||
})
|
|
||||||
.Items
|
|
||||||
.Select(i => i.Item1)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
var numComplete = 0;
|
var numComplete = 0;
|
||||||
var count = items.Count;
|
var count = names.Count;
|
||||||
|
|
||||||
foreach (var item in items)
|
foreach (var name in names)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var item = _libraryManager.GetGameGenre(name);
|
||||||
|
|
||||||
await item.RefreshMetadata(cancellationToken).ConfigureAwait(false);
|
await item.RefreshMetadata(cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
@ -58,7 +57,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error refreshing {0}", ex, item.Name);
|
_logger.ErrorException("Error refreshing {0}", ex, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
numComplete++;
|
numComplete++;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Controller.Persistence;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.Library.Validators
|
namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
@ -13,16 +14,18 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
private readonly IItemRepository _itemRepo;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ArtistsPostScanTask" /> class.
|
/// Initializes a new instance of the <see cref="ArtistsPostScanTask" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="libraryManager">The library manager.</param>
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
/// <param name="logger">The logger.</param>
|
/// <param name="logger">The logger.</param>
|
||||||
public GenresPostScanTask(ILibraryManager libraryManager, ILogger logger)
|
public GenresPostScanTask(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_itemRepo = itemRepo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -33,7 +36,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return new GenresValidator(_libraryManager, _logger).Run(progress, cancellationToken);
|
return new GenresValidator(_libraryManager, _logger, _itemRepo).Run(progress, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ using System;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Controller.Persistence;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.Library.Validators
|
namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
{
|
{
|
||||||
@ -15,16 +16,18 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||||||
/// The _library manager
|
/// The _library manager
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
private readonly IItemRepository _itemRepo;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _logger
|
/// The _logger
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
public GenresValidator(ILibraryManager libraryManager, ILogger logger)
|
public GenresValidator(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_itemRepo = itemRepo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -35,21 +38,17 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var items = _libraryManager.GetGenres(new InternalItemsQuery
|
var names = _itemRepo.GetGenreNames();
|
||||||
{
|
|
||||||
ExcludeItemTypes = new[] { typeof(Audio).Name, typeof(MusicArtist).Name, typeof(MusicAlbum).Name, typeof(MusicVideo).Name, typeof(Game).Name }
|
|
||||||
})
|
|
||||||
.Items
|
|
||||||
.Select(i => i.Item1)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
var numComplete = 0;
|
var numComplete = 0;
|
||||||
var count = items.Count;
|
var count = names.Count;
|
||||||
|
|
||||||
foreach (var item in items)
|
foreach (var name in names)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var item = _libraryManager.GetGenre(name);
|
||||||
|
|
||||||
await item.RefreshMetadata(cancellationToken).ConfigureAwait(false);
|
await item.RefreshMetadata(cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
@ -59,7 +58,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error refreshing {0}", ex, item.Name);
|
_logger.ErrorException("Error refreshing {0}", ex, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
numComplete++;
|
numComplete++;
|
||||||
|
@ -3,6 +3,7 @@ using MediaBrowser.Model.Logging;
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Controller.Persistence;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.Library.Validators
|
namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
{
|
{
|
||||||
@ -16,16 +17,18 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
private readonly IItemRepository _itemRepo;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ArtistsPostScanTask" /> class.
|
/// Initializes a new instance of the <see cref="ArtistsPostScanTask" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="libraryManager">The library manager.</param>
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
/// <param name="logger">The logger.</param>
|
/// <param name="logger">The logger.</param>
|
||||||
public MusicGenresPostScanTask(ILibraryManager libraryManager, ILogger logger)
|
public MusicGenresPostScanTask(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_itemRepo = itemRepo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -36,7 +39,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return new MusicGenresValidator(_libraryManager, _logger).Run(progress, cancellationToken);
|
return new MusicGenresValidator(_libraryManager, _logger, _itemRepo).Run(progress, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ using System.Linq;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
|
using MediaBrowser.Controller.Persistence;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.Library.Validators
|
namespace MediaBrowser.Server.Implementations.Library.Validators
|
||||||
{
|
{
|
||||||
@ -20,11 +21,13 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||||||
/// The _logger
|
/// The _logger
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
private readonly IItemRepository _itemRepo;
|
||||||
|
|
||||||
public MusicGenresValidator(ILibraryManager libraryManager, ILogger logger)
|
public MusicGenresValidator(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_itemRepo = itemRepo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -35,21 +38,17 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var items = _libraryManager.GetMusicGenres(new InternalItemsQuery
|
var names = _itemRepo.GetMusicGenreNames();
|
||||||
{
|
|
||||||
IncludeItemTypes = new[] { typeof(Audio).Name, typeof(MusicArtist).Name, typeof(MusicAlbum).Name, typeof(MusicVideo).Name }
|
|
||||||
})
|
|
||||||
.Items
|
|
||||||
.Select(i => i.Item1)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
var numComplete = 0;
|
var numComplete = 0;
|
||||||
var count = items.Count;
|
var count = names.Count;
|
||||||
|
|
||||||
foreach (var item in items)
|
foreach (var name in names)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var item = _libraryManager.GetMusicGenre(name);
|
||||||
|
|
||||||
await item.RefreshMetadata(cancellationToken).ConfigureAwait(false);
|
await item.RefreshMetadata(cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
@ -59,7 +58,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error refreshing {0}", ex, item.Name);
|
_logger.ErrorException("Error refreshing {0}", ex, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
numComplete++;
|
numComplete++;
|
||||||
|
@ -1139,7 +1139,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||||||
|
|
||||||
var organize = new EpisodeFileOrganizer(_organizationService, _config, _fileSystem, _logger, _libraryManager, _libraryMonitor, _providerManager);
|
var organize = new EpisodeFileOrganizer(_organizationService, _config, _fileSystem, _logger, _libraryManager, _libraryMonitor, _providerManager);
|
||||||
|
|
||||||
var result = await organize.OrganizeEpisodeFile(path, CancellationToken.None).ConfigureAwait(false);
|
var result = await organize.OrganizeEpisodeFile(path, _config.GetAutoOrganizeOptions(), false, CancellationToken.None).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
<HintPath>..\packages\CommonIO.1.0.0.9\lib\net45\CommonIO.dll</HintPath>
|
<HintPath>..\packages\CommonIO.1.0.0.9\lib\net45\CommonIO.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Emby.XmlTv, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Emby.XmlTv, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Emby.XmlTv.1.0.0.55\lib\net45\Emby.XmlTv.dll</HintPath>
|
<HintPath>..\packages\Emby.XmlTv.1.0.0.56\lib\net45\Emby.XmlTv.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="INIFileParser, Version=2.3.0.0, Culture=neutral, PublicKeyToken=79af7b307b65cf3c, processorArchitecture=MSIL">
|
<Reference Include="INIFileParser, Version=2.3.0.0, Culture=neutral, PublicKeyToken=79af7b307b65cf3c, processorArchitecture=MSIL">
|
||||||
|
@ -3882,18 +3882,36 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||||||
|
|
||||||
public List<string> GetStudioNames()
|
public List<string> GetStudioNames()
|
||||||
{
|
{
|
||||||
return GetItemValueNames(new[] { 3 });
|
return GetItemValueNames(new[] { 3 }, new List<string>(), new List<string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<string> GetAllArtistNames()
|
public List<string> GetAllArtistNames()
|
||||||
{
|
{
|
||||||
return GetItemValueNames(new[] { 0, 1 });
|
return GetItemValueNames(new[] { 0, 1 }, new List<string>(), new List<string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<string> GetItemValueNames(int[] itemValueTypes)
|
public List<string> GetMusicGenreNames()
|
||||||
|
{
|
||||||
|
return GetItemValueNames(new[] { 2 }, new List<string> { "Audio", "MusicVideo", "MusicAlbum", "MusicArtist" }, new List<string>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<string> GetGameGenreNames()
|
||||||
|
{
|
||||||
|
return GetItemValueNames(new[] { 2 }, new List<string> { "Game" }, new List<string>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<string> GetGenreNames()
|
||||||
|
{
|
||||||
|
return GetItemValueNames(new[] { 2 }, new List<string>(), new List<string> { "Audio", "MusicVideo", "MusicAlbum", "MusicArtist", "Game", "GameSystem" });
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<string> GetItemValueNames(int[] itemValueTypes, List<string> withItemTypes, List<string> excludeItemTypes)
|
||||||
{
|
{
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
|
withItemTypes = withItemTypes.SelectMany(MapIncludeItemTypes).ToList();
|
||||||
|
excludeItemTypes = excludeItemTypes.SelectMany(MapIncludeItemTypes).ToList();
|
||||||
|
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
|
|
||||||
var typeClause = itemValueTypes.Length == 1 ?
|
var typeClause = itemValueTypes.Length == 1 ?
|
||||||
@ -3904,7 +3922,20 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||||||
|
|
||||||
using (var cmd = _connection.CreateCommand())
|
using (var cmd = _connection.CreateCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = "Select Value From ItemValues where " + typeClause + " Group By CleanValue";
|
cmd.CommandText = "Select Value From ItemValues where " + typeClause;
|
||||||
|
|
||||||
|
if (withItemTypes.Count > 0)
|
||||||
|
{
|
||||||
|
var typeString = string.Join(",", withItemTypes.Select(i => "'" + i + "'").ToArray());
|
||||||
|
cmd.CommandText += " AND ItemId In (select guid from typedbaseitems where type in (" + typeString + "))";
|
||||||
|
}
|
||||||
|
if (excludeItemTypes.Count > 0)
|
||||||
|
{
|
||||||
|
var typeString = string.Join(",", excludeItemTypes.Select(i => "'" + i + "'").ToArray());
|
||||||
|
cmd.CommandText += " AND ItemId not In (select guid from typedbaseitems where type in (" + typeString + "))";
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.CommandText += " Group By CleanValue";
|
||||||
|
|
||||||
var commandBehavior = CommandBehavior.SequentialAccess | CommandBehavior.SingleResult;
|
var commandBehavior = CommandBehavior.SequentialAccess | CommandBehavior.SingleResult;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="CommonIO" version="1.0.0.9" targetFramework="net45" />
|
<package id="CommonIO" version="1.0.0.9" targetFramework="net45" />
|
||||||
<package id="Emby.XmlTv" version="1.0.0.55" targetFramework="net45" />
|
<package id="Emby.XmlTv" version="1.0.0.56" targetFramework="net45" />
|
||||||
<package id="ini-parser" version="2.3.0" targetFramework="net45" />
|
<package id="ini-parser" version="2.3.0" targetFramework="net45" />
|
||||||
<package id="Interfaces.IO" version="1.0.0.5" targetFramework="net45" />
|
<package id="Interfaces.IO" version="1.0.0.5" targetFramework="net45" />
|
||||||
<package id="MediaBrowser.Naming" version="1.0.0.55" targetFramework="net45" />
|
<package id="MediaBrowser.Naming" version="1.0.0.55" targetFramework="net45" />
|
||||||
|
@ -101,6 +101,7 @@ using System.Reflection;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using CommonIO;
|
using CommonIO;
|
||||||
|
using MediaBrowser.Api.Playback;
|
||||||
using MediaBrowser.Common.Implementations.Updates;
|
using MediaBrowser.Common.Implementations.Updates;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Startup.Common
|
namespace MediaBrowser.Server.Startup.Common
|
||||||
@ -766,6 +767,8 @@ namespace MediaBrowser.Server.Startup.Common
|
|||||||
BaseItem.CollectionManager = CollectionManager;
|
BaseItem.CollectionManager = CollectionManager;
|
||||||
BaseItem.MediaSourceManager = MediaSourceManager;
|
BaseItem.MediaSourceManager = MediaSourceManager;
|
||||||
CollectionFolder.XmlSerializer = XmlSerializer;
|
CollectionFolder.XmlSerializer = XmlSerializer;
|
||||||
|
BaseStreamingService.AppHost = this;
|
||||||
|
BaseStreamingService.HttpClient = HttpClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user