Merge pull request #2874 from barronpm/warnings-cleanup1
Emby.Server.Implementations code cleanup and warning fixes (Part 1)
This commit is contained in:
commit
f81833693d
|
@ -137,7 +137,7 @@ namespace Emby.Server.Implementations.Activity
|
||||||
CultureInfo.InvariantCulture,
|
CultureInfo.InvariantCulture,
|
||||||
_localization.GetLocalizedString("SubtitleDownloadFailureFromForItem"),
|
_localization.GetLocalizedString("SubtitleDownloadFailureFromForItem"),
|
||||||
e.Provider,
|
e.Provider,
|
||||||
Emby.Notifications.NotificationEntryPoint.GetItemName(e.Item)),
|
Notifications.NotificationEntryPoint.GetItemName(e.Item)),
|
||||||
Type = "SubtitleDownloadFailure",
|
Type = "SubtitleDownloadFailure",
|
||||||
ItemId = e.Item.Id.ToString("N", CultureInfo.InvariantCulture),
|
ItemId = e.Item.Id.ToString("N", CultureInfo.InvariantCulture),
|
||||||
ShortOverview = e.Exception.Message
|
ShortOverview = e.Exception.Message
|
||||||
|
@ -265,31 +265,20 @@ namespace Emby.Server.Implementations.Activity
|
||||||
|
|
||||||
private void OnSessionEnded(object sender, SessionEventArgs e)
|
private void OnSessionEnded(object sender, SessionEventArgs e)
|
||||||
{
|
{
|
||||||
string name;
|
|
||||||
var session = e.SessionInfo;
|
var session = e.SessionInfo;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(session.UserName))
|
if (string.IsNullOrEmpty(session.UserName))
|
||||||
{
|
{
|
||||||
name = string.Format(
|
|
||||||
CultureInfo.InvariantCulture,
|
|
||||||
_localization.GetLocalizedString("DeviceOfflineWithName"),
|
|
||||||
session.DeviceName);
|
|
||||||
|
|
||||||
// Causing too much spam for now
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
name = string.Format(
|
|
||||||
CultureInfo.InvariantCulture,
|
|
||||||
_localization.GetLocalizedString("UserOfflineFromDevice"),
|
|
||||||
session.UserName,
|
|
||||||
session.DeviceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateLogEntry(new ActivityLogEntry
|
CreateLogEntry(new ActivityLogEntry
|
||||||
{
|
{
|
||||||
Name = name,
|
Name = string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
_localization.GetLocalizedString("UserOfflineFromDevice"),
|
||||||
|
session.UserName,
|
||||||
|
session.DeviceName),
|
||||||
Type = "SessionEnded",
|
Type = "SessionEnded",
|
||||||
ShortOverview = string.Format(
|
ShortOverview = string.Format(
|
||||||
CultureInfo.InvariantCulture,
|
CultureInfo.InvariantCulture,
|
||||||
|
@ -388,31 +377,20 @@ namespace Emby.Server.Implementations.Activity
|
||||||
|
|
||||||
private void OnSessionStarted(object sender, SessionEventArgs e)
|
private void OnSessionStarted(object sender, SessionEventArgs e)
|
||||||
{
|
{
|
||||||
string name;
|
|
||||||
var session = e.SessionInfo;
|
var session = e.SessionInfo;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(session.UserName))
|
if (string.IsNullOrEmpty(session.UserName))
|
||||||
{
|
{
|
||||||
name = string.Format(
|
|
||||||
CultureInfo.InvariantCulture,
|
|
||||||
_localization.GetLocalizedString("DeviceOnlineWithName"),
|
|
||||||
session.DeviceName);
|
|
||||||
|
|
||||||
// Causing too much spam for now
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
name = string.Format(
|
|
||||||
CultureInfo.InvariantCulture,
|
|
||||||
_localization.GetLocalizedString("UserOnlineFromDevice"),
|
|
||||||
session.UserName,
|
|
||||||
session.DeviceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateLogEntry(new ActivityLogEntry
|
CreateLogEntry(new ActivityLogEntry
|
||||||
{
|
{
|
||||||
Name = name,
|
Name = string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
_localization.GetLocalizedString("UserOnlineFromDevice"),
|
||||||
|
session.UserName,
|
||||||
|
session.DeviceName),
|
||||||
Type = "SessionStarted",
|
Type = "SessionStarted",
|
||||||
ShortOverview = string.Format(
|
ShortOverview = string.Format(
|
||||||
CultureInfo.InvariantCulture,
|
CultureInfo.InvariantCulture,
|
||||||
|
@ -580,7 +558,7 @@ namespace Emby.Server.Implementations.Activity
|
||||||
{
|
{
|
||||||
int years = days / DaysInYear;
|
int years = days / DaysInYear;
|
||||||
values.Add(CreateValueString(years, "year"));
|
values.Add(CreateValueString(years, "year"));
|
||||||
days = days % DaysInYear;
|
days %= DaysInYear;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Number of months
|
// Number of months
|
||||||
|
@ -588,7 +566,7 @@ namespace Emby.Server.Implementations.Activity
|
||||||
{
|
{
|
||||||
int months = days / DaysInMonth;
|
int months = days / DaysInMonth;
|
||||||
values.Add(CreateValueString(months, "month"));
|
values.Add(CreateValueString(months, "month"));
|
||||||
days = days % DaysInMonth;
|
days %= DaysInMonth;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Number of days
|
// Number of days
|
||||||
|
|
|
@ -1,25 +1,31 @@
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Model.Activity;
|
using MediaBrowser.Model.Activity;
|
||||||
using MediaBrowser.Model.Events;
|
using MediaBrowser.Model.Events;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Activity
|
namespace Emby.Server.Implementations.Activity
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The activity log manager.
|
||||||
|
/// </summary>
|
||||||
public class ActivityManager : IActivityManager
|
public class ActivityManager : IActivityManager
|
||||||
{
|
{
|
||||||
private readonly IActivityRepository _repo;
|
private readonly IActivityRepository _repo;
|
||||||
private readonly IUserManager _userManager;
|
private readonly IUserManager _userManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ActivityManager"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="repo">The activity repository.</param>
|
||||||
|
/// <param name="userManager">The user manager.</param>
|
||||||
public ActivityManager(IActivityRepository repo, IUserManager userManager)
|
public ActivityManager(IActivityRepository repo, IUserManager userManager)
|
||||||
{
|
{
|
||||||
_repo = repo;
|
_repo = repo;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public event EventHandler<GenericEventArgs<ActivityLogEntry>> EntryCreated;
|
public event EventHandler<GenericEventArgs<ActivityLogEntry>> EntryCreated;
|
||||||
|
|
||||||
public void Create(ActivityLogEntry entry)
|
public void Create(ActivityLogEntry entry)
|
||||||
|
@ -31,6 +37,7 @@ namespace Emby.Server.Implementations.Activity
|
||||||
EntryCreated?.Invoke(this, new GenericEventArgs<ActivityLogEntry>(entry));
|
EntryCreated?.Invoke(this, new GenericEventArgs<ActivityLogEntry>(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
|
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
|
||||||
{
|
{
|
||||||
var result = _repo.GetActivityLogEntries(minDate, hasUserId, startIndex, limit);
|
var result = _repo.GetActivityLogEntries(minDate, hasUserId, startIndex, limit);
|
||||||
|
@ -54,6 +61,7 @@ namespace Emby.Server.Implementations.Activity
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, int? startIndex, int? limit)
|
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, int? startIndex, int? limit)
|
||||||
{
|
{
|
||||||
return GetActivityLogEntries(minDate, null, startIndex, limit);
|
return GetActivityLogEntries(minDate, null, startIndex, limit);
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
@ -15,12 +13,21 @@ using SQLitePCL.pretty;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Activity
|
namespace Emby.Server.Implementations.Activity
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The activity log repository.
|
||||||
|
/// </summary>
|
||||||
public class ActivityRepository : BaseSqliteRepository, IActivityRepository
|
public class ActivityRepository : BaseSqliteRepository, IActivityRepository
|
||||||
{
|
{
|
||||||
private const string BaseActivitySelectText = "select Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity from ActivityLog";
|
private const string BaseActivitySelectText = "select Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity from ActivityLog";
|
||||||
|
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ActivityRepository"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logger">The logger.</param>
|
||||||
|
/// <param name="appPaths">The server application paths.</param>
|
||||||
|
/// <param name="fileSystem">The filesystem.</param>
|
||||||
public ActivityRepository(ILogger<ActivityRepository> logger, IServerApplicationPaths appPaths, IFileSystem fileSystem)
|
public ActivityRepository(ILogger<ActivityRepository> logger, IServerApplicationPaths appPaths, IFileSystem fileSystem)
|
||||||
: base(logger)
|
: base(logger)
|
||||||
{
|
{
|
||||||
|
@ -28,6 +35,9 @@ namespace Emby.Server.Implementations.Activity
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the <see cref="ActivityRepository"/>.
|
||||||
|
/// </summary>
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -46,16 +56,14 @@ namespace Emby.Server.Implementations.Activity
|
||||||
|
|
||||||
private void InitializeInternal()
|
private void InitializeInternal()
|
||||||
{
|
{
|
||||||
using (var connection = GetConnection())
|
using var connection = GetConnection();
|
||||||
|
connection.RunQueries(new[]
|
||||||
{
|
{
|
||||||
connection.RunQueries(new[]
|
"create table if not exists ActivityLog (Id INTEGER PRIMARY KEY, Name TEXT NOT NULL, Overview TEXT, ShortOverview TEXT, Type TEXT NOT NULL, ItemId TEXT, UserId TEXT, DateCreated DATETIME NOT NULL, LogSeverity TEXT NOT NULL)",
|
||||||
{
|
"drop index if exists idx_ActivityLogEntries"
|
||||||
"create table if not exists ActivityLog (Id INTEGER PRIMARY KEY, Name TEXT NOT NULL, Overview TEXT, ShortOverview TEXT, Type TEXT NOT NULL, ItemId TEXT, UserId TEXT, DateCreated DATETIME NOT NULL, LogSeverity TEXT NOT NULL)",
|
});
|
||||||
"drop index if exists idx_ActivityLogEntries"
|
|
||||||
});
|
|
||||||
|
|
||||||
TryMigrate(connection);
|
TryMigrate(connection);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TryMigrate(ManagedConnection connection)
|
private void TryMigrate(ManagedConnection connection)
|
||||||
|
@ -77,6 +85,7 @@ namespace Emby.Server.Implementations.Activity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public void Create(ActivityLogEntry entry)
|
public void Create(ActivityLogEntry entry)
|
||||||
{
|
{
|
||||||
if (entry == null)
|
if (entry == null)
|
||||||
|
@ -84,39 +93,38 @@ namespace Emby.Server.Implementations.Activity
|
||||||
throw new ArgumentNullException(nameof(entry));
|
throw new ArgumentNullException(nameof(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var connection = GetConnection())
|
using var connection = GetConnection();
|
||||||
|
connection.RunInTransaction(db =>
|
||||||
{
|
{
|
||||||
connection.RunInTransaction(
|
using var statement = db.PrepareStatement("insert into ActivityLog (Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) values (@Name, @Overview, @ShortOverview, @Type, @ItemId, @UserId, @DateCreated, @LogSeverity)");
|
||||||
db =>
|
statement.TryBind("@Name", entry.Name);
|
||||||
{
|
|
||||||
using (var statement = db.PrepareStatement("insert into ActivityLog (Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) values (@Name, @Overview, @ShortOverview, @Type, @ItemId, @UserId, @DateCreated, @LogSeverity)"))
|
|
||||||
{
|
|
||||||
statement.TryBind("@Name", entry.Name);
|
|
||||||
|
|
||||||
statement.TryBind("@Overview", entry.Overview);
|
statement.TryBind("@Overview", entry.Overview);
|
||||||
statement.TryBind("@ShortOverview", entry.ShortOverview);
|
statement.TryBind("@ShortOverview", entry.ShortOverview);
|
||||||
statement.TryBind("@Type", entry.Type);
|
statement.TryBind("@Type", entry.Type);
|
||||||
statement.TryBind("@ItemId", entry.ItemId);
|
statement.TryBind("@ItemId", entry.ItemId);
|
||||||
|
|
||||||
if (entry.UserId.Equals(Guid.Empty))
|
if (entry.UserId.Equals(Guid.Empty))
|
||||||
{
|
{
|
||||||
statement.TryBindNull("@UserId");
|
statement.TryBindNull("@UserId");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture));
|
statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture));
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue());
|
statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue());
|
||||||
statement.TryBind("@LogSeverity", entry.Severity.ToString());
|
statement.TryBind("@LogSeverity", entry.Severity.ToString());
|
||||||
|
|
||||||
statement.MoveNext();
|
statement.MoveNext();
|
||||||
}
|
}, TransactionMode);
|
||||||
},
|
|
||||||
TransactionMode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the provided <see cref="ActivityLogEntry"/> to this repository.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entry">The activity log entry.</param>
|
||||||
|
/// <exception cref="ArgumentNullException">If entry is null.</exception>
|
||||||
public void Update(ActivityLogEntry entry)
|
public void Update(ActivityLogEntry entry)
|
||||||
{
|
{
|
||||||
if (entry == null)
|
if (entry == null)
|
||||||
|
@ -124,40 +132,35 @@ namespace Emby.Server.Implementations.Activity
|
||||||
throw new ArgumentNullException(nameof(entry));
|
throw new ArgumentNullException(nameof(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var connection = GetConnection())
|
using var connection = GetConnection();
|
||||||
|
connection.RunInTransaction(db =>
|
||||||
{
|
{
|
||||||
connection.RunInTransaction(
|
using var statement = db.PrepareStatement("Update ActivityLog set Name=@Name,Overview=@Overview,ShortOverview=@ShortOverview,Type=@Type,ItemId=@ItemId,UserId=@UserId,DateCreated=@DateCreated,LogSeverity=@LogSeverity where Id=@Id");
|
||||||
db =>
|
statement.TryBind("@Id", entry.Id);
|
||||||
{
|
|
||||||
using (var statement = db.PrepareStatement("Update ActivityLog set Name=@Name,Overview=@Overview,ShortOverview=@ShortOverview,Type=@Type,ItemId=@ItemId,UserId=@UserId,DateCreated=@DateCreated,LogSeverity=@LogSeverity where Id=@Id"))
|
|
||||||
{
|
|
||||||
statement.TryBind("@Id", entry.Id);
|
|
||||||
|
|
||||||
statement.TryBind("@Name", entry.Name);
|
statement.TryBind("@Name", entry.Name);
|
||||||
statement.TryBind("@Overview", entry.Overview);
|
statement.TryBind("@Overview", entry.Overview);
|
||||||
statement.TryBind("@ShortOverview", entry.ShortOverview);
|
statement.TryBind("@ShortOverview", entry.ShortOverview);
|
||||||
statement.TryBind("@Type", entry.Type);
|
statement.TryBind("@Type", entry.Type);
|
||||||
statement.TryBind("@ItemId", entry.ItemId);
|
statement.TryBind("@ItemId", entry.ItemId);
|
||||||
|
|
||||||
if (entry.UserId.Equals(Guid.Empty))
|
if (entry.UserId.Equals(Guid.Empty))
|
||||||
{
|
{
|
||||||
statement.TryBindNull("@UserId");
|
statement.TryBindNull("@UserId");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture));
|
statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture));
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue());
|
statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue());
|
||||||
statement.TryBind("@LogSeverity", entry.Severity.ToString());
|
statement.TryBind("@LogSeverity", entry.Severity.ToString());
|
||||||
|
|
||||||
statement.MoveNext();
|
statement.MoveNext();
|
||||||
}
|
}, TransactionMode);
|
||||||
},
|
|
||||||
TransactionMode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
|
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
|
||||||
{
|
{
|
||||||
var commandText = BaseActivitySelectText;
|
var commandText = BaseActivitySelectText;
|
||||||
|
@ -170,14 +173,7 @@ namespace Emby.Server.Implementations.Activity
|
||||||
|
|
||||||
if (hasUserId.HasValue)
|
if (hasUserId.HasValue)
|
||||||
{
|
{
|
||||||
if (hasUserId.Value)
|
whereClauses.Add(hasUserId.Value ? "UserId not null" : "UserId is null");
|
||||||
{
|
|
||||||
whereClauses.Add("UserId not null");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
whereClauses.Add("UserId is null");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var whereTextWithoutPaging = whereClauses.Count == 0 ?
|
var whereTextWithoutPaging = whereClauses.Count == 0 ?
|
||||||
|
@ -220,38 +216,33 @@ namespace Emby.Server.Implementations.Activity
|
||||||
var list = new List<ActivityLogEntry>();
|
var list = new List<ActivityLogEntry>();
|
||||||
var result = new QueryResult<ActivityLogEntry>();
|
var result = new QueryResult<ActivityLogEntry>();
|
||||||
|
|
||||||
using (var connection = GetConnection(true))
|
using var connection = GetConnection(true);
|
||||||
{
|
connection.RunInTransaction(
|
||||||
connection.RunInTransaction(
|
db =>
|
||||||
db =>
|
{
|
||||||
|
var statements = PrepareAll(db, statementTexts).ToList();
|
||||||
|
|
||||||
|
using (var statement = statements[0])
|
||||||
{
|
{
|
||||||
var statements = PrepareAll(db, statementTexts).ToList();
|
if (minDate.HasValue)
|
||||||
|
|
||||||
using (var statement = statements[0])
|
|
||||||
{
|
{
|
||||||
if (minDate.HasValue)
|
statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue());
|
||||||
{
|
|
||||||
statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var row in statement.ExecuteQuery())
|
|
||||||
{
|
|
||||||
list.Add(GetEntry(row));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var statement = statements[1])
|
list.AddRange(statement.ExecuteQuery().Select(GetEntry));
|
||||||
{
|
}
|
||||||
if (minDate.HasValue)
|
|
||||||
{
|
|
||||||
statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
|
using (var statement = statements[1])
|
||||||
|
{
|
||||||
|
if (minDate.HasValue)
|
||||||
|
{
|
||||||
|
statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue());
|
||||||
}
|
}
|
||||||
},
|
|
||||||
ReadTransactionMode);
|
result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
ReadTransactionMode);
|
||||||
|
|
||||||
result.Items = list;
|
result.Items = list;
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -15,6 +15,11 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="BaseApplicationPaths"/> class.
|
/// Initializes a new instance of the <see cref="BaseApplicationPaths"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="programDataPath">The program data path.</param>
|
||||||
|
/// <param name="logDirectoryPath">The log directory path.</param>
|
||||||
|
/// <param name="configurationDirectoryPath">The configuration directory path.</param>
|
||||||
|
/// <param name="cacheDirectoryPath">The cache directory path.</param>
|
||||||
|
/// <param name="webDirectoryPath">The web directory path.</param>
|
||||||
protected BaseApplicationPaths(
|
protected BaseApplicationPaths(
|
||||||
string programDataPath,
|
string programDataPath,
|
||||||
string logDirectoryPath,
|
string logDirectoryPath,
|
||||||
|
|
|
@ -36,24 +36,22 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
configuration = Activator.CreateInstance(type);
|
configuration = Activator.CreateInstance(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var stream = new MemoryStream())
|
using var stream = new MemoryStream();
|
||||||
|
xmlSerializer.SerializeToStream(configuration, stream);
|
||||||
|
|
||||||
|
// Take the object we just got and serialize it back to bytes
|
||||||
|
var newBytes = stream.ToArray();
|
||||||
|
|
||||||
|
// If the file didn't exist before, or if something has changed, re-save
|
||||||
|
if (buffer == null || !buffer.SequenceEqual(newBytes))
|
||||||
{
|
{
|
||||||
xmlSerializer.SerializeToStream(configuration, stream);
|
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||||
|
|
||||||
// Take the object we just got and serialize it back to bytes
|
// Save it after load in case we got new items
|
||||||
var newBytes = stream.ToArray();
|
File.WriteAllBytes(path, newBytes);
|
||||||
|
|
||||||
// If the file didn't exist before, or if something has changed, re-save
|
|
||||||
if (buffer == null || !buffer.SequenceEqual(newBytes))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
|
||||||
|
|
||||||
// Save it after load in case we got new items
|
|
||||||
File.WriteAllBytes(path, newBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return configuration;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return configuration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,10 +22,8 @@ namespace Emby.Server.Implementations.Archiving
|
||||||
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
|
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
|
||||||
public void ExtractAll(string sourceFile, string targetPath, bool overwriteExistingFiles)
|
public void ExtractAll(string sourceFile, string targetPath, bool overwriteExistingFiles)
|
||||||
{
|
{
|
||||||
using (var fileStream = File.OpenRead(sourceFile))
|
using var fileStream = File.OpenRead(sourceFile);
|
||||||
{
|
ExtractAll(fileStream, targetPath, overwriteExistingFiles);
|
||||||
ExtractAll(fileStream, targetPath, overwriteExistingFiles);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -36,70 +34,61 @@ namespace Emby.Server.Implementations.Archiving
|
||||||
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
|
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
|
||||||
public void ExtractAll(Stream source, string targetPath, bool overwriteExistingFiles)
|
public void ExtractAll(Stream source, string targetPath, bool overwriteExistingFiles)
|
||||||
{
|
{
|
||||||
using (var reader = ReaderFactory.Open(source))
|
using var reader = ReaderFactory.Open(source);
|
||||||
|
var options = new ExtractionOptions
|
||||||
{
|
{
|
||||||
var options = new ExtractionOptions();
|
ExtractFullPath = true
|
||||||
options.ExtractFullPath = true;
|
};
|
||||||
|
|
||||||
if (overwriteExistingFiles)
|
if (overwriteExistingFiles)
|
||||||
{
|
{
|
||||||
options.Overwrite = true;
|
options.Overwrite = true;
|
||||||
}
|
|
||||||
|
|
||||||
reader.WriteAllToDirectory(targetPath, options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reader.WriteAllToDirectory(targetPath, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void ExtractAllFromZip(Stream source, string targetPath, bool overwriteExistingFiles)
|
public void ExtractAllFromZip(Stream source, string targetPath, bool overwriteExistingFiles)
|
||||||
{
|
{
|
||||||
using (var reader = ZipReader.Open(source))
|
using var reader = ZipReader.Open(source);
|
||||||
|
var options = new ExtractionOptions
|
||||||
{
|
{
|
||||||
var options = new ExtractionOptions();
|
ExtractFullPath = true,
|
||||||
options.ExtractFullPath = true;
|
Overwrite = overwriteExistingFiles
|
||||||
|
};
|
||||||
|
|
||||||
if (overwriteExistingFiles)
|
reader.WriteAllToDirectory(targetPath, options);
|
||||||
{
|
|
||||||
options.Overwrite = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
reader.WriteAllToDirectory(targetPath, options);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void ExtractAllFromGz(Stream source, string targetPath, bool overwriteExistingFiles)
|
public void ExtractAllFromGz(Stream source, string targetPath, bool overwriteExistingFiles)
|
||||||
{
|
{
|
||||||
using (var reader = GZipReader.Open(source))
|
using var reader = GZipReader.Open(source);
|
||||||
|
var options = new ExtractionOptions
|
||||||
{
|
{
|
||||||
var options = new ExtractionOptions();
|
ExtractFullPath = true,
|
||||||
options.ExtractFullPath = true;
|
Overwrite = overwriteExistingFiles
|
||||||
|
};
|
||||||
|
|
||||||
if (overwriteExistingFiles)
|
reader.WriteAllToDirectory(targetPath, options);
|
||||||
{
|
|
||||||
options.Overwrite = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
reader.WriteAllToDirectory(targetPath, options);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void ExtractFirstFileFromGz(Stream source, string targetPath, string defaultFileName)
|
public void ExtractFirstFileFromGz(Stream source, string targetPath, string defaultFileName)
|
||||||
{
|
{
|
||||||
using (var reader = GZipReader.Open(source))
|
using var reader = GZipReader.Open(source);
|
||||||
|
if (reader.MoveToNextEntry())
|
||||||
{
|
{
|
||||||
if (reader.MoveToNextEntry())
|
var entry = reader.Entry;
|
||||||
{
|
|
||||||
var entry = reader.Entry;
|
|
||||||
|
|
||||||
var filename = entry.Key;
|
var filename = entry.Key;
|
||||||
if (string.IsNullOrWhiteSpace(filename))
|
if (string.IsNullOrWhiteSpace(filename))
|
||||||
{
|
{
|
||||||
filename = defaultFileName;
|
filename = defaultFileName;
|
||||||
}
|
|
||||||
reader.WriteEntryToFile(Path.Combine(targetPath, filename));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reader.WriteEntryToFile(Path.Combine(targetPath, filename));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,10 +100,8 @@ namespace Emby.Server.Implementations.Archiving
|
||||||
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
|
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
|
||||||
public void ExtractAllFrom7z(string sourceFile, string targetPath, bool overwriteExistingFiles)
|
public void ExtractAllFrom7z(string sourceFile, string targetPath, bool overwriteExistingFiles)
|
||||||
{
|
{
|
||||||
using (var fileStream = File.OpenRead(sourceFile))
|
using var fileStream = File.OpenRead(sourceFile);
|
||||||
{
|
ExtractAllFrom7z(fileStream, targetPath, overwriteExistingFiles);
|
||||||
ExtractAllFrom7z(fileStream, targetPath, overwriteExistingFiles);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -125,21 +112,15 @@ namespace Emby.Server.Implementations.Archiving
|
||||||
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
|
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
|
||||||
public void ExtractAllFrom7z(Stream source, string targetPath, bool overwriteExistingFiles)
|
public void ExtractAllFrom7z(Stream source, string targetPath, bool overwriteExistingFiles)
|
||||||
{
|
{
|
||||||
using (var archive = SevenZipArchive.Open(source))
|
using var archive = SevenZipArchive.Open(source);
|
||||||
|
using var reader = archive.ExtractAllEntries();
|
||||||
|
var options = new ExtractionOptions
|
||||||
{
|
{
|
||||||
using (var reader = archive.ExtractAllEntries())
|
ExtractFullPath = true,
|
||||||
{
|
Overwrite = overwriteExistingFiles
|
||||||
var options = new ExtractionOptions();
|
};
|
||||||
options.ExtractFullPath = true;
|
|
||||||
|
|
||||||
if (overwriteExistingFiles)
|
reader.WriteAllToDirectory(targetPath, options);
|
||||||
{
|
|
||||||
options.Overwrite = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
reader.WriteAllToDirectory(targetPath, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -150,10 +131,8 @@ namespace Emby.Server.Implementations.Archiving
|
||||||
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
|
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
|
||||||
public void ExtractAllFromTar(string sourceFile, string targetPath, bool overwriteExistingFiles)
|
public void ExtractAllFromTar(string sourceFile, string targetPath, bool overwriteExistingFiles)
|
||||||
{
|
{
|
||||||
using (var fileStream = File.OpenRead(sourceFile))
|
using var fileStream = File.OpenRead(sourceFile);
|
||||||
{
|
ExtractAllFromTar(fileStream, targetPath, overwriteExistingFiles);
|
||||||
ExtractAllFromTar(fileStream, targetPath, overwriteExistingFiles);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -164,21 +143,15 @@ namespace Emby.Server.Implementations.Archiving
|
||||||
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
|
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
|
||||||
public void ExtractAllFromTar(Stream source, string targetPath, bool overwriteExistingFiles)
|
public void ExtractAllFromTar(Stream source, string targetPath, bool overwriteExistingFiles)
|
||||||
{
|
{
|
||||||
using (var archive = TarArchive.Open(source))
|
using var archive = TarArchive.Open(source);
|
||||||
|
using var reader = archive.ExtractAllEntries();
|
||||||
|
var options = new ExtractionOptions
|
||||||
{
|
{
|
||||||
using (var reader = archive.ExtractAllEntries())
|
ExtractFullPath = true,
|
||||||
{
|
Overwrite = overwriteExistingFiles
|
||||||
var options = new ExtractionOptions();
|
};
|
||||||
options.ExtractFullPath = true;
|
|
||||||
|
|
||||||
if (overwriteExistingFiles)
|
reader.WriteAllToDirectory(targetPath, options);
|
||||||
{
|
|
||||||
options.Overwrite = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
reader.WriteAllToDirectory(targetPath, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Model.Branding;
|
using MediaBrowser.Model.Branding;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Branding
|
namespace Emby.Server.Implementations.Branding
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A configuration factory for <see cref="BrandingOptions"/>.
|
||||||
|
/// </summary>
|
||||||
public class BrandingConfigurationFactory : IConfigurationFactory
|
public class BrandingConfigurationFactory : IConfigurationFactory
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
public IEnumerable<ConfigurationStore> GetConfigurations()
|
public IEnumerable<ConfigurationStore> GetConfigurations()
|
||||||
{
|
{
|
||||||
return new[]
|
return new[]
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Controller.Channels;
|
using MediaBrowser.Controller.Channels;
|
||||||
|
@ -11,6 +10,9 @@ using MediaBrowser.Model.Dto;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Channels
|
namespace Emby.Server.Implementations.Channels
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A media source provider for channels.
|
||||||
|
/// </summary>
|
||||||
public class ChannelDynamicMediaSourceProvider : IMediaSourceProvider
|
public class ChannelDynamicMediaSourceProvider : IMediaSourceProvider
|
||||||
{
|
{
|
||||||
private readonly ChannelManager _channelManager;
|
private readonly ChannelManager _channelManager;
|
||||||
|
@ -27,12 +29,9 @@ namespace Emby.Server.Implementations.Channels
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task<IEnumerable<MediaSourceInfo>> GetMediaSources(BaseItem item, CancellationToken cancellationToken)
|
public Task<IEnumerable<MediaSourceInfo>> GetMediaSources(BaseItem item, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (item.SourceType == SourceType.Channel)
|
return item.SourceType == SourceType.Channel
|
||||||
{
|
? _channelManager.GetDynamicMediaSources(item, cancellationToken)
|
||||||
return _channelManager.GetDynamicMediaSources(item, cancellationToken);
|
: Task.FromResult(Enumerable.Empty<MediaSourceInfo>());
|
||||||
}
|
|
||||||
|
|
||||||
return Task.FromResult<IEnumerable<MediaSourceInfo>>(new List<MediaSourceInfo>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -11,22 +9,32 @@ using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Channels
|
namespace Emby.Server.Implementations.Channels
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An image provider for channels.
|
||||||
|
/// </summary>
|
||||||
public class ChannelImageProvider : IDynamicImageProvider, IHasItemChangeMonitor
|
public class ChannelImageProvider : IDynamicImageProvider, IHasItemChangeMonitor
|
||||||
{
|
{
|
||||||
private readonly IChannelManager _channelManager;
|
private readonly IChannelManager _channelManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ChannelImageProvider"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="channelManager">The channel manager.</param>
|
||||||
public ChannelImageProvider(IChannelManager channelManager)
|
public ChannelImageProvider(IChannelManager channelManager)
|
||||||
{
|
{
|
||||||
_channelManager = channelManager;
|
_channelManager = channelManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public string Name => "Channel Image Provider";
|
public string Name => "Channel Image Provider";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
|
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
|
||||||
{
|
{
|
||||||
return GetChannel(item).GetSupportedChannelImages();
|
return GetChannel(item).GetSupportedChannelImages();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public Task<DynamicImageResponse> GetImage(BaseItem item, ImageType type, CancellationToken cancellationToken)
|
public Task<DynamicImageResponse> GetImage(BaseItem item, ImageType type, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var channel = GetChannel(item);
|
var channel = GetChannel(item);
|
||||||
|
@ -34,6 +42,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
return channel.GetChannelImage(type, cancellationToken);
|
return channel.GetChannelImage(type, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public bool Supports(BaseItem item)
|
public bool Supports(BaseItem item)
|
||||||
{
|
{
|
||||||
return item is Channel;
|
return item is Channel;
|
||||||
|
@ -46,6 +55,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
return ((ChannelManager)_channelManager).GetChannelProvider(channel);
|
return ((ChannelManager)_channelManager).GetChannelProvider(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public bool HasChanged(BaseItem item, IDirectoryService directoryService)
|
public bool HasChanged(BaseItem item, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
return GetSupportedImages(item).Any(i => !item.HasImage(i));
|
return GetSupportedImages(item).Any(i => !item.HasImage(i));
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -29,6 +27,9 @@ using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Channels
|
namespace Emby.Server.Implementations.Channels
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The LiveTV channel manager.
|
||||||
|
/// </summary>
|
||||||
public class ChannelManager : IChannelManager
|
public class ChannelManager : IChannelManager
|
||||||
{
|
{
|
||||||
private readonly IUserManager _userManager;
|
private readonly IUserManager _userManager;
|
||||||
|
@ -45,7 +46,19 @@ namespace Emby.Server.Implementations.Channels
|
||||||
new ConcurrentDictionary<string, Tuple<DateTime, List<MediaSourceInfo>>>();
|
new ConcurrentDictionary<string, Tuple<DateTime, List<MediaSourceInfo>>>();
|
||||||
|
|
||||||
private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1);
|
private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ChannelManager"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userManager">The user manager.</param>
|
||||||
|
/// <param name="dtoService">The dto service.</param>
|
||||||
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
|
/// <param name="loggerFactory">The logger factory.</param>
|
||||||
|
/// <param name="config">The server configuration manager.</param>
|
||||||
|
/// <param name="fileSystem">The filesystem.</param>
|
||||||
|
/// <param name="userDataManager">The user data manager.</param>
|
||||||
|
/// <param name="jsonSerializer">The JSON serializer.</param>
|
||||||
|
/// <param name="providerManager">The provider manager.</param>
|
||||||
public ChannelManager(
|
public ChannelManager(
|
||||||
IUserManager userManager,
|
IUserManager userManager,
|
||||||
IDtoService dtoService,
|
IDtoService dtoService,
|
||||||
|
@ -72,11 +85,13 @@ namespace Emby.Server.Implementations.Channels
|
||||||
|
|
||||||
private static TimeSpan CacheLength => TimeSpan.FromHours(3);
|
private static TimeSpan CacheLength => TimeSpan.FromHours(3);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public void AddParts(IEnumerable<IChannel> channels)
|
public void AddParts(IEnumerable<IChannel> channels)
|
||||||
{
|
{
|
||||||
Channels = channels.ToArray();
|
Channels = channels.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public bool EnableMediaSourceDisplay(BaseItem item)
|
public bool EnableMediaSourceDisplay(BaseItem item)
|
||||||
{
|
{
|
||||||
var internalChannel = _libraryManager.GetItemById(item.ChannelId);
|
var internalChannel = _libraryManager.GetItemById(item.ChannelId);
|
||||||
|
@ -85,6 +100,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
return !(channel is IDisableMediaSourceDisplay);
|
return !(channel is IDisableMediaSourceDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public bool CanDelete(BaseItem item)
|
public bool CanDelete(BaseItem item)
|
||||||
{
|
{
|
||||||
var internalChannel = _libraryManager.GetItemById(item.ChannelId);
|
var internalChannel = _libraryManager.GetItemById(item.ChannelId);
|
||||||
|
@ -93,6 +109,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
return channel is ISupportsDelete supportsDelete && supportsDelete.CanDelete(item);
|
return channel is ISupportsDelete supportsDelete && supportsDelete.CanDelete(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public bool EnableMediaProbe(BaseItem item)
|
public bool EnableMediaProbe(BaseItem item)
|
||||||
{
|
{
|
||||||
var internalChannel = _libraryManager.GetItemById(item.ChannelId);
|
var internalChannel = _libraryManager.GetItemById(item.ChannelId);
|
||||||
|
@ -101,6 +118,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
return channel is ISupportsMediaProbe;
|
return channel is ISupportsMediaProbe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public Task DeleteItem(BaseItem item)
|
public Task DeleteItem(BaseItem item)
|
||||||
{
|
{
|
||||||
var internalChannel = _libraryManager.GetItemById(item.ChannelId);
|
var internalChannel = _libraryManager.GetItemById(item.ChannelId);
|
||||||
|
@ -127,11 +145,16 @@ namespace Emby.Server.Implementations.Channels
|
||||||
.OrderBy(i => i.Name);
|
.OrderBy(i => i.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the installed channel IDs.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>An <see cref="IEnumerable{T}"/> containing installed channel IDs.</returns>
|
||||||
public IEnumerable<Guid> GetInstalledChannelIds()
|
public IEnumerable<Guid> GetInstalledChannelIds()
|
||||||
{
|
{
|
||||||
return GetAllChannels().Select(i => GetInternalChannelId(i.Name));
|
return GetAllChannels().Select(i => GetInternalChannelId(i.Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public QueryResult<Channel> GetChannelsInternal(ChannelQuery query)
|
public QueryResult<Channel> GetChannelsInternal(ChannelQuery query)
|
||||||
{
|
{
|
||||||
var user = query.UserId.Equals(Guid.Empty)
|
var user = query.UserId.Equals(Guid.Empty)
|
||||||
|
@ -249,6 +272,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public QueryResult<BaseItemDto> GetChannels(ChannelQuery query)
|
public QueryResult<BaseItemDto> GetChannels(ChannelQuery query)
|
||||||
{
|
{
|
||||||
var user = query.UserId.Equals(Guid.Empty)
|
var user = query.UserId.Equals(Guid.Empty)
|
||||||
|
@ -271,6 +295,12 @@ namespace Emby.Server.Implementations.Channels
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Refreshes the associated channels.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="progress">The progress.</param>
|
||||||
|
/// <param name="cancellationToken">A cancellation token that can be used to cancel the operation.</param>
|
||||||
|
/// <returns>The completed task.</returns>
|
||||||
public async Task RefreshChannels(IProgress<double> progress, CancellationToken cancellationToken)
|
public async Task RefreshChannels(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var allChannelsList = GetAllChannels().ToList();
|
var allChannelsList = GetAllChannels().ToList();
|
||||||
|
@ -304,14 +334,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
|
|
||||||
private Channel GetChannelEntity(IChannel channel)
|
private Channel GetChannelEntity(IChannel channel)
|
||||||
{
|
{
|
||||||
var item = GetChannel(GetInternalChannelId(channel.Name));
|
return GetChannel(GetInternalChannelId(channel.Name)) ?? GetChannel(channel, CancellationToken.None).Result;
|
||||||
|
|
||||||
if (item == null)
|
|
||||||
{
|
|
||||||
item = GetChannel(channel, CancellationToken.None).Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<MediaSourceInfo> GetSavedMediaSources(BaseItem item)
|
private List<MediaSourceInfo> GetSavedMediaSources(BaseItem item)
|
||||||
|
@ -350,6 +373,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
_jsonSerializer.SerializeToFile(mediaSources, path);
|
_jsonSerializer.SerializeToFile(mediaSources, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public IEnumerable<MediaSourceInfo> GetStaticMediaSources(BaseItem item, CancellationToken cancellationToken)
|
public IEnumerable<MediaSourceInfo> GetStaticMediaSources(BaseItem item, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
IEnumerable<MediaSourceInfo> results = GetSavedMediaSources(item);
|
IEnumerable<MediaSourceInfo> results = GetSavedMediaSources(item);
|
||||||
|
@ -359,6 +383,12 @@ namespace Emby.Server.Implementations.Channels
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the dynamic media sources based on the provided item.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">The item.</param>
|
||||||
|
/// <param name="cancellationToken">A cancellation token that can be used to cancel the operation.</param>
|
||||||
|
/// <returns>The task representing the operation to get the media sources.</returns>
|
||||||
public async Task<IEnumerable<MediaSourceInfo>> GetDynamicMediaSources(BaseItem item, CancellationToken cancellationToken)
|
public async Task<IEnumerable<MediaSourceInfo>> GetDynamicMediaSources(BaseItem item, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var channel = GetChannel(item.ChannelId);
|
var channel = GetChannel(item.ChannelId);
|
||||||
|
@ -403,7 +433,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
|
|
||||||
private static MediaSourceInfo NormalizeMediaSource(BaseItem item, MediaSourceInfo info)
|
private static MediaSourceInfo NormalizeMediaSource(BaseItem item, MediaSourceInfo info)
|
||||||
{
|
{
|
||||||
info.RunTimeTicks = info.RunTimeTicks ?? item.RunTimeTicks;
|
info.RunTimeTicks ??= item.RunTimeTicks;
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
@ -481,31 +511,33 @@ namespace Emby.Server.Implementations.Channels
|
||||||
|
|
||||||
private static string GetOfficialRating(ChannelParentalRating rating)
|
private static string GetOfficialRating(ChannelParentalRating rating)
|
||||||
{
|
{
|
||||||
switch (rating)
|
return rating switch
|
||||||
{
|
{
|
||||||
case ChannelParentalRating.Adult:
|
ChannelParentalRating.Adult => "XXX",
|
||||||
return "XXX";
|
ChannelParentalRating.UsR => "R",
|
||||||
case ChannelParentalRating.UsR:
|
ChannelParentalRating.UsPG13 => "PG-13",
|
||||||
return "R";
|
ChannelParentalRating.UsPG => "PG",
|
||||||
case ChannelParentalRating.UsPG13:
|
_ => null
|
||||||
return "PG-13";
|
};
|
||||||
case ChannelParentalRating.UsPG:
|
|
||||||
return "PG";
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a channel with the provided Guid.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The Guid.</param>
|
||||||
|
/// <returns>The corresponding channel.</returns>
|
||||||
public Channel GetChannel(Guid id)
|
public Channel GetChannel(Guid id)
|
||||||
{
|
{
|
||||||
return _libraryManager.GetItemById(id) as Channel;
|
return _libraryManager.GetItemById(id) as Channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public Channel GetChannel(string id)
|
public Channel GetChannel(string id)
|
||||||
{
|
{
|
||||||
return _libraryManager.GetItemById(id) as Channel;
|
return _libraryManager.GetItemById(id) as Channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public ChannelFeatures[] GetAllChannelFeatures()
|
public ChannelFeatures[] GetAllChannelFeatures()
|
||||||
{
|
{
|
||||||
return _libraryManager.GetItemIds(
|
return _libraryManager.GetItemIds(
|
||||||
|
@ -516,6 +548,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
}).Select(i => GetChannelFeatures(i.ToString("N", CultureInfo.InvariantCulture))).ToArray();
|
}).Select(i => GetChannelFeatures(i.ToString("N", CultureInfo.InvariantCulture))).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public ChannelFeatures GetChannelFeatures(string id)
|
public ChannelFeatures GetChannelFeatures(string id)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(id))
|
if (string.IsNullOrEmpty(id))
|
||||||
|
@ -529,6 +562,11 @@ namespace Emby.Server.Implementations.Channels
|
||||||
return GetChannelFeaturesDto(channel, channelProvider, channelProvider.GetChannelFeatures());
|
return GetChannelFeaturesDto(channel, channelProvider, channelProvider.GetChannelFeatures());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks whether the provided Guid supports external transfer.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="channelId">The Guid.</param>
|
||||||
|
/// <returns>Whether or not the provided Guid supports external transfer.</returns>
|
||||||
public bool SupportsExternalTransfer(Guid channelId)
|
public bool SupportsExternalTransfer(Guid channelId)
|
||||||
{
|
{
|
||||||
var channelProvider = GetChannelProvider(channelId);
|
var channelProvider = GetChannelProvider(channelId);
|
||||||
|
@ -536,6 +574,13 @@ namespace Emby.Server.Implementations.Channels
|
||||||
return channelProvider.GetChannelFeatures().SupportsContentDownloading;
|
return channelProvider.GetChannelFeatures().SupportsContentDownloading;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the provided channel's supported features.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="channel">The channel.</param>
|
||||||
|
/// <param name="provider">The provider.</param>
|
||||||
|
/// <param name="features">The features.</param>
|
||||||
|
/// <returns>The supported features.</returns>
|
||||||
public ChannelFeatures GetChannelFeaturesDto(
|
public ChannelFeatures GetChannelFeaturesDto(
|
||||||
Channel channel,
|
Channel channel,
|
||||||
IChannel provider,
|
IChannel provider,
|
||||||
|
@ -570,6 +615,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
return _libraryManager.GetNewItemId("Channel " + name, typeof(Channel));
|
return _libraryManager.GetNewItemId("Channel " + name, typeof(Channel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public async Task<QueryResult<BaseItemDto>> GetLatestChannelItems(InternalItemsQuery query, CancellationToken cancellationToken)
|
public async Task<QueryResult<BaseItemDto>> GetLatestChannelItems(InternalItemsQuery query, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var internalResult = await GetLatestChannelItemsInternal(query, cancellationToken).ConfigureAwait(false);
|
var internalResult = await GetLatestChannelItemsInternal(query, cancellationToken).ConfigureAwait(false);
|
||||||
|
@ -588,6 +634,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public async Task<QueryResult<BaseItem>> GetLatestChannelItemsInternal(InternalItemsQuery query, CancellationToken cancellationToken)
|
public async Task<QueryResult<BaseItem>> GetLatestChannelItemsInternal(InternalItemsQuery query, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var channels = GetAllChannels().Where(i => i is ISupportsLatestMedia).ToArray();
|
var channels = GetAllChannels().Where(i => i is ISupportsLatestMedia).ToArray();
|
||||||
|
@ -666,6 +713,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public async Task<QueryResult<BaseItem>> GetChannelItemsInternal(InternalItemsQuery query, IProgress<double> progress, CancellationToken cancellationToken)
|
public async Task<QueryResult<BaseItem>> GetChannelItemsInternal(InternalItemsQuery query, IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Get the internal channel entity
|
// Get the internal channel entity
|
||||||
|
@ -727,6 +775,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
return _libraryManager.GetItemsResult(query);
|
return _libraryManager.GetItemsResult(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public async Task<QueryResult<BaseItemDto>> GetChannelItems(InternalItemsQuery query, CancellationToken cancellationToken)
|
public async Task<QueryResult<BaseItemDto>> GetChannelItems(InternalItemsQuery query, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var internalResult = await GetChannelItemsInternal(query, new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false);
|
var internalResult = await GetChannelItemsInternal(query, new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false);
|
||||||
|
@ -796,7 +845,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
|
|
||||||
var query = new InternalChannelItemQuery
|
var query = new InternalChannelItemQuery
|
||||||
{
|
{
|
||||||
UserId = user == null ? Guid.Empty : user.Id,
|
UserId = user?.Id ?? Guid.Empty,
|
||||||
SortBy = sortField,
|
SortBy = sortField,
|
||||||
SortDescending = sortDescending,
|
SortDescending = sortDescending,
|
||||||
FolderId = externalFolderId
|
FolderId = externalFolderId
|
||||||
|
@ -923,60 +972,32 @@ namespace Emby.Server.Implementations.Channels
|
||||||
|
|
||||||
if (info.Type == ChannelItemType.Folder)
|
if (info.Type == ChannelItemType.Folder)
|
||||||
{
|
{
|
||||||
if (info.FolderType == ChannelFolderType.MusicAlbum)
|
item = info.FolderType switch
|
||||||
{
|
{
|
||||||
item = GetItemById<MusicAlbum>(info.Id, channelProvider.Name, out isNew);
|
ChannelFolderType.MusicAlbum => GetItemById<MusicAlbum>(info.Id, channelProvider.Name, out isNew),
|
||||||
}
|
ChannelFolderType.MusicArtist => GetItemById<MusicArtist>(info.Id, channelProvider.Name, out isNew),
|
||||||
else if (info.FolderType == ChannelFolderType.MusicArtist)
|
ChannelFolderType.PhotoAlbum => GetItemById<PhotoAlbum>(info.Id, channelProvider.Name, out isNew),
|
||||||
{
|
ChannelFolderType.Series => GetItemById<Series>(info.Id, channelProvider.Name, out isNew),
|
||||||
item = GetItemById<MusicArtist>(info.Id, channelProvider.Name, out isNew);
|
ChannelFolderType.Season => GetItemById<Season>(info.Id, channelProvider.Name, out isNew),
|
||||||
}
|
_ => GetItemById<Folder>(info.Id, channelProvider.Name, out isNew)
|
||||||
else if (info.FolderType == ChannelFolderType.PhotoAlbum)
|
};
|
||||||
{
|
|
||||||
item = GetItemById<PhotoAlbum>(info.Id, channelProvider.Name, out isNew);
|
|
||||||
}
|
|
||||||
else if (info.FolderType == ChannelFolderType.Series)
|
|
||||||
{
|
|
||||||
item = GetItemById<Series>(info.Id, channelProvider.Name, out isNew);
|
|
||||||
}
|
|
||||||
else if (info.FolderType == ChannelFolderType.Season)
|
|
||||||
{
|
|
||||||
item = GetItemById<Season>(info.Id, channelProvider.Name, out isNew);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item = GetItemById<Folder>(info.Id, channelProvider.Name, out isNew);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (info.MediaType == ChannelMediaType.Audio)
|
else if (info.MediaType == ChannelMediaType.Audio)
|
||||||
{
|
{
|
||||||
if (info.ContentType == ChannelMediaContentType.Podcast)
|
item = info.ContentType == ChannelMediaContentType.Podcast
|
||||||
{
|
? GetItemById<AudioBook>(info.Id, channelProvider.Name, out isNew)
|
||||||
item = GetItemById<AudioBook>(info.Id, channelProvider.Name, out isNew);
|
: GetItemById<Audio>(info.Id, channelProvider.Name, out isNew);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item = GetItemById<Audio>(info.Id, channelProvider.Name, out isNew);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (info.ContentType == ChannelMediaContentType.Episode)
|
item = info.ContentType switch
|
||||||
{
|
{
|
||||||
item = GetItemById<Episode>(info.Id, channelProvider.Name, out isNew);
|
ChannelMediaContentType.Episode => GetItemById<Episode>(info.Id, channelProvider.Name, out isNew),
|
||||||
}
|
ChannelMediaContentType.Movie => GetItemById<Movie>(info.Id, channelProvider.Name, out isNew),
|
||||||
else if (info.ContentType == ChannelMediaContentType.Movie)
|
var x when x == ChannelMediaContentType.Trailer || info.ExtraType == ExtraType.Trailer
|
||||||
{
|
=> GetItemById<Trailer>(info.Id, channelProvider.Name, out isNew),
|
||||||
item = GetItemById<Movie>(info.Id, channelProvider.Name, out isNew);
|
_ => GetItemById<Video>(info.Id, channelProvider.Name, out isNew)
|
||||||
}
|
};
|
||||||
else if (info.ContentType == ChannelMediaContentType.Trailer || info.ExtraType == ExtraType.Trailer)
|
|
||||||
{
|
|
||||||
item = GetItemById<Trailer>(info.Id, channelProvider.Name, out isNew);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item = GetItemById<Video>(info.Id, channelProvider.Name, out isNew);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var enableMediaProbe = channelProvider is ISupportsMediaProbe;
|
var enableMediaProbe = channelProvider is ISupportsMediaProbe;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -11,12 +9,21 @@ using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Channels
|
namespace Emby.Server.Implementations.Channels
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A task to remove all non-installed channels from the database.
|
||||||
|
/// </summary>
|
||||||
public class ChannelPostScanTask
|
public class ChannelPostScanTask
|
||||||
{
|
{
|
||||||
private readonly IChannelManager _channelManager;
|
private readonly IChannelManager _channelManager;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ChannelPostScanTask"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="channelManager">The channel manager.</param>
|
||||||
|
/// <param name="logger">The logger.</param>
|
||||||
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
public ChannelPostScanTask(IChannelManager channelManager, ILogger logger, ILibraryManager libraryManager)
|
public ChannelPostScanTask(IChannelManager channelManager, ILogger logger, ILibraryManager libraryManager)
|
||||||
{
|
{
|
||||||
_channelManager = channelManager;
|
_channelManager = channelManager;
|
||||||
|
@ -24,6 +31,12 @@ namespace Emby.Server.Implementations.Channels
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs this task.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="progress">The progress.</param>
|
||||||
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
|
/// <returns>The completed task.</returns>
|
||||||
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
CleanDatabase(cancellationToken);
|
CleanDatabase(cancellationToken);
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -13,6 +11,9 @@ using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Channels
|
namespace Emby.Server.Implementations.Channels
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The "Refresh Channels" scheduled task.
|
||||||
|
/// </summary>
|
||||||
public class RefreshChannelsScheduledTask : IScheduledTask, IConfigurableScheduledTask
|
public class RefreshChannelsScheduledTask : IScheduledTask, IConfigurableScheduledTask
|
||||||
{
|
{
|
||||||
private readonly IChannelManager _channelManager;
|
private readonly IChannelManager _channelManager;
|
||||||
|
@ -20,6 +21,13 @@ namespace Emby.Server.Implementations.Channels
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly ILocalizationManager _localization;
|
private readonly ILocalizationManager _localization;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="RefreshChannelsScheduledTask"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="channelManager">The channel manager.</param>
|
||||||
|
/// <param name="logger">The logger.</param>
|
||||||
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
|
/// <param name="localization">The localization manager.</param>
|
||||||
public RefreshChannelsScheduledTask(
|
public RefreshChannelsScheduledTask(
|
||||||
IChannelManager channelManager,
|
IChannelManager channelManager,
|
||||||
ILogger<RefreshChannelsScheduledTask> logger,
|
ILogger<RefreshChannelsScheduledTask> logger,
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Emby.Server.Implementations.Images;
|
using Emby.Server.Implementations.Images;
|
||||||
|
@ -15,8 +13,18 @@ using MediaBrowser.Model.IO;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Collections
|
namespace Emby.Server.Implementations.Collections
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A collection image provider.
|
||||||
|
/// </summary>
|
||||||
public class CollectionImageProvider : BaseDynamicImageProvider<BoxSet>
|
public class CollectionImageProvider : BaseDynamicImageProvider<BoxSet>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="CollectionImageProvider"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileSystem">The filesystem.</param>
|
||||||
|
/// <param name="providerManager">The provider manager.</param>
|
||||||
|
/// <param name="applicationPaths">The application paths.</param>
|
||||||
|
/// <param name="imageProcessor">The image processor.</param>
|
||||||
public CollectionImageProvider(
|
public CollectionImageProvider(
|
||||||
IFileSystem fileSystem,
|
IFileSystem fileSystem,
|
||||||
IProviderManager providerManager,
|
IProviderManager providerManager,
|
||||||
|
@ -26,6 +34,7 @@ namespace Emby.Server.Implementations.Collections
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
protected override bool Supports(BaseItem item)
|
protected override bool Supports(BaseItem item)
|
||||||
{
|
{
|
||||||
// Right now this is the only way to prevent this image from getting created ahead of internet image providers
|
// Right now this is the only way to prevent this image from getting created ahead of internet image providers
|
||||||
|
@ -37,6 +46,7 @@ namespace Emby.Server.Implementations.Collections
|
||||||
return base.Supports(item);
|
return base.Supports(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
protected override IReadOnlyList<BaseItem> GetItemsWithImages(BaseItem item)
|
protected override IReadOnlyList<BaseItem> GetItemsWithImages(BaseItem item)
|
||||||
{
|
{
|
||||||
var playlist = (BoxSet)item;
|
var playlist = (BoxSet)item;
|
||||||
|
@ -46,13 +56,12 @@ namespace Emby.Server.Implementations.Collections
|
||||||
{
|
{
|
||||||
var subItem = i;
|
var subItem = i;
|
||||||
|
|
||||||
if (subItem is Episode episode)
|
var episode = subItem as Episode;
|
||||||
|
|
||||||
|
var series = episode?.Series;
|
||||||
|
if (series != null && series.HasImage(ImageType.Primary))
|
||||||
{
|
{
|
||||||
var series = episode.Series;
|
return series;
|
||||||
if (series != null && series.HasImage(ImageType.Primary))
|
|
||||||
{
|
|
||||||
return series;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subItem.HasImage(ImageType.Primary))
|
if (subItem.HasImage(ImageType.Primary))
|
||||||
|
@ -78,6 +87,7 @@ namespace Emby.Server.Implementations.Collections
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
protected override string CreateImage(BaseItem item, IReadOnlyCollection<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex)
|
protected override string CreateImage(BaseItem item, IReadOnlyCollection<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex)
|
||||||
{
|
{
|
||||||
return CreateSingleImage(itemsWithImages, outputPathWithoutExtension, ImageType.Primary);
|
return CreateSingleImage(itemsWithImages, outputPathWithoutExtension, ImageType.Primary);
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
@ -23,6 +21,9 @@ using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Collections
|
namespace Emby.Server.Implementations.Collections
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The collection manager.
|
||||||
|
/// </summary>
|
||||||
public class CollectionManager : ICollectionManager
|
public class CollectionManager : ICollectionManager
|
||||||
{
|
{
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
@ -33,6 +34,16 @@ namespace Emby.Server.Implementations.Collections
|
||||||
private readonly ILocalizationManager _localizationManager;
|
private readonly ILocalizationManager _localizationManager;
|
||||||
private readonly IApplicationPaths _appPaths;
|
private readonly IApplicationPaths _appPaths;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="CollectionManager"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
|
/// <param name="appPaths">The application paths.</param>
|
||||||
|
/// <param name="localizationManager">The localization manager.</param>
|
||||||
|
/// <param name="fileSystem">The filesystem.</param>
|
||||||
|
/// <param name="iLibraryMonitor">The library monitor.</param>
|
||||||
|
/// <param name="loggerFactory">The logger factory.</param>
|
||||||
|
/// <param name="providerManager">The provider manager.</param>
|
||||||
public CollectionManager(
|
public CollectionManager(
|
||||||
ILibraryManager libraryManager,
|
ILibraryManager libraryManager,
|
||||||
IApplicationPaths appPaths,
|
IApplicationPaths appPaths,
|
||||||
|
@ -51,10 +62,13 @@ namespace Emby.Server.Implementations.Collections
|
||||||
_appPaths = appPaths;
|
_appPaths = appPaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public event EventHandler<CollectionCreatedEventArgs> CollectionCreated;
|
public event EventHandler<CollectionCreatedEventArgs> CollectionCreated;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public event EventHandler<CollectionModifiedEventArgs> ItemsAddedToCollection;
|
public event EventHandler<CollectionModifiedEventArgs> ItemsAddedToCollection;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public event EventHandler<CollectionModifiedEventArgs> ItemsRemovedFromCollection;
|
public event EventHandler<CollectionModifiedEventArgs> ItemsRemovedFromCollection;
|
||||||
|
|
||||||
private IEnumerable<Folder> FindFolders(string path)
|
private IEnumerable<Folder> FindFolders(string path)
|
||||||
|
@ -116,6 +130,7 @@ namespace Emby.Server.Implementations.Collections
|
||||||
: folder.GetChildren(user, true).OfType<BoxSet>();
|
: folder.GetChildren(user, true).OfType<BoxSet>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public BoxSet CreateCollection(CollectionCreationOptions options)
|
public BoxSet CreateCollection(CollectionCreationOptions options)
|
||||||
{
|
{
|
||||||
var name = options.Name;
|
var name = options.Name;
|
||||||
|
@ -180,11 +195,13 @@ namespace Emby.Server.Implementations.Collections
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public void AddToCollection(Guid collectionId, IEnumerable<string> ids)
|
public void AddToCollection(Guid collectionId, IEnumerable<string> ids)
|
||||||
{
|
{
|
||||||
AddToCollection(collectionId, ids, true, new MetadataRefreshOptions(new DirectoryService(_fileSystem)));
|
AddToCollection(collectionId, ids, true, new MetadataRefreshOptions(new DirectoryService(_fileSystem)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public void AddToCollection(Guid collectionId, IEnumerable<Guid> ids)
|
public void AddToCollection(Guid collectionId, IEnumerable<Guid> ids)
|
||||||
{
|
{
|
||||||
AddToCollection(collectionId, ids.Select(i => i.ToString("N", CultureInfo.InvariantCulture)), true, new MetadataRefreshOptions(new DirectoryService(_fileSystem)));
|
AddToCollection(collectionId, ids.Select(i => i.ToString("N", CultureInfo.InvariantCulture)), true, new MetadataRefreshOptions(new DirectoryService(_fileSystem)));
|
||||||
|
@ -247,11 +264,13 @@ namespace Emby.Server.Implementations.Collections
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public void RemoveFromCollection(Guid collectionId, IEnumerable<string> itemIds)
|
public void RemoveFromCollection(Guid collectionId, IEnumerable<string> itemIds)
|
||||||
{
|
{
|
||||||
RemoveFromCollection(collectionId, itemIds.Select(i => new Guid(i)));
|
RemoveFromCollection(collectionId, itemIds.Select(i => new Guid(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public void RemoveFromCollection(Guid collectionId, IEnumerable<Guid> itemIds)
|
public void RemoveFromCollection(Guid collectionId, IEnumerable<Guid> itemIds)
|
||||||
{
|
{
|
||||||
var collection = _libraryManager.GetItemById(collectionId) as BoxSet;
|
var collection = _libraryManager.GetItemById(collectionId) as BoxSet;
|
||||||
|
@ -305,6 +324,7 @@ namespace Emby.Server.Implementations.Collections
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public IEnumerable<BaseItem> CollapseItemsWithinBoxSets(IEnumerable<BaseItem> items, User user)
|
public IEnumerable<BaseItem> CollapseItemsWithinBoxSets(IEnumerable<BaseItem> items, User user)
|
||||||
{
|
{
|
||||||
var results = new Dictionary<Guid, BaseItem>();
|
var results = new Dictionary<Guid, BaseItem>();
|
||||||
|
@ -313,9 +333,7 @@ namespace Emby.Server.Implementations.Collections
|
||||||
|
|
||||||
foreach (var item in items)
|
foreach (var item in items)
|
||||||
{
|
{
|
||||||
var grouping = item as ISupportsBoxSetGrouping;
|
if (!(item is ISupportsBoxSetGrouping))
|
||||||
|
|
||||||
if (grouping == null)
|
|
||||||
{
|
{
|
||||||
results[item.Id] = item;
|
results[item.Id] = item;
|
||||||
}
|
}
|
||||||
|
@ -345,12 +363,21 @@ namespace Emby.Server.Implementations.Collections
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The collection manager entry point.
|
||||||
|
/// </summary>
|
||||||
public sealed class CollectionManagerEntryPoint : IServerEntryPoint
|
public sealed class CollectionManagerEntryPoint : IServerEntryPoint
|
||||||
{
|
{
|
||||||
private readonly CollectionManager _collectionManager;
|
private readonly CollectionManager _collectionManager;
|
||||||
private readonly IServerConfigurationManager _config;
|
private readonly IServerConfigurationManager _config;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="CollectionManagerEntryPoint"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="collectionManager">The collection manager.</param>
|
||||||
|
/// <param name="config">The server configuration manager.</param>
|
||||||
|
/// <param name="logger">The logger.</param>
|
||||||
public CollectionManagerEntryPoint(
|
public CollectionManagerEntryPoint(
|
||||||
ICollectionManager collectionManager,
|
ICollectionManager collectionManager,
|
||||||
IServerConfigurationManager config,
|
IServerConfigurationManager config,
|
||||||
|
|
|
@ -69,21 +69,16 @@ namespace Emby.Server.Implementations.Configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void UpdateMetadataPath()
|
private void UpdateMetadataPath()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(Configuration.MetadataPath))
|
((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = string.IsNullOrWhiteSpace(Configuration.MetadataPath)
|
||||||
{
|
? Path.Combine(ApplicationPaths.ProgramDataPath, "metadata")
|
||||||
((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = Path.Combine(ApplicationPaths.ProgramDataPath, "metadata");
|
: Configuration.MetadataPath;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = Configuration.MetadataPath;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Replaces the configuration.
|
/// Replaces the configuration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="newConfiguration">The new configuration.</param>
|
/// <param name="newConfiguration">The new configuration.</param>
|
||||||
/// <exception cref="DirectoryNotFoundException"></exception>
|
/// <exception cref="DirectoryNotFoundException">If the configuration path doesn't exist.</exception>
|
||||||
public override void ReplaceConfiguration(BaseApplicationConfiguration newConfiguration)
|
public override void ReplaceConfiguration(BaseApplicationConfiguration newConfiguration)
|
||||||
{
|
{
|
||||||
var newConfig = (ServerConfiguration)newConfiguration;
|
var newConfig = (ServerConfiguration)newConfiguration;
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace Emby.Server.Implementations.Cryptography
|
||||||
|
|
||||||
private RandomNumberGenerator _randomNumberGenerator;
|
private RandomNumberGenerator _randomNumberGenerator;
|
||||||
|
|
||||||
private bool _disposed = false;
|
private bool _disposed;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="CryptographyProvider"/> class.
|
/// Initializes a new instance of the <see cref="CryptographyProvider"/> class.
|
||||||
|
@ -56,15 +56,13 @@ namespace Emby.Server.Implementations.Cryptography
|
||||||
{
|
{
|
||||||
// downgrading for now as we need this library to be dotnetstandard compliant
|
// downgrading for now as we need this library to be dotnetstandard compliant
|
||||||
// with this downgrade we'll add a check to make sure we're on the downgrade method at the moment
|
// with this downgrade we'll add a check to make sure we're on the downgrade method at the moment
|
||||||
if (method == DefaultHashMethod)
|
if (method != DefaultHashMethod)
|
||||||
{
|
{
|
||||||
using (var r = new Rfc2898DeriveBytes(bytes, salt, iterations))
|
throw new CryptographicException($"Cannot currently use PBKDF2 with requested hash method: {method}");
|
||||||
{
|
|
||||||
return r.GetBytes(32);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new CryptographicException($"Cannot currently use PBKDF2 with requested hash method: {method}");
|
using var r = new Rfc2898DeriveBytes(bytes, salt, iterations);
|
||||||
|
return r.GetBytes(32);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -74,25 +72,22 @@ namespace Emby.Server.Implementations.Cryptography
|
||||||
{
|
{
|
||||||
return PBKDF2(hashMethod, bytes, salt, DefaultIterations);
|
return PBKDF2(hashMethod, bytes, salt, DefaultIterations);
|
||||||
}
|
}
|
||||||
else if (_supportedHashMethods.Contains(hashMethod))
|
|
||||||
|
if (!_supportedHashMethods.Contains(hashMethod))
|
||||||
{
|
{
|
||||||
using (var h = HashAlgorithm.Create(hashMethod))
|
throw new CryptographicException($"Requested hash method is not supported: {hashMethod}");
|
||||||
{
|
|
||||||
if (salt.Length == 0)
|
|
||||||
{
|
|
||||||
return h.ComputeHash(bytes);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
byte[] salted = new byte[bytes.Length + salt.Length];
|
|
||||||
Array.Copy(bytes, salted, bytes.Length);
|
|
||||||
Array.Copy(salt, 0, salted, bytes.Length, salt.Length);
|
|
||||||
return h.ComputeHash(salted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new CryptographicException($"Requested hash method is not supported: {hashMethod}");
|
using var h = HashAlgorithm.Create(hashMethod);
|
||||||
|
if (salt.Length == 0)
|
||||||
|
{
|
||||||
|
return h.ComputeHash(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] salted = new byte[bytes.Length + salt.Length];
|
||||||
|
Array.Copy(bytes, salted, bytes.Length);
|
||||||
|
Array.Copy(salt, 0, salted, bytes.Length, salt.Length);
|
||||||
|
return h.ComputeHash(salted);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
Loading…
Reference in New Issue
Block a user