aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes2
-rw-r--r--Emby.Server.Implementations/Data/SqliteItemRepository.cs2
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpListenerHost.cs20
-rw-r--r--Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs41
-rw-r--r--Jellyfin.Server/Program.cs6
-rw-r--r--MediaBrowser.Controller/LiveTv/IListingsProvider.cs5
-rw-r--r--MediaBrowser.Providers/TV/TheTVDB/TvDbClientManager.cs55
-rwxr-xr-xbump_version27
8 files changed, 85 insertions, 73 deletions
diff --git a/.gitattributes b/.gitattributes
index d78b0459d..8ae599725 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,3 +1,5 @@
* text=auto eol=lf
+*.png binary
+*.jpg binary
CONTRIBUTORS.md merge=union
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index 2f083dda4..96f90b831 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -2724,7 +2724,7 @@ namespace Emby.Server.Implementations.Data
if (elapsed >= SlowThreshold)
{
- Logger.LogWarning(
+ Logger.LogDebug(
"{Method} query time (slow): {ElapsedMs}ms. Query: {Query}",
methodName,
elapsed,
diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
index ecd35a1a8..e4f98acb9 100644
--- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -224,7 +224,7 @@ namespace Emby.Server.Implementations.HttpServer
}
}
- private async Task ErrorHandler(Exception ex, IRequest httpReq, bool logExceptionStackTrace, bool logExceptionMessage)
+ private async Task ErrorHandler(Exception ex, IRequest httpReq, bool logExceptionStackTrace)
{
try
{
@@ -234,9 +234,9 @@ namespace Emby.Server.Implementations.HttpServer
{
_logger.LogError(ex, "Error processing request");
}
- else if (logExceptionMessage)
+ else
{
- _logger.LogError(ex.Message);
+ _logger.LogError("Error processing request: {Message}", ex.Message);
}
var httpRes = httpReq.Response;
@@ -249,8 +249,10 @@ namespace Emby.Server.Implementations.HttpServer
var statusCode = GetStatusCode(ex);
httpRes.StatusCode = statusCode;
- httpRes.ContentType = "text/html";
- await httpRes.WriteAsync(NormalizeExceptionMessage(ex.Message)).ConfigureAwait(false);
+ var errContent = NormalizeExceptionMessage(ex.Message);
+ httpRes.ContentType = "text/plain";
+ httpRes.ContentLength = errContent.Length;
+ await httpRes.WriteAsync(errContent).ConfigureAwait(false);
}
catch (Exception errorEx)
{
@@ -518,22 +520,22 @@ namespace Emby.Server.Implementations.HttpServer
}
else
{
- await ErrorHandler(new FileNotFoundException(), httpReq, false, false).ConfigureAwait(false);
+ await ErrorHandler(new FileNotFoundException(), httpReq, false).ConfigureAwait(false);
}
}
catch (Exception ex) when (ex is SocketException || ex is IOException || ex is OperationCanceledException)
{
- await ErrorHandler(ex, httpReq, false, false).ConfigureAwait(false);
+ await ErrorHandler(ex, httpReq, false).ConfigureAwait(false);
}
catch (SecurityException ex)
{
- await ErrorHandler(ex, httpReq, false, true).ConfigureAwait(false);
+ await ErrorHandler(ex, httpReq, false).ConfigureAwait(false);
}
catch (Exception ex)
{
var logException = !string.Equals(ex.GetType().Name, "SocketException", StringComparison.OrdinalIgnoreCase);
- await ErrorHandler(ex, httpReq, logException, false).ConfigureAwait(false);
+ await ErrorHandler(ex, httpReq, logException).ConfigureAwait(false);
}
finally
{
diff --git a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs
index d8faceadb..6afcf567a 100644
--- a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs
+++ b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs
@@ -21,14 +21,6 @@ namespace Emby.Server.Implementations.Images
public abstract class BaseDynamicImageProvider<T> : IHasItemChangeMonitor, IForcedProvider, ICustomMetadataProvider<T>, IHasOrder
where T : BaseItem
{
- protected virtual IReadOnlyCollection<ImageType> SupportedImages { get; }
- = new ImageType[] { ImageType.Primary };
-
- protected IFileSystem FileSystem { get; private set; }
- protected IProviderManager ProviderManager { get; private set; }
- protected IApplicationPaths ApplicationPaths { get; private set; }
- protected IImageProcessor ImageProcessor { get; set; }
-
protected BaseDynamicImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor)
{
ApplicationPaths = applicationPaths;
@@ -37,6 +29,24 @@ namespace Emby.Server.Implementations.Images
ImageProcessor = imageProcessor;
}
+ protected IFileSystem FileSystem { get; }
+
+ protected IProviderManager ProviderManager { get; }
+
+ protected IApplicationPaths ApplicationPaths { get; }
+
+ protected IImageProcessor ImageProcessor { get; set; }
+
+ protected virtual IReadOnlyCollection<ImageType> SupportedImages { get; }
+ = new ImageType[] { ImageType.Primary };
+
+ /// <inheritdoc />
+ public string Name => "Dynamic Image Provider";
+
+ protected virtual int MaxImageAgeDays => 7;
+
+ public int Order => 0;
+
protected virtual bool Supports(BaseItem _) => true;
public async Task<ItemUpdateType> FetchAsync(T item, MetadataRefreshOptions options, CancellationToken cancellationToken)
@@ -85,7 +95,8 @@ namespace Emby.Server.Implementations.Images
return FetchToFileInternal(item, items, imageType, cancellationToken);
}
- protected async Task<ItemUpdateType> FetchToFileInternal(BaseItem item,
+ protected async Task<ItemUpdateType> FetchToFileInternal(
+ BaseItem item,
IReadOnlyList<BaseItem> itemsWithImages,
ImageType imageType,
CancellationToken cancellationToken)
@@ -181,8 +192,6 @@ namespace Emby.Server.Implementations.Images
return outputPath;
}
- public string Name => "Dynamic Image Provider";
-
protected virtual string CreateImage(BaseItem item,
IReadOnlyCollection<BaseItem> itemsWithImages,
string outputPathWithoutExtension,
@@ -214,8 +223,6 @@ namespace Emby.Server.Implementations.Images
throw new ArgumentException("Unexpected image type", nameof(imageType));
}
- protected virtual int MaxImageAgeDays => 7;
-
public bool HasChanged(BaseItem item, IDirectoryService directoryServicee)
{
if (!Supports(item))
@@ -263,15 +270,9 @@ namespace Emby.Server.Implementations.Images
protected virtual bool HasChangedByDate(BaseItem item, ItemImageInfo image)
{
var age = DateTime.UtcNow - image.DateModified;
- if (age.TotalDays <= MaxImageAgeDays)
- {
- return false;
- }
- return true;
+ return age.TotalDays > MaxImageAgeDays;
}
- public int Order => 0;
-
protected string CreateSingleImage(IEnumerable<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType)
{
var image = itemsWithImages
diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs
index 6f1c111c6..3ab19769a 100644
--- a/Jellyfin.Server/Program.cs
+++ b/Jellyfin.Server/Program.cs
@@ -84,6 +84,8 @@ namespace Jellyfin.Server
private static async Task StartApp(StartupOptions options)
{
+ var stopWatch = new Stopwatch();
+ stopWatch.Start();
ServerApplicationPaths appPaths = CreateApplicationPaths(options);
// $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager
@@ -168,6 +170,10 @@ namespace Jellyfin.Server
await appHost.RunStartupTasksAsync().ConfigureAwait(false);
+ stopWatch.Stop();
+
+ _logger.LogInformation("Startup complete {Time:g}", stopWatch.Elapsed);
+
// Block main thread until shutdown
await Task.Delay(-1, _tokenSource.Token).ConfigureAwait(false);
}
diff --git a/MediaBrowser.Controller/LiveTv/IListingsProvider.cs b/MediaBrowser.Controller/LiveTv/IListingsProvider.cs
index c719ad81c..2ea0a748e 100644
--- a/MediaBrowser.Controller/LiveTv/IListingsProvider.cs
+++ b/MediaBrowser.Controller/LiveTv/IListingsProvider.cs
@@ -10,10 +10,15 @@ namespace MediaBrowser.Controller.LiveTv
public interface IListingsProvider
{
string Name { get; }
+
string Type { get; }
+
Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken);
+
Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings);
+
Task<List<NameIdPair>> GetLineups(ListingsProviderInfo info, string country, string location);
+
Task<List<ChannelInfo>> GetChannels(ListingsProviderInfo info, CancellationToken cancellationToken);
}
}
diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvDbClientManager.cs b/MediaBrowser.Providers/TV/TheTVDB/TvDbClientManager.cs
index 5cd0a6ab8..4abe6a943 100644
--- a/MediaBrowser.Providers/TV/TheTVDB/TvDbClientManager.cs
+++ b/MediaBrowser.Providers/TV/TheTVDB/TvDbClientManager.cs
@@ -14,11 +14,12 @@ namespace MediaBrowser.Providers.TV.TheTVDB
{
public class TvDbClientManager
{
+ private const string DefaultLanguage = "en";
+
private readonly SemaphoreSlim _cacheWriteLock = new SemaphoreSlim(1, 1);
private readonly IMemoryCache _cache;
private readonly TvDbClient _tvDbClient;
private DateTime _tokenCreatedAt;
- private const string DefaultLanguage = "en";
public TvDbClientManager(IMemoryCache memoryCache)
{
@@ -102,39 +103,50 @@ namespace MediaBrowser.Providers.TV.TheTVDB
return episodes;
}
- public Task<TvDbResponse<SeriesSearchResult[]>> GetSeriesByImdbIdAsync(string imdbId, string language,
+ public Task<TvDbResponse<SeriesSearchResult[]>> GetSeriesByImdbIdAsync(
+ string imdbId,
+ string language,
CancellationToken cancellationToken)
{
var cacheKey = GenerateKey("series", imdbId, language);
return TryGetValue(cacheKey, language,() => TvDbClient.Search.SearchSeriesByImdbIdAsync(imdbId, cancellationToken));
}
- public Task<TvDbResponse<SeriesSearchResult[]>> GetSeriesByZap2ItIdAsync(string zap2ItId, string language,
+ public Task<TvDbResponse<SeriesSearchResult[]>> GetSeriesByZap2ItIdAsync(
+ string zap2ItId,
+ string language,
CancellationToken cancellationToken)
{
var cacheKey = GenerateKey("series", zap2ItId, language);
- return TryGetValue( cacheKey, language,() => TvDbClient.Search.SearchSeriesByZap2ItIdAsync(zap2ItId, cancellationToken));
+ return TryGetValue(cacheKey, language, () => TvDbClient.Search.SearchSeriesByZap2ItIdAsync(zap2ItId, cancellationToken));
}
- public Task<TvDbResponse<Actor[]>> GetActorsAsync(int tvdbId, string language,
+ public Task<TvDbResponse<Actor[]>> GetActorsAsync(
+ int tvdbId,
+ string language,
CancellationToken cancellationToken)
{
var cacheKey = GenerateKey("actors", tvdbId, language);
- return TryGetValue(cacheKey, language,() => TvDbClient.Series.GetActorsAsync(tvdbId, cancellationToken));
+ return TryGetValue(cacheKey, language, () => TvDbClient.Series.GetActorsAsync(tvdbId, cancellationToken));
}
- public Task<TvDbResponse<Image[]>> GetImagesAsync(int tvdbId, ImagesQuery imageQuery, string language,
+ public Task<TvDbResponse<Image[]>> GetImagesAsync(
+ int tvdbId,
+ ImagesQuery imageQuery,
+ string language,
CancellationToken cancellationToken)
{
var cacheKey = GenerateKey("images", tvdbId, language, imageQuery);
- return TryGetValue(cacheKey, language,() => TvDbClient.Series.GetImagesAsync(tvdbId, imageQuery, cancellationToken));
+ return TryGetValue(cacheKey, language, () => TvDbClient.Series.GetImagesAsync(tvdbId, imageQuery, cancellationToken));
}
public Task<TvDbResponse<Language[]>> GetLanguagesAsync(CancellationToken cancellationToken)
{
- return TryGetValue("languages", null,() => TvDbClient.Languages.GetAllAsync(cancellationToken));
+ return TryGetValue("languages", null, () => TvDbClient.Languages.GetAllAsync(cancellationToken));
}
- public Task<TvDbResponse<EpisodesSummary>> GetSeriesEpisodeSummaryAsync(int tvdbId, string language,
+ public Task<TvDbResponse<EpisodesSummary>> GetSeriesEpisodeSummaryAsync(
+ int tvdbId,
+ string language,
CancellationToken cancellationToken)
{
var cacheKey = GenerateKey("seriesepisodesummary", tvdbId, language);
@@ -142,8 +154,12 @@ namespace MediaBrowser.Providers.TV.TheTVDB
() => TvDbClient.Series.GetEpisodesSummaryAsync(tvdbId, cancellationToken));
}
- public Task<TvDbResponse<EpisodeRecord[]>> GetEpisodesPageAsync(int tvdbId, int page, EpisodeQuery episodeQuery,
- string language, CancellationToken cancellationToken)
+ public Task<TvDbResponse<EpisodeRecord[]>> GetEpisodesPageAsync(
+ int tvdbId,
+ int page,
+ EpisodeQuery episodeQuery,
+ string language,
+ CancellationToken cancellationToken)
{
var cacheKey = GenerateKey(language, tvdbId, episodeQuery);
@@ -151,7 +167,9 @@ namespace MediaBrowser.Providers.TV.TheTVDB
() => TvDbClient.Series.GetEpisodesAsync(tvdbId, page, episodeQuery, cancellationToken));
}
- public Task<string> GetEpisodeTvdbId(EpisodeInfo searchInfo, string language,
+ public Task<string> GetEpisodeTvdbId(
+ EpisodeInfo searchInfo,
+ string language,
CancellationToken cancellationToken)
{
searchInfo.SeriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(),
@@ -187,7 +205,9 @@ namespace MediaBrowser.Providers.TV.TheTVDB
return GetEpisodeTvdbId(Convert.ToInt32(seriesTvdbId), episodeQuery, language, cancellationToken);
}
- public async Task<string> GetEpisodeTvdbId(int seriesTvdbId, EpisodeQuery episodeQuery,
+ public async Task<string> GetEpisodeTvdbId(
+ int seriesTvdbId,
+ EpisodeQuery episodeQuery,
string language,
CancellationToken cancellationToken)
{
@@ -197,8 +217,11 @@ namespace MediaBrowser.Providers.TV.TheTVDB
return episodePage.Data.FirstOrDefault()?.Id.ToString();
}
- public Task<TvDbResponse<EpisodeRecord[]>> GetEpisodesPageAsync(int tvdbId, EpisodeQuery episodeQuery,
- string language, CancellationToken cancellationToken)
+ public Task<TvDbResponse<EpisodeRecord[]>> GetEpisodesPageAsync(
+ int tvdbId,
+ EpisodeQuery episodeQuery,
+ string language,
+ CancellationToken cancellationToken)
{
return GetEpisodesPageAsync(tvdbId, 1, episodeQuery, language, cancellationToken);
}
diff --git a/bump_version b/bump_version
index 590020864..106dd7a78 100755
--- a/bump_version
+++ b/bump_version
@@ -24,33 +24,6 @@ fi
shared_version_file="./SharedVersion.cs"
build_file="./build.yaml"
-if [[ -z $2 ]]; then
- web_branch="$( git branch 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/' )"
-else
- web_branch="$2"
-fi
-
-# Initialize submodules
-git submodule update --init --recursive
-
-# configure branch
-pushd MediaBrowser.WebDashboard/jellyfin-web
-
-if ! git diff-index --quiet HEAD --; then
- popd
- echo
- echo "ERROR: Your 'jellyfin-web' submodule working directory is not clean!"
- echo "This script will overwrite your unstaged and unpushed changes."
- echo "Please do development on 'jellyfin-web' outside of the submodule."
- exit 1
-fi
-
-git fetch --all
-git checkout origin/${web_branch}
-popd
-
-git add MediaBrowser.WebDashboard/jellyfin-web
-
new_version="$1"
# Parse the version from the AssemblyVersion