mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-05-24 02:02:29 -04:00
fixes #1001 - Support downloading
This commit is contained in:
parent
4ae6b5f675
commit
b6d59c7688
@ -226,6 +226,18 @@ namespace MediaBrowser.Api.Library
|
||||
public string TvdbId { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Items/{Id}/Download", "GET", Summary = "Downloads item media")]
|
||||
[Authenticated(Roles = "download")]
|
||||
public class GetDownload
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the id.
|
||||
/// </summary>
|
||||
/// <value>The id.</value>
|
||||
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class LibraryService
|
||||
/// </summary>
|
||||
@ -273,7 +285,7 @@ namespace MediaBrowser.Api.Library
|
||||
}
|
||||
|
||||
var dtoOptions = GetDtoOptions(request);
|
||||
|
||||
|
||||
var result = new ItemsResult
|
||||
{
|
||||
TotalRecordCount = items.Count,
|
||||
@ -289,6 +301,28 @@ namespace MediaBrowser.Api.Library
|
||||
Task.Run(() => _libraryManager.ValidateMediaLibrary(new Progress<double>(), CancellationToken.None));
|
||||
}
|
||||
|
||||
public object Get(GetDownload request)
|
||||
{
|
||||
var item = _libraryManager.GetItemById(request.Id);
|
||||
|
||||
if (!item.CanDelete())
|
||||
{
|
||||
throw new ArgumentException("Item does not support downloading");
|
||||
}
|
||||
|
||||
var headers = new Dictionary<string, string>();
|
||||
|
||||
// Quotes are valid in linux. They'll possibly cause issues here
|
||||
var filename = Path.GetFileName(item.Path).Replace("\"", string.Empty);
|
||||
headers["Content-Disposition"] = string.Format("inline; filename=\"{0}\"", filename);
|
||||
|
||||
return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
|
||||
{
|
||||
Path = item.Path,
|
||||
ResponseHeaders = headers
|
||||
});
|
||||
}
|
||||
|
||||
public object Get(GetFile request)
|
||||
{
|
||||
var item = _libraryManager.GetItemById(request.Id);
|
||||
@ -347,7 +381,7 @@ namespace MediaBrowser.Api.Library
|
||||
var dtoOptions = GetDtoOptions(request);
|
||||
|
||||
BaseItem parent = item.Parent;
|
||||
|
||||
|
||||
while (parent != null)
|
||||
{
|
||||
if (user != null)
|
||||
@ -458,23 +492,9 @@ namespace MediaBrowser.Api.Library
|
||||
var auth = _authContext.GetAuthorizationInfo(Request);
|
||||
var user = _userManager.GetUserById(auth.UserId);
|
||||
|
||||
if (item is Playlist || item is BoxSet)
|
||||
if (!item.CanDelete(user))
|
||||
{
|
||||
// For now this is allowed if user can see the playlist
|
||||
}
|
||||
else if (item is ILiveTvRecording)
|
||||
{
|
||||
if (!user.Policy.EnableLiveTvManagement)
|
||||
{
|
||||
throw new UnauthorizedAccessException();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!user.Policy.EnableContentDeletion)
|
||||
{
|
||||
throw new UnauthorizedAccessException();
|
||||
}
|
||||
throw new UnauthorizedAccessException();
|
||||
}
|
||||
|
||||
var task = _libraryManager.DeleteItem(item);
|
||||
|
@ -123,7 +123,7 @@ namespace MediaBrowser.Api.Playback
|
||||
private string GetOutputFilePath(StreamState state)
|
||||
{
|
||||
var folder = ServerConfigurationManager.ApplicationPaths.TranscodingTempPath;
|
||||
|
||||
|
||||
var outputFileExtension = GetOutputFileExtension(state);
|
||||
|
||||
var data = GetCommandLineArguments("dummy\\dummy", "dummyTranscodingId", state, false);
|
||||
@ -323,13 +323,13 @@ namespace MediaBrowser.Api.Playback
|
||||
switch (qualitySetting)
|
||||
{
|
||||
case EncodingQuality.HighSpeed:
|
||||
param += " -crf 23";
|
||||
param += " -subq 0 -crf 23";
|
||||
break;
|
||||
case EncodingQuality.HighQuality:
|
||||
param += " -crf 20";
|
||||
param += " -subq 3 -crf 20";
|
||||
break;
|
||||
case EncodingQuality.MaxQuality:
|
||||
param += " -crf 18";
|
||||
param += " -subq 6 -crf 18";
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -507,7 +507,7 @@ namespace MediaBrowser.Api.Playback
|
||||
}
|
||||
}
|
||||
|
||||
return param;
|
||||
return "-pix_fmt yuv420p " + param;
|
||||
}
|
||||
|
||||
protected string GetAudioFilterParam(StreamState state, bool isHls)
|
||||
@ -918,7 +918,7 @@ namespace MediaBrowser.Api.Playback
|
||||
if (SupportsThrottleWithStream)
|
||||
{
|
||||
var url = "http://localhost:" + ServerConfigurationManager.Configuration.HttpServerPortNumber.ToString(UsCulture) + "/videos/" + state.Request.Id + "/stream?static=true&Throttle=true&mediaSourceId=" + state.Request.MediaSourceId;
|
||||
|
||||
|
||||
url += "&transcodingJobId=" + transcodingJobId;
|
||||
|
||||
return string.Format("\"{0}\"", url);
|
||||
|
@ -97,6 +97,7 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||
|
||||
if (string.Equals(Path.GetExtension(outputPath), ".mp4", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Comparison: https://github.com/jansmolders86/mediacenterjs/blob/master/lib/transcoding/desktop.js
|
||||
format = " -f mp4 -movflags frag_keyframe+empty_moov";
|
||||
}
|
||||
|
||||
|
@ -67,5 +67,10 @@ namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
return System.IO.Path.Combine(basePath, "channels", id.ToString("N"), "metadata");
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,10 @@ using MediaBrowser.Model.Channels;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Users;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Model.Users;
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
@ -89,5 +89,10 @@ namespace MediaBrowser.Controller.Channels
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
using System;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Channels;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using MediaBrowser.Model.Users;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Users;
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
@ -76,5 +75,10 @@ namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
return System.IO.Path.Combine(basePath, "channels", ChannelId, Id.ToString("N"));
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,11 +4,11 @@ using MediaBrowser.Model.Channels;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Users;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Model.Users;
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
@ -119,5 +119,10 @@ namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
return System.IO.Path.Combine(basePath, "channels", ChannelId, Id.ToString("N"));
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,11 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The _virtual children
|
||||
/// </summary>
|
||||
|
@ -113,6 +113,13 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanDownload()
|
||||
{
|
||||
var locationType = LocationType;
|
||||
return locationType != LocationType.Remote &&
|
||||
locationType != LocationType.Virtual;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the artist.
|
||||
/// </summary>
|
||||
|
@ -1,14 +1,13 @@
|
||||
using System.Runtime.Serialization;
|
||||
using MediaBrowser.Common.Progress;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Users;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Users;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
@ -35,6 +34,11 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return !IsAccessedByName;
|
||||
}
|
||||
|
||||
protected override IEnumerable<BaseItem> ActualChildren
|
||||
{
|
||||
get
|
||||
|
@ -39,6 +39,11 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is owned item.
|
||||
/// </summary>
|
||||
|
@ -239,6 +239,38 @@ namespace MediaBrowser.Controller.Entities
|
||||
get { return this.GetImagePath(ImageType.Primary); }
|
||||
}
|
||||
|
||||
public virtual bool CanDelete()
|
||||
{
|
||||
var locationType = LocationType;
|
||||
return locationType != LocationType.Remote &&
|
||||
locationType != LocationType.Virtual;
|
||||
}
|
||||
|
||||
public virtual bool IsAuthorizedToDelete(User user)
|
||||
{
|
||||
return user.Policy.EnableContentDeletion;
|
||||
}
|
||||
|
||||
public bool CanDelete(User user)
|
||||
{
|
||||
return CanDelete() && IsAuthorizedToDelete(user);
|
||||
}
|
||||
|
||||
public virtual bool CanDownload()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool IsAuthorizedToDownload(User user)
|
||||
{
|
||||
return user.Policy.EnableContentDownloading;
|
||||
}
|
||||
|
||||
public bool CanDownload(User user)
|
||||
{
|
||||
return CanDownload() && IsAuthorizedToDownload(user);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the date created.
|
||||
/// </summary>
|
||||
|
@ -11,5 +11,10 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Users;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
@ -37,6 +38,13 @@ namespace MediaBrowser.Controller.Entities
|
||||
Tags = new List<string>();
|
||||
}
|
||||
|
||||
public override bool CanDownload()
|
||||
{
|
||||
var locationType = LocationType;
|
||||
return locationType != LocationType.Remote &&
|
||||
locationType != LocationType.Virtual;
|
||||
}
|
||||
|
||||
protected override bool GetBlockUnratedValue(UserPolicy config)
|
||||
{
|
||||
return config.BlockUnratedItems.Contains(UnratedItem.Book);
|
||||
|
@ -35,6 +35,11 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public string CollectionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
@ -1,10 +1,10 @@
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Users;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.Users;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
@ -38,6 +38,13 @@ namespace MediaBrowser.Controller.Entities
|
||||
public List<Guid> LocalTrailerIds { get; set; }
|
||||
public List<Guid> RemoteTrailerIds { get; set; }
|
||||
|
||||
public override bool CanDownload()
|
||||
{
|
||||
var locationType = LocationType;
|
||||
return locationType != LocationType.Remote &&
|
||||
locationType != LocationType.Virtual;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the tags.
|
||||
/// </summary>
|
||||
|
@ -43,6 +43,11 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems)
|
||||
{
|
||||
return inputItems.Where(GetItemFilter());
|
||||
|
@ -34,6 +34,11 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is owned item.
|
||||
/// </summary>
|
||||
|
@ -15,6 +15,10 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item filter.
|
||||
/// </summary>
|
||||
/// <returns>Func<BaseItem, System.Boolean>.</returns>
|
||||
Func<BaseItem, bool> GetItemFilter();
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,11 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsAuthorizedToDelete(User user)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the trailer ids.
|
||||
/// </summary>
|
||||
|
@ -45,6 +45,11 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is owned item.
|
||||
/// </summary>
|
||||
|
@ -40,6 +40,11 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is owned item.
|
||||
/// </summary>
|
||||
|
@ -40,6 +40,11 @@ namespace MediaBrowser.Controller.Entities
|
||||
return result.Items;
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override IEnumerable<BaseItem> GetRecursiveChildren(User user, Func<BaseItem, bool> filter)
|
||||
{
|
||||
var result = GetItems(new InternalItemsQuery
|
||||
|
@ -64,6 +64,19 @@ namespace MediaBrowser.Controller.Entities
|
||||
LinkedAlternateVersions = new List<LinkedChild>();
|
||||
}
|
||||
|
||||
public override bool CanDownload()
|
||||
{
|
||||
if (VideoType == VideoType.HdDvd || VideoType == VideoType.Dvd ||
|
||||
VideoType == VideoType.BluRay)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var locationType = LocationType;
|
||||
return locationType != LocationType.Remote &&
|
||||
locationType != LocationType.Virtual;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsAddingToPlaylist
|
||||
{
|
||||
|
@ -34,6 +34,11 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is owned item.
|
||||
/// </summary>
|
||||
|
@ -25,5 +25,9 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
Task RefreshMetadata(MetadataRefreshOptions options, CancellationToken cancellationToken);
|
||||
|
||||
PlayAccess GetPlayAccess(User user);
|
||||
|
||||
bool CanDelete();
|
||||
|
||||
bool CanDelete(User user);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Runtime.Serialization;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
@ -93,5 +94,10 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
{
|
||||
return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N"));
|
||||
}
|
||||
|
||||
public override bool IsAuthorizedToDelete(User user)
|
||||
{
|
||||
return user.Policy.EnableLiveTvManagement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System.Runtime.Serialization;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
@ -8,6 +7,7 @@ using MediaBrowser.Model.MediaInfo;
|
||||
using MediaBrowser.Model.Users;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.LiveTv
|
||||
{
|
||||
@ -135,5 +135,10 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
{
|
||||
return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N"), "metadata");
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
using System.Runtime.Serialization;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.LiveTv;
|
||||
using MediaBrowser.Model.Users;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.Users;
|
||||
|
||||
namespace MediaBrowser.Controller.LiveTv
|
||||
{
|
||||
@ -215,5 +215,10 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
{
|
||||
return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N"));
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,5 +92,10 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
{
|
||||
return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N"));
|
||||
}
|
||||
|
||||
public override bool IsAuthorizedToDelete(User user)
|
||||
{
|
||||
return user.Policy.EnableLiveTvManagement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using System;
|
||||
@ -40,6 +38,11 @@ namespace MediaBrowser.Controller.Playlists
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsAuthorizedToDelete(User user)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool IsSaveLocalMetadataEnabled()
|
||||
{
|
||||
return true;
|
||||
|
@ -631,13 +631,13 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||
switch (qualitySetting)
|
||||
{
|
||||
case EncodingQuality.HighSpeed:
|
||||
param += " -crf 23";
|
||||
param += " -subq 0 -crf 23";
|
||||
break;
|
||||
case EncodingQuality.HighQuality:
|
||||
param += " -crf 20";
|
||||
param += " -subq 3 -crf 20";
|
||||
break;
|
||||
case EncodingQuality.MaxQuality:
|
||||
param += " -crf 18";
|
||||
param += " -subq 6 -crf 18";
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -740,7 +740,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||
param += " -level " + state.Options.Level.Value.ToString(UsCulture);
|
||||
}
|
||||
|
||||
return param;
|
||||
return "-pix_fmt yuv420p " + param;
|
||||
}
|
||||
|
||||
protected string GetVideoBitrateParam(EncodingJob state, string videoCodec, bool isHls)
|
||||
|
@ -56,6 +56,8 @@ namespace MediaBrowser.Model.Dto
|
||||
public int? AirsBeforeEpisodeNumber { get; set; }
|
||||
public int? AbsoluteEpisodeNumber { get; set; }
|
||||
public bool? DisplaySpecialsWithSeasons { get; set; }
|
||||
public bool? CanDelete { get; set; }
|
||||
public bool? CanDownload { get; set; }
|
||||
|
||||
public string PreferredMetadataLanguage { get; set; }
|
||||
public string PreferredMetadataCountryCode { get; set; }
|
||||
|
@ -99,6 +99,12 @@ namespace MediaBrowser.Model.LiveTv
|
||||
/// <value>The path.</value>
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance can delete.
|
||||
/// </summary>
|
||||
/// <value><c>null</c> if [can delete] contains no value, <c>true</c> if [can delete]; otherwise, <c>false</c>.</value>
|
||||
public bool? CanDelete { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Overview of the recording.
|
||||
/// </summary>
|
||||
|
@ -1,5 +1,4 @@
|
||||
|
||||
namespace MediaBrowser.Model.Querying
|
||||
namespace MediaBrowser.Model.Querying
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to control the data that gets attached to DtoBaseItems
|
||||
@ -26,6 +25,16 @@ namespace MediaBrowser.Model.Querying
|
||||
/// </summary>
|
||||
Budget,
|
||||
|
||||
/// <summary>
|
||||
/// The can delete
|
||||
/// </summary>
|
||||
CanDelete,
|
||||
|
||||
/// <summary>
|
||||
/// The can download
|
||||
/// </summary>
|
||||
CanDownload,
|
||||
|
||||
/// <summary>
|
||||
/// The chapters
|
||||
/// </summary>
|
||||
|
@ -42,7 +42,8 @@ namespace MediaBrowser.Model.Users
|
||||
|
||||
public bool EnableMediaPlayback { get; set; }
|
||||
public bool EnableContentDeletion { get; set; }
|
||||
|
||||
public bool EnableContentDownloading { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [enable synchronize].
|
||||
/// </summary>
|
||||
@ -80,6 +81,8 @@ namespace MediaBrowser.Model.Users
|
||||
|
||||
EnabledDevices = new string[] { };
|
||||
EnableAllDevices = true;
|
||||
|
||||
EnableContentDownloading = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -284,6 +284,20 @@ namespace MediaBrowser.Server.Implementations.Dto
|
||||
AttachLinkedChildImages(dto, playlist, user, options);
|
||||
}
|
||||
|
||||
if (fields.Contains(ItemFields.CanDelete))
|
||||
{
|
||||
dto.CanDelete = user == null
|
||||
? item.CanDelete()
|
||||
: item.CanDelete(user);
|
||||
}
|
||||
|
||||
if (fields.Contains(ItemFields.CanDownload))
|
||||
{
|
||||
dto.CanDownload = user == null
|
||||
? item.CanDownload()
|
||||
: item.CanDownload(user);
|
||||
}
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security
|
||||
ValidateUserAccess(user, request, authAttribtues, auth);
|
||||
}
|
||||
|
||||
if (!IsExemptFromRoles(auth, authAttribtues))
|
||||
var info = (AuthenticationInfo)request.Items["OriginalAuthenticationInfo"];
|
||||
|
||||
if (!IsExemptFromRoles(auth, authAttribtues, info))
|
||||
{
|
||||
var roles = authAttribtues.GetRoles().ToList();
|
||||
|
||||
@ -142,7 +144,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security
|
||||
StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private bool IsExemptFromRoles(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues)
|
||||
private bool IsExemptFromRoles(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues, AuthenticationInfo tokenInfo)
|
||||
{
|
||||
if (!_config.Configuration.IsStartupWizardCompleted &&
|
||||
authAttribtues.AllowBeforeStartupWizard)
|
||||
@ -150,6 +152,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security
|
||||
return true;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(auth.Token))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tokenInfo != null && string.IsNullOrWhiteSpace(tokenInfo.UserId))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -175,6 +187,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security
|
||||
};
|
||||
}
|
||||
}
|
||||
if (roles.Contains("download", StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
if (user == null || !user.Policy.EnableContentDownloading)
|
||||
{
|
||||
throw new SecurityException("User does not have download access.")
|
||||
{
|
||||
SecurityExceptionType = SecurityExceptionType.Unauthenticated
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsValidConnectKey(string token)
|
||||
|
@ -229,6 +229,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
ServerId = _appHost.SystemId
|
||||
};
|
||||
|
||||
dto.CanDelete = user == null
|
||||
? recording.CanDelete()
|
||||
: recording.CanDelete(user);
|
||||
|
||||
dto.MediaStreams = dto.MediaSources.SelectMany(i => i.MediaStreams).ToList();
|
||||
|
||||
if (info.Status == RecordingStatus.InProgress)
|
||||
|
@ -48,6 +48,7 @@
|
||||
"LabelFailed": "(failed)",
|
||||
"ButtonHelp": "Help",
|
||||
"ButtonSave": "Save",
|
||||
"ButtonDownload": "Download",
|
||||
"SyncJobStatusQueued": "Queued",
|
||||
"SyncJobStatusConverting": "Converting",
|
||||
"SyncJobStatusFailed": "Failed",
|
||||
@ -56,6 +57,7 @@
|
||||
"SyncJobStatusReadyToTransfer": "Ready to Transfer",
|
||||
"SyncJobStatusTransferring": "Transferring",
|
||||
"SyncJobStatusCompletedWithError": "Synced with errors",
|
||||
"SyncJobItemStatusReadyToTransfer": "Ready to Transfer",
|
||||
"LabelCollection": "Collection",
|
||||
"HeaderAddToCollection": "Add to Collection",
|
||||
"NewCollectionNameExample": "Example: Star Wars Collection",
|
||||
|
@ -285,10 +285,10 @@
|
||||
"ButtonHelp": "Help",
|
||||
"OptionAllowUserToManageServer": "Allow this user to manage the server",
|
||||
"HeaderFeatureAccess": "Feature Access",
|
||||
"OptionAllowMediaPlayback": "Allow media playback",
|
||||
"OptionAllowBrowsingLiveTv": "Allow browsing of live tv",
|
||||
"OptionAllowDeleteLibraryContent": "Allow deletion of library content",
|
||||
"OptionAllowManageLiveTv": "Allow management of live tv recordings",
|
||||
"OptionAllowMediaPlayback": "Media playback",
|
||||
"OptionAllowBrowsingLiveTv": "Live TV",
|
||||
"OptionAllowDeleteLibraryContent": "Media deletion",
|
||||
"OptionAllowManageLiveTv": "Live TV recording management",
|
||||
"OptionAllowRemoteControlOthers": "Allow remote control of other users",
|
||||
"OptionAllowRemoteSharedDevices": "Allow remote control of shared devices",
|
||||
"OptionAllowRemoteSharedDevicesHelp": "Dlna devices are considered shared until a user begins controlling it.",
|
||||
@ -1133,7 +1133,7 @@
|
||||
"ViewTypeLiveTvRecordingGroups": "Recordings",
|
||||
"ViewTypeLiveTvChannels": "Channels",
|
||||
"LabelEasyPinCode": "Easy pin code:",
|
||||
"EasyPasswordHelp": "Your easy pin code is used for offline access with supported Media Browser apps, and can also be used for easy in-network sign in.",
|
||||
"EasyPasswordHelp": "Your easy pin code is used for offline access with supported Media Browser apps, and can also be used for easy in-network sign in.",
|
||||
"LabelInNetworkSignInWithEasyPassword": "Enable in-network sign in with my easy pin code",
|
||||
"LabelInNetworkSignInWithEasyPasswordHelp": "If enabled, you'll be able to use your easy pin code to sign in to Media Browser apps from inside your home network. Your regular password will only be needed away from home. If the pin code is left blank, you won't need a password within your home network.",
|
||||
"HeaderPassword": "Password",
|
||||
@ -1362,7 +1362,8 @@
|
||||
"LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
|
||||
"TabActivity": "Activity",
|
||||
"TitleSync": "Sync",
|
||||
"OptionAllowSyncContent": "Allow syncing media to devices",
|
||||
"OptionAllowSyncContent": "Sync",
|
||||
"OptionAllowContentDownloading": "Media downloading",
|
||||
"NameSeasonUnknown": "Season Unknown",
|
||||
"NameSeasonNumber": "Season {0}",
|
||||
"LabelNewUserNameHelp": "Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)",
|
||||
|
@ -311,8 +311,10 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||
var itemByName = item as IItemByName;
|
||||
if (itemByName != null)
|
||||
{
|
||||
var itemByNameFilter = itemByName.GetItemFilter();
|
||||
|
||||
return user.RootFolder
|
||||
.GetRecursiveChildren(user, itemByName.GetItemFilter());
|
||||
.GetRecursiveChildren(user, i => !i.IsFolder && itemByNameFilter(i));
|
||||
}
|
||||
|
||||
if (item.IsFolder)
|
||||
|
@ -414,7 +414,6 @@ namespace MediaBrowser.WebDashboard.Api
|
||||
"indexpage.js",
|
||||
"itembynamedetailpage.js",
|
||||
"itemdetailpage.js",
|
||||
"itemgallery.js",
|
||||
"itemlistpage.js",
|
||||
"librarypathmapping.js",
|
||||
"reports.js",
|
||||
|
@ -1656,9 +1656,6 @@
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="dashboard-ui\itemgallery.html">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\librarysettings.html">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
@ -1707,9 +1704,6 @@
|
||||
<Content Include="dashboard-ui\scripts\edititemmetadata.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\scripts\itemgallery.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\scripts\librarysettings.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
Loading…
x
Reference in New Issue
Block a user