Merge pull request #1304 from jellyfin/release-10.3.z

Backmerge 10.3.1
This commit is contained in:
Bond-009 2019-04-25 07:27:37 +02:00 committed by GitHub
commit 61d7bed181
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 170 additions and 75 deletions

View File

@ -21,7 +21,7 @@ RUN apt-get update \
COPY --from=ffmpeg / / COPY --from=ffmpeg / /
COPY --from=builder /jellyfin /jellyfin COPY --from=builder /jellyfin /jellyfin
ARG JELLYFIN_WEB_VERSION=10.3.0 ARG JELLYFIN_WEB_VERSION=10.3.1
RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/v${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \ RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/v${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& rm -rf /jellyfin/jellyfin-web \ && rm -rf /jellyfin/jellyfin-web \
&& mv jellyfin-web-${JELLYFIN_WEB_VERSION} /jellyfin/jellyfin-web && mv jellyfin-web-${JELLYFIN_WEB_VERSION} /jellyfin/jellyfin-web

View File

@ -30,7 +30,7 @@ RUN apt-get update \
&& chmod 777 /cache /config /media && chmod 777 /cache /config /media
COPY --from=builder /jellyfin /jellyfin COPY --from=builder /jellyfin /jellyfin
ARG JELLYFIN_WEB_VERSION=10.3.0 ARG JELLYFIN_WEB_VERSION=10.3.1
RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/v${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \ RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/v${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& rm -rf /jellyfin/jellyfin-web \ && rm -rf /jellyfin/jellyfin-web \
&& mv jellyfin-web-${JELLYFIN_WEB_VERSION} /jellyfin/jellyfin-web && mv jellyfin-web-${JELLYFIN_WEB_VERSION} /jellyfin/jellyfin-web

View File

@ -31,7 +31,7 @@ RUN apt-get update \
&& chmod 777 /cache /config /media && chmod 777 /cache /config /media
COPY --from=builder /jellyfin /jellyfin COPY --from=builder /jellyfin /jellyfin
ARG JELLYFIN_WEB_VERSION=10.3.0 ARG JELLYFIN_WEB_VERSION=10.3.1
RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/v${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \ RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/v${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& rm -rf /jellyfin/jellyfin-web \ && rm -rf /jellyfin/jellyfin-web \
&& mv jellyfin-web-${JELLYFIN_WEB_VERSION} /jellyfin/jellyfin-web && mv jellyfin-web-${JELLYFIN_WEB_VERSION} /jellyfin/jellyfin-web

View File

@ -1146,7 +1146,7 @@ namespace Emby.Server.Implementations
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.LogError(ex, "Error loading plugin {pluginName}", plugin.GetType().FullName); Logger.LogError(ex, "Error loading plugin {PluginName}", plugin.GetType().FullName);
return null; return null;
} }
@ -1160,10 +1160,32 @@ namespace Emby.Server.Implementations
{ {
Logger.LogInformation("Loading assemblies"); Logger.LogInformation("Loading assemblies");
AllConcreteTypes = GetComposablePartAssemblies() AllConcreteTypes = GetTypes(GetComposablePartAssemblies()).ToArray();
.SelectMany(x => x.ExportedTypes) }
.Where(type => type.IsClass && !type.IsAbstract && !type.IsInterface && !type.IsGenericType)
.ToArray(); private IEnumerable<Type> GetTypes(IEnumerable<Assembly> assemblies)
{
foreach (var ass in assemblies)
{
Type[] exportedTypes;
try
{
exportedTypes = ass.GetExportedTypes();
}
catch (TypeLoadException ex)
{
Logger.LogError(ex, "Error getting exported types from {Assembly}", ass.FullName);
continue;
}
foreach (Type type in exportedTypes)
{
if (type.IsClass && !type.IsAbstract && !type.IsInterface && !type.IsGenericType)
{
yield return type;
}
}
}
} }
private CertificateInfo CertificateInfo { get; set; } private CertificateInfo CertificateInfo { get; set; }
@ -1327,8 +1349,19 @@ namespace Emby.Server.Implementations
{ {
foreach (var file in Directory.EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.AllDirectories)) foreach (var file in Directory.EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.AllDirectories))
{ {
Logger.LogInformation("Loading assembly {Path}", file); Assembly plugAss;
yield return Assembly.LoadFrom(file); try
{
plugAss = Assembly.LoadFrom(file);
}
catch (FileLoadException ex)
{
Logger.LogError(ex, "Failed to load assembly {Path}", file);
continue;
}
Logger.LogInformation("Loaded assembly {Assembly} from {Path}", plugAss.FullName, file);
yield return plugAss;
} }
} }

View File

@ -81,7 +81,7 @@ namespace Emby.Server.Implementations.Data
{ {
// If the user password is the sha1 hash of the empty string, remove it // If the user password is the sha1 hash of the empty string, remove it
if (!string.Equals(user.Password, "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", StringComparison.Ordinal) if (!string.Equals(user.Password, "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", StringComparison.Ordinal)
|| !string.Equals(user.Password, "$SHA1$DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", StringComparison.Ordinal)) && !string.Equals(user.Password, "$SHA1$DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", StringComparison.Ordinal))
{ {
continue; continue;
} }

View File

@ -67,6 +67,7 @@ namespace Emby.Server.Implementations.HttpServer
if (string.IsNullOrWhiteSpace(rangeHeader)) if (string.IsNullOrWhiteSpace(rangeHeader))
{ {
Headers[HeaderNames.ContentLength] = TotalContentLength.ToString(CultureInfo.InvariantCulture);
StatusCode = HttpStatusCode.OK; StatusCode = HttpStatusCode.OK;
} }
else else
@ -99,10 +100,13 @@ namespace Emby.Server.Implementations.HttpServer
RangeStart = requestedRange.Key; RangeStart = requestedRange.Key;
RangeLength = 1 + RangeEnd - RangeStart; RangeLength = 1 + RangeEnd - RangeStart;
// Content-Length is the length of what we're serving, not the original content
var lengthString = RangeLength.ToString(CultureInfo.InvariantCulture);
Headers[HeaderNames.ContentLength] = lengthString;
var rangeString = $"bytes {RangeStart}-{RangeEnd}/{TotalContentLength}"; var rangeString = $"bytes {RangeStart}-{RangeEnd}/{TotalContentLength}";
Headers[HeaderNames.ContentRange] = rangeString; Headers[HeaderNames.ContentRange] = rangeString;
Logger.LogInformation("Setting range response values for {0}. RangeRequest: {1} Content-Range: {2}", Path, RangeHeader, rangeString); Logger.LogInformation("Setting range response values for {0}. RangeRequest: {1} Content-Length: {2}, Content-Range: {3}", Path, RangeHeader, lengthString, rangeString);
} }
/// <summary> /// <summary>

View File

@ -626,6 +626,7 @@ namespace Emby.Server.Implementations.HttpServer
private static Task Write(IResponse response, string text) private static Task Write(IResponse response, string text)
{ {
var bOutput = Encoding.UTF8.GetBytes(text); var bOutput = Encoding.UTF8.GetBytes(text);
response.OriginalResponse.ContentLength = bOutput.Length;
return response.OutputStream.WriteAsync(bOutput, 0, bOutput.Length); return response.OutputStream.WriteAsync(bOutput, 0, bOutput.Length);
} }

View File

@ -132,7 +132,7 @@ namespace Emby.Server.Implementations.HttpServer
content = Array.Empty<byte>(); content = Array.Empty<byte>();
} }
result = new StreamWriter(content, contentType); result = new StreamWriter(content, contentType, contentLength);
} }
else else
{ {
@ -176,7 +176,7 @@ namespace Emby.Server.Implementations.HttpServer
bytes = Array.Empty<byte>(); bytes = Array.Empty<byte>();
} }
result = new StreamWriter(bytes, contentType); result = new StreamWriter(bytes, contentType, contentLength);
} }
else else
{ {
@ -335,13 +335,13 @@ namespace Emby.Server.Implementations.HttpServer
if (isHeadRequest) if (isHeadRequest)
{ {
var result = new StreamWriter(Array.Empty<byte>(), contentType); var result = new StreamWriter(Array.Empty<byte>(), contentType, contentLength);
AddResponseHeaders(result, responseHeaders); AddResponseHeaders(result, responseHeaders);
return result; return result;
} }
else else
{ {
var result = new StreamWriter(content, contentType); var result = new StreamWriter(content, contentType, contentLength);
AddResponseHeaders(result, responseHeaders); AddResponseHeaders(result, responseHeaders);
return result; return result;
} }
@ -581,6 +581,11 @@ namespace Emby.Server.Implementations.HttpServer
} }
else else
{ {
if (totalContentLength.HasValue)
{
responseHeaders["Content-Length"] = totalContentLength.Value.ToString(CultureInfo.InvariantCulture);
}
if (isHeadRequest) if (isHeadRequest)
{ {
using (stream) using (stream)

View File

@ -96,6 +96,7 @@ namespace Emby.Server.Implementations.HttpServer
RangeStart = requestedRange.Key; RangeStart = requestedRange.Key;
RangeLength = 1 + RangeEnd - RangeStart; RangeLength = 1 + RangeEnd - RangeStart;
Headers[HeaderNames.ContentLength] = RangeLength.ToString(CultureInfo.InvariantCulture);
Headers[HeaderNames.ContentRange] = $"bytes {RangeStart}-{RangeEnd}/{TotalContentLength}"; Headers[HeaderNames.ContentRange] = $"bytes {RangeStart}-{RangeEnd}/{TotalContentLength}";
if (RangeStart > 0 && SourceStream.CanSeek) if (RangeStart > 0 && SourceStream.CanSeek)

View File

@ -26,7 +26,7 @@ namespace Emby.Server.Implementations.HttpServer
public void FilterResponse(IRequest req, IResponse res, object dto) public void FilterResponse(IRequest req, IResponse res, object dto)
{ {
// Try to prevent compatibility view // Try to prevent compatibility view
res.AddHeader("Access-Control-Allow-Headers", "Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-MD5, Content-Range, Content-Type, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, X-Emby-Authorization"); res.AddHeader("Access-Control-Allow-Headers", "Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, Content-Type, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, X-Emby-Authorization");
res.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS"); res.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");
res.AddHeader("Access-Control-Allow-Origin", "*"); res.AddHeader("Access-Control-Allow-Origin", "*");
@ -58,6 +58,7 @@ namespace Emby.Server.Implementations.HttpServer
if (length > 0) if (length > 0)
{ {
res.OriginalResponse.ContentLength = length;
res.SendChunked = false; res.SendChunked = false;
} }
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -49,6 +50,13 @@ namespace Emby.Server.Implementations.HttpServer
SourceStream = source; SourceStream = source;
Headers["Content-Type"] = contentType;
if (source.CanSeek)
{
Headers[HeaderNames.ContentLength] = source.Length.ToString(CultureInfo.InvariantCulture);
}
Headers[HeaderNames.ContentType] = contentType; Headers[HeaderNames.ContentType] = contentType;
} }
@ -57,7 +65,7 @@ namespace Emby.Server.Implementations.HttpServer
/// </summary> /// </summary>
/// <param name="source">The source.</param> /// <param name="source">The source.</param>
/// <param name="contentType">Type of the content.</param> /// <param name="contentType">Type of the content.</param>
public StreamWriter(byte[] source, string contentType) public StreamWriter(byte[] source, string contentType, int contentLength)
{ {
if (string.IsNullOrEmpty(contentType)) if (string.IsNullOrEmpty(contentType))
{ {
@ -66,6 +74,7 @@ namespace Emby.Server.Implementations.HttpServer
SourceBytes = source; SourceBytes = source;
Headers[HeaderNames.ContentLength] = contentLength.ToString(CultureInfo.InvariantCulture);
Headers[HeaderNames.ContentType] = contentType; Headers[HeaderNames.ContentType] = contentType;
} }

View File

@ -43,6 +43,11 @@ namespace Emby.Server.Implementations.Services
{ {
var contentLength = bytesResponse.Length; var contentLength = bytesResponse.Length;
if (response != null)
{
response.OriginalResponse.ContentLength = contentLength;
}
if (contentLength > 0) if (contentLength > 0)
{ {
await responseStream.WriteAsync(bytesResponse, 0, contentLength, cancellationToken).ConfigureAwait(false); await responseStream.WriteAsync(bytesResponse, 0, contentLength, cancellationToken).ConfigureAwait(false);

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Text; using System.Text;
@ -20,6 +21,8 @@ namespace Emby.Server.Implementations.Services
{ {
response.StatusCode = (int)HttpStatusCode.NoContent; response.StatusCode = (int)HttpStatusCode.NoContent;
} }
response.OriginalResponse.ContentLength = 0;
return Task.CompletedTask; return Task.CompletedTask;
} }
@ -39,11 +42,6 @@ namespace Emby.Server.Implementations.Services
response.StatusCode = httpResult.Status; response.StatusCode = httpResult.Status;
response.StatusDescription = httpResult.StatusCode.ToString(); response.StatusDescription = httpResult.StatusCode.ToString();
//if (string.IsNullOrEmpty(httpResult.ContentType))
//{
// httpResult.ContentType = defaultContentType;
//}
//response.ContentType = httpResult.ContentType;
} }
var responseOptions = result as IHasHeaders; var responseOptions = result as IHasHeaders;
@ -53,6 +51,7 @@ namespace Emby.Server.Implementations.Services
{ {
if (string.Equals(responseHeaders.Key, "Content-Length", StringComparison.OrdinalIgnoreCase)) if (string.Equals(responseHeaders.Key, "Content-Length", StringComparison.OrdinalIgnoreCase))
{ {
response.OriginalResponse.ContentLength = long.Parse(responseHeaders.Value, CultureInfo.InvariantCulture);
continue; continue;
} }
@ -72,52 +71,37 @@ namespace Emby.Server.Implementations.Services
response.ContentType += "; charset=utf-8"; response.ContentType += "; charset=utf-8";
} }
var asyncStreamWriter = result as IAsyncStreamWriter; switch (result)
if (asyncStreamWriter != null)
{ {
return asyncStreamWriter.WriteToAsync(response.OutputStream, cancellationToken); case IAsyncStreamWriter asyncStreamWriter:
} return asyncStreamWriter.WriteToAsync(response.OutputStream, cancellationToken);
case IStreamWriter streamWriter:
streamWriter.WriteTo(response.OutputStream);
return Task.CompletedTask;
case FileWriter fileWriter:
return fileWriter.WriteToAsync(response, cancellationToken);
case Stream stream:
return CopyStream(stream, response.OutputStream);
case byte[] bytes:
response.ContentType = "application/octet-stream";
response.OriginalResponse.ContentLength = bytes.Length;
var streamWriter = result as IStreamWriter; if (bytes.Length > 0)
if (streamWriter != null) {
{ return response.OutputStream.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
streamWriter.WriteTo(response.OutputStream); }
return Task.CompletedTask;
}
var fileWriter = result as FileWriter; return Task.CompletedTask;
if (fileWriter != null) case string responseText:
{ var responseTextAsBytes = Encoding.UTF8.GetBytes(responseText);
return fileWriter.WriteToAsync(response, cancellationToken); response.OriginalResponse.ContentLength = responseTextAsBytes.Length;
}
var stream = result as Stream; if (responseTextAsBytes.Length > 0)
if (stream != null) {
{ return response.OutputStream.WriteAsync(responseTextAsBytes, 0, responseTextAsBytes.Length, cancellationToken);
return CopyStream(stream, response.OutputStream); }
}
var bytes = result as byte[]; return Task.CompletedTask;
if (bytes != null)
{
response.ContentType = "application/octet-stream";
if (bytes.Length > 0)
{
return response.OutputStream.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
}
return Task.CompletedTask;
}
var responseText = result as string;
if (responseText != null)
{
bytes = Encoding.UTF8.GetBytes(responseText);
if (bytes.Length > 0)
{
return response.OutputStream.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
}
return Task.CompletedTask;
} }
return WriteObject(request, result, response); return WriteObject(request, result, response);
@ -143,14 +127,13 @@ namespace Emby.Server.Implementations.Services
ms.Position = 0; ms.Position = 0;
var contentLength = ms.Length; var contentLength = ms.Length;
response.OriginalResponse.ContentLength = contentLength;
if (contentLength > 0) if (contentLength > 0)
{ {
await ms.CopyToAsync(response.OutputStream).ConfigureAwait(false); await ms.CopyToAsync(response.OutputStream).ConfigureAwait(false);
} }
} }
//serializer(result, outputStream);
} }
} }
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -13,6 +14,7 @@ using MediaBrowser.Controller.Net;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services;
using Microsoft.Net.Http.Headers; using Microsoft.Net.Http.Headers;
namespace MediaBrowser.Api.Playback.Progressive namespace MediaBrowser.Api.Playback.Progressive
@ -279,10 +281,9 @@ namespace MediaBrowser.Api.Playback.Progressive
/// <returns>Task{System.Object}.</returns> /// <returns>Task{System.Object}.</returns>
private async Task<object> GetStaticRemoteStreamResult(StreamState state, Dictionary<string, string> responseHeaders, bool isHeadRequest, CancellationTokenSource cancellationTokenSource) private async Task<object> GetStaticRemoteStreamResult(StreamState state, Dictionary<string, string> responseHeaders, bool isHeadRequest, CancellationTokenSource cancellationTokenSource)
{ {
string useragent = null; state.RemoteHttpHeaders.TryGetValue(HeaderNames.UserAgent, out var useragent);
state.RemoteHttpHeaders.TryGetValue("User-Agent", out useragent);
var trySupportSeek = false; const bool trySupportSeek = false;
var options = new HttpRequestOptions var options = new HttpRequestOptions
{ {
@ -317,6 +318,12 @@ namespace MediaBrowser.Api.Playback.Progressive
responseHeaders[HeaderNames.AcceptRanges] = "none"; responseHeaders[HeaderNames.AcceptRanges] = "none";
} }
// Seeing cases of -1 here
if (response.ContentLength.HasValue && response.ContentLength.Value >= 0)
{
responseHeaders[HeaderNames.ContentLength] = response.ContentLength.Value.ToString(CultureInfo.InvariantCulture);
}
if (isHeadRequest) if (isHeadRequest)
{ {
using (response) using (response)
@ -356,10 +363,31 @@ namespace MediaBrowser.Api.Playback.Progressive
var contentType = state.GetMimeType(outputPath); var contentType = state.GetMimeType(outputPath);
// TODO: The isHeadRequest is only here because ServiceStack will add Content-Length=0 to the response // TODO: The isHeadRequest is only here because ServiceStack will add Content-Length=0 to the response
var contentLength = state.EstimateContentLength || isHeadRequest ? GetEstimatedContentLength(state) : null;
if (contentLength.HasValue)
{
responseHeaders[HeaderNames.ContentLength] = contentLength.Value.ToString(CultureInfo.InvariantCulture);
}
// Headers only // Headers only
if (isHeadRequest) if (isHeadRequest)
{ {
return ResultFactory.GetResult(null, Array.Empty<byte>(), contentType, responseHeaders); var streamResult = ResultFactory.GetResult(null, Array.Empty<byte>(), contentType, responseHeaders);
if (streamResult is IHasHeaders hasHeaders)
{
if (contentLength.HasValue)
{
hasHeaders.Headers[HeaderNames.ContentLength] = contentLength.Value.ToString(CultureInfo.InvariantCulture);
}
else
{
hasHeaders.Headers.Remove(HeaderNames.ContentLength);
}
}
return streamResult;
} }
var transcodingLock = ApiEntryPoint.Instance.GetTranscodingLock(outputPath); var transcodingLock = ApiEntryPoint.Instance.GetTranscodingLock(outputPath);
@ -397,5 +425,22 @@ namespace MediaBrowser.Api.Playback.Progressive
transcodingLock.Release(); transcodingLock.Release();
} }
} }
/// <summary>
/// Gets the length of the estimated content.
/// </summary>
/// <param name="state">The state.</param>
/// <returns>System.Nullable{System.Int64}.</returns>
private long? GetEstimatedContentLength(StreamState state)
{
var totalBitrate = state.TotalOutputBitrate ?? 0;
if (totalBitrate > 0 && state.RunTimeTicks.HasValue)
{
return Convert.ToInt64(totalBitrate * TimeSpan.FromTicks(state.RunTimeTicks.Value).TotalSeconds / 8);
}
return null;
}
} }
} }

@ -1 +1 @@
Subproject commit 874b51234ee4e1f01e2e7410980a1003f316d6a2 Subproject commit 97f6808e12243bbb9b58344185511a9369913c0b

View File

@ -1,4 +1,4 @@
using System.Reflection; using System.Reflection;
[assembly: AssemblyVersion("10.3.0")] [assembly: AssemblyVersion("10.3.1")]
[assembly: AssemblyFileVersion("10.3.0")] [assembly: AssemblyFileVersion("10.3.1")]

View File

@ -1,7 +1,7 @@
--- ---
# We just wrap `build` so this is really it # We just wrap `build` so this is really it
name: "jellyfin" name: "jellyfin"
version: "10.3.0" version: "10.3.1"
packages: packages:
- debian-package-x64 - debian-package-x64
- debian-package-armhf - debian-package-armhf

View File

@ -1,3 +1,9 @@
jellyfin (10.3.1-1) unstable; urgency=medium
* New upstream version 10.3.1; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.1
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sat, 20 Apr 2019 14:24:07 -0400
jellyfin (10.3.0-1) unstable; urgency=medium jellyfin (10.3.0-1) unstable; urgency=medium
* New upstream version 10.3.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.0 * New upstream version 10.3.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.0

View File

@ -7,7 +7,7 @@
%endif %endif
Name: jellyfin Name: jellyfin
Version: 10.3.0 Version: 10.3.1
Release: 1%{?dist} Release: 1%{?dist}
Summary: The Free Software Media Browser Summary: The Free Software Media Browser
License: GPLv2 License: GPLv2
@ -140,6 +140,8 @@ fi
%systemd_postun_with_restart jellyfin.service %systemd_postun_with_restart jellyfin.service
%changelog %changelog
* Sat Apr 20 2019 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.3.1; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.1
* Fri Apr 19 2019 Jellyfin Packaging Team <packaging@jellyfin.org> * Fri Apr 19 2019 Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version 10.3.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.0 - New upstream version 10.3.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.0
* Thu Feb 28 2019 Jellyfin Packaging Team <packaging@jellyfin.org> * Thu Feb 28 2019 Jellyfin Packaging Team <packaging@jellyfin.org>