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>
|
||||
|
@ -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);
|
||||
|
@ -458,24 +492,10 @@ namespace MediaBrowser.Api.Library
|
|||
var auth = _authContext.GetAuthorizationInfo(Request);
|
||||
var user = _userManager.GetUserById(auth.UserId);
|
||||
|
||||
if (item is Playlist || item is BoxSet)
|
||||
{
|
||||
// For now this is allowed if user can see the playlist
|
||||
}
|
||||
else if (item is ILiveTvRecording)
|
||||
{
|
||||
if (!user.Policy.EnableLiveTvManagement)
|
||||
if (!item.CanDelete(user))
|
||||
{
|
||||
throw new UnauthorizedAccessException();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!user.Policy.EnableContentDeletion)
|
||||
{
|
||||
throw new UnauthorizedAccessException();
|
||||
}
|
||||
}
|
||||
|
||||
var task = _libraryManager.DeleteItem(item);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,6 +42,7 @@ 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].
|
||||
|
@ -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.",
|
||||
|
@ -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…
Reference in New Issue
Block a user