mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-11-16 02:18:54 -07:00
Merge remote-tracking branch 'upstream/master' into warning-local-metadata
This commit is contained in:
commit
a639663aa7
@ -7,6 +7,7 @@
|
|||||||
- [anthonylavado](https://github.com/anthonylavado)
|
- [anthonylavado](https://github.com/anthonylavado)
|
||||||
- [Artiume](https://github.com/Artiume)
|
- [Artiume](https://github.com/Artiume)
|
||||||
- [AThomsen](https://github.com/AThomsen)
|
- [AThomsen](https://github.com/AThomsen)
|
||||||
|
- [barronpm](https://github.com/barronpm)
|
||||||
- [bilde2910](https://github.com/bilde2910)
|
- [bilde2910](https://github.com/bilde2910)
|
||||||
- [bfayers](https://github.com/bfayers)
|
- [bfayers](https://github.com/bfayers)
|
||||||
- [BnMcG](https://github.com/BnMcG)
|
- [BnMcG](https://github.com/BnMcG)
|
||||||
@ -130,6 +131,7 @@
|
|||||||
- [XVicarious](https://github.com/XVicarious)
|
- [XVicarious](https://github.com/XVicarious)
|
||||||
- [YouKnowBlom](https://github.com/YouKnowBlom)
|
- [YouKnowBlom](https://github.com/YouKnowBlom)
|
||||||
- [KristupasSavickas](https://github.com/KristupasSavickas)
|
- [KristupasSavickas](https://github.com/KristupasSavickas)
|
||||||
|
- [Pusta](https://github.com/pusta)
|
||||||
|
|
||||||
# Emby Contributors
|
# Emby Contributors
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ namespace DvdLib.Ifo
|
|||||||
public class Cell
|
public class Cell
|
||||||
{
|
{
|
||||||
public CellPlaybackInfo PlaybackInfo { get; private set; }
|
public CellPlaybackInfo PlaybackInfo { get; private set; }
|
||||||
|
|
||||||
public CellPositionInfo PositionInfo { get; private set; }
|
public CellPositionInfo PositionInfo { get; private set; }
|
||||||
|
|
||||||
internal void ParsePlayback(BinaryReader br)
|
internal void ParsePlayback(BinaryReader br)
|
||||||
|
@ -5,7 +5,9 @@ namespace DvdLib.Ifo
|
|||||||
public class Chapter
|
public class Chapter
|
||||||
{
|
{
|
||||||
public ushort ProgramChainNumber { get; private set; }
|
public ushort ProgramChainNumber { get; private set; }
|
||||||
|
|
||||||
public ushort ProgramNumber { get; private set; }
|
public ushort ProgramNumber { get; private set; }
|
||||||
|
|
||||||
public uint ChapterNumber { get; private set; }
|
public uint ChapterNumber { get; private set; }
|
||||||
|
|
||||||
public Chapter(ushort pgcNum, ushort programNum, uint chapterNum)
|
public Chapter(ushort pgcNum, ushort programNum, uint chapterNum)
|
||||||
|
@ -22,7 +22,9 @@ namespace DvdLib.Ifo
|
|||||||
public readonly List<Cell> Cells;
|
public readonly List<Cell> Cells;
|
||||||
|
|
||||||
public DvdTime PlaybackTime { get; private set; }
|
public DvdTime PlaybackTime { get; private set; }
|
||||||
|
|
||||||
public UserOperation ProhibitedUserOperations { get; private set; }
|
public UserOperation ProhibitedUserOperations { get; private set; }
|
||||||
|
|
||||||
public byte[] AudioStreamControl { get; private set; } // 8*2 entries
|
public byte[] AudioStreamControl { get; private set; } // 8*2 entries
|
||||||
public byte[] SubpictureStreamControl { get; private set; } // 32*4 entries
|
public byte[] SubpictureStreamControl { get; private set; } // 32*4 entries
|
||||||
|
|
||||||
@ -33,9 +35,11 @@ namespace DvdLib.Ifo
|
|||||||
private ushort _goupProgramNumber;
|
private ushort _goupProgramNumber;
|
||||||
|
|
||||||
public ProgramPlaybackMode PlaybackMode { get; private set; }
|
public ProgramPlaybackMode PlaybackMode { get; private set; }
|
||||||
|
|
||||||
public uint ProgramCount { get; private set; }
|
public uint ProgramCount { get; private set; }
|
||||||
|
|
||||||
public byte StillTime { get; private set; }
|
public byte StillTime { get; private set; }
|
||||||
|
|
||||||
public byte[] Palette { get; private set; } // 16*4 entries
|
public byte[] Palette { get; private set; } // 16*4 entries
|
||||||
|
|
||||||
private ushort _commandTableOffset;
|
private ushort _commandTableOffset;
|
||||||
|
@ -8,8 +8,11 @@ namespace DvdLib.Ifo
|
|||||||
public class Title
|
public class Title
|
||||||
{
|
{
|
||||||
public uint TitleNumber { get; private set; }
|
public uint TitleNumber { get; private set; }
|
||||||
|
|
||||||
public uint AngleCount { get; private set; }
|
public uint AngleCount { get; private set; }
|
||||||
|
|
||||||
public ushort ChapterCount { get; private set; }
|
public ushort ChapterCount { get; private set; }
|
||||||
|
|
||||||
public byte VideoTitleSetNumber { get; private set; }
|
public byte VideoTitleSetNumber { get; private set; }
|
||||||
|
|
||||||
private ushort _parentalManagementMask;
|
private ushort _parentalManagementMask;
|
||||||
@ -17,6 +20,7 @@ namespace DvdLib.Ifo
|
|||||||
private uint _vtsStartSector; // relative to start of entire disk
|
private uint _vtsStartSector; // relative to start of entire disk
|
||||||
|
|
||||||
public ProgramChain EntryProgramChain { get; private set; }
|
public ProgramChain EntryProgramChain { get; private set; }
|
||||||
|
|
||||||
public readonly List<ProgramChain> ProgramChains;
|
public readonly List<ProgramChain> ProgramChains;
|
||||||
|
|
||||||
public readonly List<Chapter> Chapters;
|
public readonly List<Chapter> Chapters;
|
||||||
|
@ -4,11 +4,12 @@ using System;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Emby.Dlna.Service;
|
using Emby.Dlna.Service;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Dlna;
|
using MediaBrowser.Controller.Dlna;
|
||||||
using MediaBrowser.Controller.Drawing;
|
using MediaBrowser.Controller.Drawing;
|
||||||
using MediaBrowser.Controller.Entities;
|
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Controller.TV;
|
using MediaBrowser.Controller.TV;
|
||||||
@ -32,7 +33,8 @@ namespace Emby.Dlna.ContentDirectory
|
|||||||
private readonly IMediaEncoder _mediaEncoder;
|
private readonly IMediaEncoder _mediaEncoder;
|
||||||
private readonly ITVSeriesManager _tvSeriesManager;
|
private readonly ITVSeriesManager _tvSeriesManager;
|
||||||
|
|
||||||
public ContentDirectory(IDlnaManager dlna,
|
public ContentDirectory(
|
||||||
|
IDlnaManager dlna,
|
||||||
IUserDataManager userDataManager,
|
IUserDataManager userDataManager,
|
||||||
IImageProcessor imageProcessor,
|
IImageProcessor imageProcessor,
|
||||||
ILibraryManager libraryManager,
|
ILibraryManager libraryManager,
|
||||||
@ -131,7 +133,7 @@ namespace Emby.Dlna.ContentDirectory
|
|||||||
|
|
||||||
foreach (var user in _userManager.Users)
|
foreach (var user in _userManager.Users)
|
||||||
{
|
{
|
||||||
if (user.Policy.IsAdministrator)
|
if (user.HasPermission(PermissionKind.IsAdministrator))
|
||||||
{
|
{
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ using System.Threading;
|
|||||||
using System.Xml;
|
using System.Xml;
|
||||||
using Emby.Dlna.Didl;
|
using Emby.Dlna.Didl;
|
||||||
using Emby.Dlna.Service;
|
using Emby.Dlna.Service;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Drawing;
|
using MediaBrowser.Controller.Drawing;
|
||||||
@ -17,7 +18,6 @@ using MediaBrowser.Controller.Dto;
|
|||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
using MediaBrowser.Controller.Entities.Movies;
|
using MediaBrowser.Controller.Entities.Movies;
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.LiveTv;
|
using MediaBrowser.Controller.LiveTv;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
@ -28,6 +28,12 @@ using MediaBrowser.Model.Entities;
|
|||||||
using MediaBrowser.Model.Globalization;
|
using MediaBrowser.Model.Globalization;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Book = MediaBrowser.Controller.Entities.Book;
|
||||||
|
using Episode = MediaBrowser.Controller.Entities.TV.Episode;
|
||||||
|
using Genre = MediaBrowser.Controller.Entities.Genre;
|
||||||
|
using Movie = MediaBrowser.Controller.Entities.Movies.Movie;
|
||||||
|
using MusicAlbum = MediaBrowser.Controller.Entities.Audio.MusicAlbum;
|
||||||
|
using Series = MediaBrowser.Controller.Entities.TV.Series;
|
||||||
|
|
||||||
namespace Emby.Dlna.ContentDirectory
|
namespace Emby.Dlna.ContentDirectory
|
||||||
{
|
{
|
||||||
@ -460,12 +466,12 @@ namespace Emby.Dlna.ContentDirectory
|
|||||||
}
|
}
|
||||||
else if (search.SearchType == SearchType.Playlist)
|
else if (search.SearchType == SearchType.Playlist)
|
||||||
{
|
{
|
||||||
//items = items.OfType<Playlist>();
|
// items = items.OfType<Playlist>();
|
||||||
isFolder = true;
|
isFolder = true;
|
||||||
}
|
}
|
||||||
else if (search.SearchType == SearchType.MusicAlbum)
|
else if (search.SearchType == SearchType.MusicAlbum)
|
||||||
{
|
{
|
||||||
//items = items.OfType<MusicAlbum>();
|
// items = items.OfType<MusicAlbum>();
|
||||||
isFolder = true;
|
isFolder = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -731,7 +737,7 @@ namespace Emby.Dlna.ContentDirectory
|
|||||||
return GetGenres(item, user, query);
|
return GetGenres(item, user, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
var array = new ServerItem[]
|
var array = new[]
|
||||||
{
|
{
|
||||||
new ServerItem(item)
|
new ServerItem(item)
|
||||||
{
|
{
|
||||||
@ -920,7 +926,7 @@ namespace Emby.Dlna.ContentDirectory
|
|||||||
private QueryResult<ServerItem> GetMovieCollections(User user, InternalItemsQuery query)
|
private QueryResult<ServerItem> GetMovieCollections(User user, InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
query.Recursive = true;
|
query.Recursive = true;
|
||||||
//query.Parent = parent;
|
// query.Parent = parent;
|
||||||
query.SetUser(user);
|
query.SetUser(user);
|
||||||
|
|
||||||
query.IncludeItemTypes = new[] { typeof(BoxSet).Name };
|
query.IncludeItemTypes = new[] { typeof(BoxSet).Name };
|
||||||
@ -1115,7 +1121,7 @@ namespace Emby.Dlna.ContentDirectory
|
|||||||
private QueryResult<ServerItem> GetMusicPlaylists(User user, InternalItemsQuery query)
|
private QueryResult<ServerItem> GetMusicPlaylists(User user, InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
query.Parent = null;
|
query.Parent = null;
|
||||||
query.IncludeItemTypes = new[] { typeof(Playlist).Name };
|
query.IncludeItemTypes = new[] { nameof(Playlist) };
|
||||||
query.SetUser(user);
|
query.SetUser(user);
|
||||||
query.Recursive = true;
|
query.Recursive = true;
|
||||||
|
|
||||||
@ -1132,10 +1138,9 @@ namespace Emby.Dlna.ContentDirectory
|
|||||||
{
|
{
|
||||||
UserId = user.Id,
|
UserId = user.Id,
|
||||||
Limit = 50,
|
Limit = 50,
|
||||||
IncludeItemTypes = new[] { typeof(Audio).Name },
|
IncludeItemTypes = new[] { nameof(Audio) },
|
||||||
ParentId = parent == null ? Guid.Empty : parent.Id,
|
ParentId = parent?.Id ?? Guid.Empty,
|
||||||
GroupItems = true
|
GroupItems = true
|
||||||
|
|
||||||
}, query.DtoOptions).Select(i => i.Item1 ?? i.Item2.FirstOrDefault()).Where(i => i != null).ToArray();
|
}, query.DtoOptions).Select(i => i.Item1 ?? i.Item2.FirstOrDefault()).Where(i => i != null).ToArray();
|
||||||
|
|
||||||
return ToResult(items);
|
return ToResult(items);
|
||||||
@ -1150,7 +1155,6 @@ namespace Emby.Dlna.ContentDirectory
|
|||||||
Limit = query.Limit,
|
Limit = query.Limit,
|
||||||
StartIndex = query.StartIndex,
|
StartIndex = query.StartIndex,
|
||||||
UserId = query.User.Id
|
UserId = query.User.Id
|
||||||
|
|
||||||
}, new[] { parent }, query.DtoOptions);
|
}, new[] { parent }, query.DtoOptions);
|
||||||
|
|
||||||
return ToResult(result);
|
return ToResult(result);
|
||||||
@ -1167,7 +1171,6 @@ namespace Emby.Dlna.ContentDirectory
|
|||||||
IncludeItemTypes = new[] { typeof(Episode).Name },
|
IncludeItemTypes = new[] { typeof(Episode).Name },
|
||||||
ParentId = parent == null ? Guid.Empty : parent.Id,
|
ParentId = parent == null ? Guid.Empty : parent.Id,
|
||||||
GroupItems = false
|
GroupItems = false
|
||||||
|
|
||||||
}, query.DtoOptions).Select(i => i.Item1 ?? i.Item2.FirstOrDefault()).Where(i => i != null).ToArray();
|
}, query.DtoOptions).Select(i => i.Item1 ?? i.Item2.FirstOrDefault()).Where(i => i != null).ToArray();
|
||||||
|
|
||||||
return ToResult(items);
|
return ToResult(items);
|
||||||
@ -1177,14 +1180,14 @@ namespace Emby.Dlna.ContentDirectory
|
|||||||
{
|
{
|
||||||
query.OrderBy = Array.Empty<(string, SortOrder)>();
|
query.OrderBy = Array.Empty<(string, SortOrder)>();
|
||||||
|
|
||||||
var items = _userViewManager.GetLatestItems(new LatestItemsQuery
|
var items = _userViewManager.GetLatestItems(
|
||||||
|
new LatestItemsQuery
|
||||||
{
|
{
|
||||||
UserId = user.Id,
|
UserId = user.Id,
|
||||||
Limit = 50,
|
Limit = 50,
|
||||||
IncludeItemTypes = new[] { typeof(Movie).Name },
|
IncludeItemTypes = new[] { nameof(Movie) },
|
||||||
ParentId = parent == null ? Guid.Empty : parent.Id,
|
ParentId = parent?.Id ?? Guid.Empty,
|
||||||
GroupItems = true
|
GroupItems = true
|
||||||
|
|
||||||
}, query.DtoOptions).Select(i => i.Item1 ?? i.Item2.FirstOrDefault()).Where(i => i != null).ToArray();
|
}, query.DtoOptions).Select(i => i.Item1 ?? i.Item2.FirstOrDefault()).Where(i => i != null).ToArray();
|
||||||
|
|
||||||
return ToResult(items);
|
return ToResult(items);
|
||||||
@ -1217,7 +1220,11 @@ namespace Emby.Dlna.ContentDirectory
|
|||||||
Recursive = true,
|
Recursive = true,
|
||||||
ParentId = parentId,
|
ParentId = parentId,
|
||||||
GenreIds = new[] { item.Id },
|
GenreIds = new[] { item.Id },
|
||||||
IncludeItemTypes = new[] { typeof(Movie).Name, typeof(Series).Name },
|
IncludeItemTypes = new[]
|
||||||
|
{
|
||||||
|
nameof(Movie),
|
||||||
|
nameof(Series)
|
||||||
|
},
|
||||||
Limit = limit,
|
Limit = limit,
|
||||||
StartIndex = startIndex,
|
StartIndex = startIndex,
|
||||||
DtoOptions = GetDtoOptions()
|
DtoOptions = GetDtoOptions()
|
||||||
@ -1350,6 +1357,7 @@ namespace Emby.Dlna.ContentDirectory
|
|||||||
internal class ServerItem
|
internal class ServerItem
|
||||||
{
|
{
|
||||||
public BaseItem Item { get; set; }
|
public BaseItem Item { get; set; }
|
||||||
|
|
||||||
public StubType? StubType { get; set; }
|
public StubType? StubType { get; set; }
|
||||||
|
|
||||||
public ServerItem(BaseItem item)
|
public ServerItem(BaseItem item)
|
||||||
|
@ -6,14 +6,13 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using Emby.Dlna.Configuration;
|
|
||||||
using Emby.Dlna.ContentDirectory;
|
using Emby.Dlna.ContentDirectory;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
using MediaBrowser.Controller.Channels;
|
using MediaBrowser.Controller.Channels;
|
||||||
using MediaBrowser.Controller.Drawing;
|
using MediaBrowser.Controller.Drawing;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
using MediaBrowser.Controller.Entities.Movies;
|
using MediaBrowser.Controller.Entities.Movies;
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Controller.Playlists;
|
using MediaBrowser.Controller.Playlists;
|
||||||
@ -23,6 +22,13 @@ using MediaBrowser.Model.Entities;
|
|||||||
using MediaBrowser.Model.Globalization;
|
using MediaBrowser.Model.Globalization;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Episode = MediaBrowser.Controller.Entities.TV.Episode;
|
||||||
|
using Genre = MediaBrowser.Controller.Entities.Genre;
|
||||||
|
using Movie = MediaBrowser.Controller.Entities.Movies.Movie;
|
||||||
|
using MusicAlbum = MediaBrowser.Controller.Entities.Audio.MusicAlbum;
|
||||||
|
using Season = MediaBrowser.Controller.Entities.TV.Season;
|
||||||
|
using Series = MediaBrowser.Controller.Entities.TV.Series;
|
||||||
|
using XmlAttribute = MediaBrowser.Model.Dlna.XmlAttribute;
|
||||||
|
|
||||||
namespace Emby.Dlna.Didl
|
namespace Emby.Dlna.Didl
|
||||||
{
|
{
|
||||||
@ -92,21 +98,21 @@ namespace Emby.Dlna.Didl
|
|||||||
{
|
{
|
||||||
using (var writer = XmlWriter.Create(builder, settings))
|
using (var writer = XmlWriter.Create(builder, settings))
|
||||||
{
|
{
|
||||||
//writer.WriteStartDocument();
|
// writer.WriteStartDocument();
|
||||||
|
|
||||||
writer.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL);
|
writer.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL);
|
||||||
|
|
||||||
writer.WriteAttributeString("xmlns", "dc", null, NS_DC);
|
writer.WriteAttributeString("xmlns", "dc", null, NS_DC);
|
||||||
writer.WriteAttributeString("xmlns", "dlna", null, NS_DLNA);
|
writer.WriteAttributeString("xmlns", "dlna", null, NS_DLNA);
|
||||||
writer.WriteAttributeString("xmlns", "upnp", null, NS_UPNP);
|
writer.WriteAttributeString("xmlns", "upnp", null, NS_UPNP);
|
||||||
//didl.SetAttribute("xmlns:sec", NS_SEC);
|
// didl.SetAttribute("xmlns:sec", NS_SEC);
|
||||||
|
|
||||||
WriteXmlRootAttributes(_profile, writer);
|
WriteXmlRootAttributes(_profile, writer);
|
||||||
|
|
||||||
WriteItemElement(writer, item, user, context, null, deviceId, filter, streamInfo);
|
WriteItemElement(writer, item, user, context, null, deviceId, filter, streamInfo);
|
||||||
|
|
||||||
writer.WriteFullEndElement();
|
writer.WriteFullEndElement();
|
||||||
//writer.WriteEndDocument();
|
// writer.WriteEndDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.ToString();
|
return builder.ToString();
|
||||||
@ -421,7 +427,6 @@ namespace Emby.Dlna.Didl
|
|||||||
case StubType.FavoriteSeries: return _localization.GetLocalizedString("HeaderFavoriteShows");
|
case StubType.FavoriteSeries: return _localization.GetLocalizedString("HeaderFavoriteShows");
|
||||||
case StubType.FavoriteEpisodes: return _localization.GetLocalizedString("HeaderFavoriteEpisodes");
|
case StubType.FavoriteEpisodes: return _localization.GetLocalizedString("HeaderFavoriteEpisodes");
|
||||||
case StubType.Series: return _localization.GetLocalizedString("Shows");
|
case StubType.Series: return _localization.GetLocalizedString("Shows");
|
||||||
default: break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,7 +675,7 @@ namespace Emby.Dlna.Didl
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaBrowser.Model.Dlna.XmlAttribute secAttribute = null;
|
XmlAttribute secAttribute = null;
|
||||||
foreach (var attribute in _profile.XmlRootAttributes)
|
foreach (var attribute in _profile.XmlRootAttributes)
|
||||||
{
|
{
|
||||||
if (string.Equals(attribute.Name, "xmlns:sec", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(attribute.Name, "xmlns:sec", StringComparison.OrdinalIgnoreCase))
|
||||||
@ -700,13 +705,13 @@ namespace Emby.Dlna.Didl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds fields used by both items and folders
|
/// Adds fields used by both items and folders.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void AddCommonFields(BaseItem item, StubType? itemStubType, BaseItem context, XmlWriter writer, Filter filter)
|
private void AddCommonFields(BaseItem item, StubType? itemStubType, BaseItem context, XmlWriter writer, Filter filter)
|
||||||
{
|
{
|
||||||
// Don't filter on dc:title because not all devices will include it in the filter
|
// Don't filter on dc:title because not all devices will include it in the filter
|
||||||
// MediaMonkey for example won't display content without a title
|
// MediaMonkey for example won't display content without a title
|
||||||
//if (filter.Contains("dc:title"))
|
// if (filter.Contains("dc:title"))
|
||||||
{
|
{
|
||||||
AddValue(writer, "dc", "title", GetDisplayName(item, itemStubType, context), NS_DC);
|
AddValue(writer, "dc", "title", GetDisplayName(item, itemStubType, context), NS_DC);
|
||||||
}
|
}
|
||||||
@ -745,7 +750,7 @@ namespace Emby.Dlna.Didl
|
|||||||
AddValue(writer, "dc", "description", desc, NS_DC);
|
AddValue(writer, "dc", "description", desc, NS_DC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if (filter.Contains("upnp:longDescription"))
|
// if (filter.Contains("upnp:longDescription"))
|
||||||
//{
|
//{
|
||||||
// if (!string.IsNullOrWhiteSpace(item.Overview))
|
// if (!string.IsNullOrWhiteSpace(item.Overview))
|
||||||
// {
|
// {
|
||||||
@ -760,6 +765,7 @@ namespace Emby.Dlna.Didl
|
|||||||
{
|
{
|
||||||
AddValue(writer, "dc", "rating", item.OfficialRating, NS_DC);
|
AddValue(writer, "dc", "rating", item.OfficialRating, NS_DC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter.Contains("upnp:rating"))
|
if (filter.Contains("upnp:rating"))
|
||||||
{
|
{
|
||||||
AddValue(writer, "upnp", "rating", item.OfficialRating, NS_UPNP);
|
AddValue(writer, "upnp", "rating", item.OfficialRating, NS_UPNP);
|
||||||
@ -995,7 +1001,6 @@ namespace Emby.Dlna.Didl
|
|||||||
}
|
}
|
||||||
|
|
||||||
AddImageResElement(item, writer, 160, 160, "jpg", "JPEG_TN");
|
AddImageResElement(item, writer, 160, 160, "jpg", "JPEG_TN");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddImageResElement(
|
private void AddImageResElement(
|
||||||
@ -1048,10 +1053,12 @@ namespace Emby.Dlna.Didl
|
|||||||
{
|
{
|
||||||
return GetImageInfo(item, ImageType.Primary);
|
return GetImageInfo(item, ImageType.Primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.HasImage(ImageType.Thumb))
|
if (item.HasImage(ImageType.Thumb))
|
||||||
{
|
{
|
||||||
return GetImageInfo(item, ImageType.Thumb);
|
return GetImageInfo(item, ImageType.Thumb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.HasImage(ImageType.Backdrop))
|
if (item.HasImage(ImageType.Backdrop))
|
||||||
{
|
{
|
||||||
if (item is Channel)
|
if (item is Channel)
|
||||||
@ -1131,25 +1138,24 @@ namespace Emby.Dlna.Didl
|
|||||||
|
|
||||||
if (width == 0 || height == 0)
|
if (width == 0 || height == 0)
|
||||||
{
|
{
|
||||||
//_imageProcessor.GetImageSize(item, imageInfo);
|
// _imageProcessor.GetImageSize(item, imageInfo);
|
||||||
width = null;
|
width = null;
|
||||||
height = null;
|
height = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (width == -1 || height == -1)
|
else if (width == -1 || height == -1)
|
||||||
{
|
{
|
||||||
width = null;
|
width = null;
|
||||||
height = null;
|
height = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//try
|
// try
|
||||||
//{
|
//{
|
||||||
// var size = _imageProcessor.GetImageSize(imageInfo);
|
// var size = _imageProcessor.GetImageSize(imageInfo);
|
||||||
|
|
||||||
// width = size.Width;
|
// width = size.Width;
|
||||||
// height = size.Height;
|
// height = size.Height;
|
||||||
//}
|
//}
|
||||||
//catch
|
// catch
|
||||||
//{
|
//{
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
@ -12,7 +12,6 @@ namespace Emby.Dlna.Didl
|
|||||||
public Filter()
|
public Filter()
|
||||||
: this("*")
|
: this("*")
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Filter(string filter)
|
public Filter(string filter)
|
||||||
@ -26,7 +25,7 @@ namespace Emby.Dlna.Didl
|
|||||||
{
|
{
|
||||||
// Don't bother with this. Some clients (media monkey) use the filter and then don't display very well when very little data comes back.
|
// Don't bother with this. Some clients (media monkey) use the filter and then don't display very well when very little data comes back.
|
||||||
return true;
|
return true;
|
||||||
//return _all || ListHelper.ContainsIgnoreCase(_fields, field);
|
// return _all || ListHelper.ContainsIgnoreCase(_fields, field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,6 @@ namespace Emby.Dlna
|
|||||||
.Select(i => i.Item2)
|
.Select(i => i.Item2)
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceProfile GetDefaultProfile()
|
public DeviceProfile GetDefaultProfile()
|
||||||
@ -251,7 +250,7 @@ namespace Emby.Dlna
|
|||||||
return string.Equals(value, header.Value, StringComparison.OrdinalIgnoreCase);
|
return string.Equals(value, header.Value, StringComparison.OrdinalIgnoreCase);
|
||||||
case HeaderMatchType.Substring:
|
case HeaderMatchType.Substring:
|
||||||
var isMatch = value.ToString().IndexOf(header.Value, StringComparison.OrdinalIgnoreCase) != -1;
|
var isMatch = value.ToString().IndexOf(header.Value, StringComparison.OrdinalIgnoreCase) != -1;
|
||||||
//_logger.LogDebug("IsMatch-Substring value: {0} testValue: {1} isMatch: {2}", value, header.Value, isMatch);
|
// _logger.LogDebug("IsMatch-Substring value: {0} testValue: {1} isMatch: {2}", value, header.Value, isMatch);
|
||||||
return isMatch;
|
return isMatch;
|
||||||
case HeaderMatchType.Regex:
|
case HeaderMatchType.Regex:
|
||||||
return Regex.IsMatch(value, header.Value, RegexOptions.IgnoreCase);
|
return Regex.IsMatch(value, header.Value, RegexOptions.IgnoreCase);
|
||||||
@ -439,6 +438,7 @@ namespace Emby.Dlna
|
|||||||
{
|
{
|
||||||
throw new ArgumentException("Profile is missing Id");
|
throw new ArgumentException("Profile is missing Id");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(profile.Name))
|
if (string.IsNullOrEmpty(profile.Name))
|
||||||
{
|
{
|
||||||
throw new ArgumentException("Profile is missing Name");
|
throw new ArgumentException("Profile is missing Name");
|
||||||
@ -464,6 +464,7 @@ namespace Emby.Dlna
|
|||||||
{
|
{
|
||||||
_profiles[path] = new Tuple<InternalProfileInfo, DeviceProfile>(GetInternalProfileInfo(_fileSystem.GetFileInfo(path), type), profile);
|
_profiles[path] = new Tuple<InternalProfileInfo, DeviceProfile>(GetInternalProfileInfo(_fileSystem.GetFileInfo(path), type), profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
SerializeToXml(profile, path);
|
SerializeToXml(profile, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -474,7 +475,7 @@ namespace Emby.Dlna
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Recreates the object using serialization, to ensure it's not a subclass.
|
/// Recreates the object using serialization, to ensure it's not a subclass.
|
||||||
/// If it's a subclass it may not serlialize properly to xml (different root element tag name)
|
/// If it's a subclass it may not serlialize properly to xml (different root element tag name).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="profile"></param>
|
/// <param name="profile"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
@ -493,6 +494,7 @@ namespace Emby.Dlna
|
|||||||
class InternalProfileInfo
|
class InternalProfileInfo
|
||||||
{
|
{
|
||||||
internal DeviceProfileInfo Info { get; set; }
|
internal DeviceProfileInfo Info { get; set; }
|
||||||
|
|
||||||
internal string Path { get; set; }
|
internal string Path { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -566,9 +568,9 @@ namespace Emby.Dlna
|
|||||||
new Foobar2000Profile(),
|
new Foobar2000Profile(),
|
||||||
new SharpSmartTvProfile(),
|
new SharpSmartTvProfile(),
|
||||||
new MediaMonkeyProfile(),
|
new MediaMonkeyProfile(),
|
||||||
//new Windows81Profile(),
|
// new Windows81Profile(),
|
||||||
//new WindowsMediaCenterProfile(),
|
// new WindowsMediaCenterProfile(),
|
||||||
//new WindowsPhoneProfile(),
|
// new WindowsPhoneProfile(),
|
||||||
new DirectTvProfile(),
|
new DirectTvProfile(),
|
||||||
new DishHopperJoeyProfile(),
|
new DishHopperJoeyProfile(),
|
||||||
new DefaultProfile(),
|
new DefaultProfile(),
|
||||||
|
@ -31,18 +31,26 @@ namespace Emby.Dlna.Eventing
|
|||||||
public EventSubscriptionResponse RenewEventSubscription(string subscriptionId, string notificationType, string requestedTimeoutString, string callbackUrl)
|
public EventSubscriptionResponse RenewEventSubscription(string subscriptionId, string notificationType, string requestedTimeoutString, string callbackUrl)
|
||||||
{
|
{
|
||||||
var subscription = GetSubscription(subscriptionId, false);
|
var subscription = GetSubscription(subscriptionId, false);
|
||||||
|
if (subscription != null)
|
||||||
|
{
|
||||||
|
subscription.TimeoutSeconds = ParseTimeout(requestedTimeoutString) ?? 300;
|
||||||
|
int timeoutSeconds = subscription.TimeoutSeconds;
|
||||||
|
subscription.SubscriptionTime = DateTime.UtcNow;
|
||||||
|
|
||||||
subscription.TimeoutSeconds = ParseTimeout(requestedTimeoutString) ?? 300;
|
_logger.LogDebug(
|
||||||
int timeoutSeconds = subscription.TimeoutSeconds;
|
"Renewing event subscription for {0} with timeout of {1} to {2}",
|
||||||
subscription.SubscriptionTime = DateTime.UtcNow;
|
subscription.NotificationType,
|
||||||
|
timeoutSeconds,
|
||||||
|
subscription.CallbackUrl);
|
||||||
|
|
||||||
_logger.LogDebug(
|
return GetEventSubscriptionResponse(subscriptionId, requestedTimeoutString, timeoutSeconds);
|
||||||
"Renewing event subscription for {0} with timeout of {1} to {2}",
|
}
|
||||||
subscription.NotificationType,
|
|
||||||
timeoutSeconds,
|
|
||||||
subscription.CallbackUrl);
|
|
||||||
|
|
||||||
return GetEventSubscriptionResponse(subscriptionId, requestedTimeoutString, timeoutSeconds);
|
return new EventSubscriptionResponse
|
||||||
|
{
|
||||||
|
Content = string.Empty,
|
||||||
|
ContentType = "text/plain"
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public EventSubscriptionResponse CreateEventSubscription(string notificationType, string requestedTimeoutString, string callbackUrl)
|
public EventSubscriptionResponse CreateEventSubscription(string notificationType, string requestedTimeoutString, string callbackUrl)
|
||||||
@ -150,6 +158,7 @@ namespace Emby.Dlna.Eventing
|
|||||||
builder.Append("</" + key + ">");
|
builder.Append("</" + key + ">");
|
||||||
builder.Append("</e:property>");
|
builder.Append("</e:property>");
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.Append("</e:propertyset>");
|
builder.Append("</e:propertyset>");
|
||||||
|
|
||||||
var options = new HttpRequestOptions
|
var options = new HttpRequestOptions
|
||||||
@ -169,7 +178,6 @@ namespace Emby.Dlna.Eventing
|
|||||||
{
|
{
|
||||||
using (await _httpClient.SendAsync(options, new HttpMethod("NOTIFY")).ConfigureAwait(false))
|
using (await _httpClient.SendAsync(options, new HttpMethod("NOTIFY")).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
|
@ -7,10 +7,13 @@ namespace Emby.Dlna.Eventing
|
|||||||
public class EventSubscription
|
public class EventSubscription
|
||||||
{
|
{
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
|
||||||
public string CallbackUrl { get; set; }
|
public string CallbackUrl { get; set; }
|
||||||
|
|
||||||
public string NotificationType { get; set; }
|
public string NotificationType { get; set; }
|
||||||
|
|
||||||
public DateTime SubscriptionTime { get; set; }
|
public DateTime SubscriptionTime { get; set; }
|
||||||
|
|
||||||
public int TimeoutSeconds { get; set; }
|
public int TimeoutSeconds { get; set; }
|
||||||
|
|
||||||
public long TriggerCount { get; set; }
|
public long TriggerCount { get; set; }
|
||||||
|
@ -276,7 +276,7 @@ namespace Emby.Dlna.Main
|
|||||||
|
|
||||||
var device = new SsdpRootDevice
|
var device = new SsdpRootDevice
|
||||||
{
|
{
|
||||||
CacheLifetime = TimeSpan.FromSeconds(1800), //How long SSDP clients can cache this info.
|
CacheLifetime = TimeSpan.FromSeconds(1800), // How long SSDP clients can cache this info.
|
||||||
Location = uri, // Must point to the URL that serves your devices UPnP description document.
|
Location = uri, // Must point to the URL that serves your devices UPnP description document.
|
||||||
Address = address,
|
Address = address,
|
||||||
SubnetMask = _networkManager.GetLocalIpSubnetMask(address),
|
SubnetMask = _networkManager.GetLocalIpSubnetMask(address),
|
||||||
@ -320,6 +320,7 @@ namespace Emby.Dlna.Main
|
|||||||
{
|
{
|
||||||
guid = text.GetMD5();
|
guid = text.GetMD5();
|
||||||
}
|
}
|
||||||
|
|
||||||
return guid.ToString("N", CultureInfo.InvariantCulture);
|
return guid.ToString("N", CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,6 +389,7 @@ namespace Emby.Dlna.Main
|
|||||||
{
|
{
|
||||||
_logger.LogError(ex, "Error disposing PlayTo manager");
|
_logger.LogError(ex, "Error disposing PlayTo manager");
|
||||||
}
|
}
|
||||||
|
|
||||||
_manager = null;
|
_manager = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ namespace Emby.Dlna.PlayTo
|
|||||||
RefreshVolumeIfNeeded().GetAwaiter().GetResult();
|
RefreshVolumeIfNeeded().GetAwaiter().GetResult();
|
||||||
return _volume;
|
return _volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
set => _volume = value;
|
set => _volume = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +233,7 @@ namespace Emby.Dlna.PlayTo
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets volume on a scale of 0-100
|
/// Sets volume on a scale of 0-100.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task SetVolume(int value, CancellationToken cancellationToken)
|
public async Task SetVolume(int value, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
@ -494,6 +495,7 @@ namespace Emby.Dlna.PlayTo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RestartTimerInactive();
|
RestartTimerInactive();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -750,7 +752,7 @@ namespace Emby.Dlna.PlayTo
|
|||||||
|
|
||||||
if (track == null)
|
if (track == null)
|
||||||
{
|
{
|
||||||
//If track is null, some vendors do this, use GetMediaInfo instead
|
// If track is null, some vendors do this, use GetMediaInfo instead
|
||||||
return (true, null);
|
return (true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -794,7 +796,6 @@ namespace Emby.Dlna.PlayTo
|
|||||||
}
|
}
|
||||||
catch (XmlException)
|
catch (XmlException)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// first try to add a root node with a dlna namesapce
|
// first try to add a root node with a dlna namesapce
|
||||||
@ -806,7 +807,6 @@ namespace Emby.Dlna.PlayTo
|
|||||||
}
|
}
|
||||||
catch (XmlException)
|
catch (XmlException)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// some devices send back invalid xml
|
// some devices send back invalid xml
|
||||||
@ -816,7 +816,6 @@ namespace Emby.Dlna.PlayTo
|
|||||||
}
|
}
|
||||||
catch (XmlException)
|
catch (XmlException)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -7,6 +7,7 @@ using System.Linq;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Emby.Dlna.Didl;
|
using Emby.Dlna.Didl;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Controller.Dlna;
|
using MediaBrowser.Controller.Dlna;
|
||||||
using MediaBrowser.Controller.Drawing;
|
using MediaBrowser.Controller.Drawing;
|
||||||
@ -22,6 +23,7 @@ using MediaBrowser.Model.Globalization;
|
|||||||
using MediaBrowser.Model.Session;
|
using MediaBrowser.Model.Session;
|
||||||
using Microsoft.AspNetCore.WebUtilities;
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Photo = MediaBrowser.Controller.Entities.Photo;
|
||||||
|
|
||||||
namespace Emby.Dlna.PlayTo
|
namespace Emby.Dlna.PlayTo
|
||||||
{
|
{
|
||||||
@ -423,6 +425,7 @@ namespace Emby.Dlna.PlayTo
|
|||||||
await _device.SetAvTransport(newItem.StreamUrl, GetDlnaHeaders(newItem), newItem.Didl, CancellationToken.None).ConfigureAwait(false);
|
await _device.SetAvTransport(newItem.StreamUrl, GetDlnaHeaders(newItem), newItem.Didl, CancellationToken.None).ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await SeekAfterTransportChange(newPosition, CancellationToken.None).ConfigureAwait(false);
|
await SeekAfterTransportChange(newPosition, CancellationToken.None).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -446,7 +449,13 @@ namespace Emby.Dlna.PlayTo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private PlaylistItem CreatePlaylistItem(BaseItem item, User user, long startPostionTicks, string mediaSourceId, int? audioStreamIndex, int? subtitleStreamIndex)
|
private PlaylistItem CreatePlaylistItem(
|
||||||
|
BaseItem item,
|
||||||
|
User user,
|
||||||
|
long startPostionTicks,
|
||||||
|
string mediaSourceId,
|
||||||
|
int? audioStreamIndex,
|
||||||
|
int? subtitleStreamIndex)
|
||||||
{
|
{
|
||||||
var deviceInfo = _device.Properties;
|
var deviceInfo = _device.Properties;
|
||||||
|
|
||||||
@ -705,6 +714,7 @@ namespace Emby.Dlna.PlayTo
|
|||||||
|
|
||||||
throw new ArgumentException("Volume argument cannot be null");
|
throw new ArgumentException("Volume argument cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@ -790,12 +800,15 @@ namespace Emby.Dlna.PlayTo
|
|||||||
public int? SubtitleStreamIndex { get; set; }
|
public int? SubtitleStreamIndex { get; set; }
|
||||||
|
|
||||||
public string DeviceProfileId { get; set; }
|
public string DeviceProfileId { get; set; }
|
||||||
|
|
||||||
public string DeviceId { get; set; }
|
public string DeviceId { get; set; }
|
||||||
|
|
||||||
public string MediaSourceId { get; set; }
|
public string MediaSourceId { get; set; }
|
||||||
|
|
||||||
public string LiveStreamId { get; set; }
|
public string LiveStreamId { get; set; }
|
||||||
|
|
||||||
public BaseItem Item { get; set; }
|
public BaseItem Item { get; set; }
|
||||||
|
|
||||||
private MediaSourceInfo MediaSource;
|
private MediaSourceInfo MediaSource;
|
||||||
|
|
||||||
private IMediaSourceManager _mediaSourceManager;
|
private IMediaSourceManager _mediaSourceManager;
|
||||||
|
@ -88,7 +88,7 @@ namespace Emby.Dlna.PlayTo
|
|||||||
if (usn.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) == -1 &&
|
if (usn.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) == -1 &&
|
||||||
nt.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) == -1)
|
nt.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) == -1)
|
||||||
{
|
{
|
||||||
//_logger.LogDebug("Upnp device {0} does not contain a MediaRenderer device (0).", location);
|
// _logger.LogDebug("Upnp device {0} does not contain a MediaRenderer device (0).", location);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +112,6 @@ namespace Emby.Dlna.PlayTo
|
|||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -133,6 +132,7 @@ namespace Emby.Dlna.PlayTo
|
|||||||
usn = usn.Substring(index);
|
usn = usn.Substring(index);
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
index = usn.IndexOf("::", StringComparison.OrdinalIgnoreCase);
|
index = usn.IndexOf("::", StringComparison.OrdinalIgnoreCase);
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
{
|
{
|
||||||
@ -243,7 +243,6 @@ namespace Emby.Dlna.PlayTo
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_sessionLock.Dispose();
|
_sessionLock.Dispose();
|
||||||
|
@ -12,6 +12,7 @@ namespace Emby.Dlna.PlayTo
|
|||||||
public class MediaChangedEventArgs : EventArgs
|
public class MediaChangedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public uBaseObject OldMediaInfo { get; set; }
|
public uBaseObject OldMediaInfo { get; set; }
|
||||||
|
|
||||||
public uBaseObject NewMediaInfo { get; set; }
|
public uBaseObject NewMediaInfo { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,6 @@ namespace Emby.Dlna.PlayTo
|
|||||||
|
|
||||||
using (await _httpClient.SendAsync(options, new HttpMethod("SUBSCRIBE")).ConfigureAwait(false))
|
using (await _httpClient.SendAsync(options, new HttpMethod("SUBSCRIBE")).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,10 +44,12 @@ namespace Emby.Dlna.PlayTo
|
|||||||
{
|
{
|
||||||
return MediaBrowser.Model.Entities.MediaType.Audio;
|
return MediaBrowser.Model.Entities.MediaType.Audio;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classType.IndexOf(MediaBrowser.Model.Entities.MediaType.Video, StringComparison.Ordinal) != -1)
|
if (classType.IndexOf(MediaBrowser.Model.Entities.MediaType.Video, StringComparison.Ordinal) != -1)
|
||||||
{
|
{
|
||||||
return MediaBrowser.Model.Entities.MediaType.Video;
|
return MediaBrowser.Model.Entities.MediaType.Video;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classType.IndexOf("image", StringComparison.Ordinal) != -1)
|
if (classType.IndexOf("image", StringComparison.Ordinal) != -1)
|
||||||
{
|
{
|
||||||
return MediaBrowser.Model.Entities.MediaType.Photo;
|
return MediaBrowser.Model.Entities.MediaType.Photo;
|
||||||
|
@ -134,6 +134,7 @@ namespace Emby.Dlna.Server
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.ToString(CultureInfo.InvariantCulture);
|
return c.ToString(CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,18 +158,22 @@ namespace Emby.Dlna.Server
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stringBuilder == null)
|
if (stringBuilder == null)
|
||||||
{
|
{
|
||||||
stringBuilder = new StringBuilder();
|
stringBuilder = new StringBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
stringBuilder.Append(str, num, num2 - num);
|
stringBuilder.Append(str, num, num2 - num);
|
||||||
stringBuilder.Append(GetEscapeSequence(str[num2]));
|
stringBuilder.Append(GetEscapeSequence(str[num2]));
|
||||||
num = num2 + 1;
|
num = num2 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stringBuilder == null)
|
if (stringBuilder == null)
|
||||||
{
|
{
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
stringBuilder.Append(str, num, length - num);
|
stringBuilder.Append(str, num, length - num);
|
||||||
return stringBuilder.ToString();
|
return stringBuilder.ToString();
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ namespace Emby.Dlna.Service
|
|||||||
private const string NS_SOAPENV = "http://schemas.xmlsoap.org/soap/envelope/";
|
private const string NS_SOAPENV = "http://schemas.xmlsoap.org/soap/envelope/";
|
||||||
|
|
||||||
protected IServerConfigurationManager Config { get; }
|
protected IServerConfigurationManager Config { get; }
|
||||||
|
|
||||||
protected ILogger Logger { get; }
|
protected ILogger Logger { get; }
|
||||||
|
|
||||||
protected BaseControlHandler(IServerConfigurationManager config, ILogger logger)
|
protected BaseControlHandler(IServerConfigurationManager config, ILogger logger)
|
||||||
@ -135,6 +136,7 @@ namespace Emby.Dlna.Service
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
await reader.SkipAsync().ConfigureAwait(false);
|
await reader.SkipAsync().ConfigureAwait(false);
|
||||||
@ -211,7 +213,9 @@ namespace Emby.Dlna.Service
|
|||||||
private class ControlRequestInfo
|
private class ControlRequestInfo
|
||||||
{
|
{
|
||||||
public string LocalName { get; set; }
|
public string LocalName { get; set; }
|
||||||
|
|
||||||
public string NamespaceURI { get; set; }
|
public string NamespaceURI { get; set; }
|
||||||
|
|
||||||
public Dictionary<string, string> Headers { get; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
public Dictionary<string, string> Headers { get; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +80,7 @@ namespace Emby.Dlna.Service
|
|||||||
{
|
{
|
||||||
builder.Append("<allowedValue>" + DescriptionXmlBuilder.Escape(allowedValue) + "</allowedValue>");
|
builder.Append("<allowedValue>" + DescriptionXmlBuilder.Escape(allowedValue) + "</allowedValue>");
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.Append("</allowedValueList>");
|
builder.Append("</allowedValueList>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ namespace Emby.Dlna.Ssdp
|
|||||||
// (Optional) Set the filter so we only see notifications for devices we care about
|
// (Optional) Set the filter so we only see notifications for devices we care about
|
||||||
// (can be any search target value i.e device type, uuid value etc - any value that appears in the
|
// (can be any search target value i.e device type, uuid value etc - any value that appears in the
|
||||||
// DiscoverdSsdpDevice.NotificationType property or that is used with the searchTarget parameter of the Search method).
|
// DiscoverdSsdpDevice.NotificationType property or that is used with the searchTarget parameter of the Search method).
|
||||||
//_DeviceLocator.NotificationFilter = "upnp:rootdevice";
|
// _DeviceLocator.NotificationFilter = "upnp:rootdevice";
|
||||||
|
|
||||||
// Connect our event handler so we process devices as they are found
|
// Connect our event handler so we process devices as they are found
|
||||||
_deviceLocator.DeviceAvailable += OnDeviceLocatorDeviceAvailable;
|
_deviceLocator.DeviceAvailable += OnDeviceLocatorDeviceAvailable;
|
||||||
|
@ -4,6 +4,7 @@ using System.Globalization;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Drawing;
|
using MediaBrowser.Controller.Drawing;
|
||||||
@ -14,6 +15,7 @@ using MediaBrowser.Model.Entities;
|
|||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Photo = MediaBrowser.Controller.Entities.Photo;
|
||||||
|
|
||||||
namespace Emby.Drawing
|
namespace Emby.Drawing
|
||||||
{
|
{
|
||||||
@ -349,6 +351,13 @@ namespace Emby.Drawing
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string GetImageCacheTag(User user)
|
||||||
|
{
|
||||||
|
return (user.ProfileImage.Path + user.ProfileImage.LastModified.Ticks).GetMD5()
|
||||||
|
.ToString("N", CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<(string path, DateTime dateModified)> GetSupportedImage(string originalImagePath, DateTime dateModified)
|
private async Task<(string path, DateTime dateModified)> GetSupportedImage(string originalImagePath, DateTime dateModified)
|
||||||
{
|
{
|
||||||
var inputFormat = Path.GetExtension(originalImagePath)
|
var inputFormat = Path.GetExtension(originalImagePath)
|
||||||
|
@ -64,6 +64,7 @@ namespace Emby.Naming.AudioBook
|
|||||||
{
|
{
|
||||||
result.ChapterNumber = int.Parse(matches[0].Groups[0].Value);
|
result.ChapterNumber = int.Parse(matches[0].Groups[0].Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matches.Count > 1)
|
if (matches.Count > 1)
|
||||||
{
|
{
|
||||||
result.PartNumber = int.Parse(matches[matches.Count - 1].Groups[0].Value);
|
result.PartNumber = int.Parse(matches[matches.Count - 1].Groups[0].Value);
|
||||||
|
@ -5,17 +5,17 @@ namespace Emby.Naming.Common
|
|||||||
public enum MediaType
|
public enum MediaType
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The audio
|
/// The audio.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Audio = 0,
|
Audio = 0,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The photo
|
/// The photo.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Photo = 1,
|
Photo = 1,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The video
|
/// The video.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Video = 2
|
Video = 2
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ using System.Diagnostics.CodeAnalysis;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Controller.Notifications;
|
using MediaBrowser.Controller.Notifications;
|
||||||
@ -149,9 +150,7 @@ namespace Emby.Notifications.Api
|
|||||||
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")]
|
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")]
|
||||||
public object Get(GetNotificationsSummary request)
|
public object Get(GetNotificationsSummary request)
|
||||||
{
|
{
|
||||||
return new NotificationsSummary
|
return new NotificationsSummary();
|
||||||
{
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task Post(AddAdminNotification request)
|
public Task Post(AddAdminNotification request)
|
||||||
@ -164,7 +163,10 @@ namespace Emby.Notifications.Api
|
|||||||
Level = request.Level,
|
Level = request.Level,
|
||||||
Name = request.Name,
|
Name = request.Name,
|
||||||
Url = request.Url,
|
Url = request.Url,
|
||||||
UserIds = _userManager.Users.Where(i => i.Policy.IsAdministrator).Select(i => i.Id).ToArray()
|
UserIds = _userManager.Users
|
||||||
|
.Where(user => user.HasPermission(PermissionKind.IsAdministrator))
|
||||||
|
.Select(user => user.Id)
|
||||||
|
.ToArray()
|
||||||
};
|
};
|
||||||
|
|
||||||
return _notificationManager.SendNotification(notification, CancellationToken.None);
|
return _notificationManager.SendNotification(notification, CancellationToken.None);
|
||||||
|
@ -4,6 +4,8 @@ using System.Globalization;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
@ -101,7 +103,7 @@ namespace Emby.Notifications
|
|||||||
switch (request.SendToUserMode.Value)
|
switch (request.SendToUserMode.Value)
|
||||||
{
|
{
|
||||||
case SendToUserType.Admins:
|
case SendToUserType.Admins:
|
||||||
return _userManager.Users.Where(i => i.Policy.IsAdministrator)
|
return _userManager.Users.Where(i => i.HasPermission(PermissionKind.IsAdministrator))
|
||||||
.Select(i => i.Id);
|
.Select(i => i.Id);
|
||||||
case SendToUserType.All:
|
case SendToUserType.All:
|
||||||
return _userManager.UsersIds;
|
return _userManager.UsersIds;
|
||||||
@ -117,7 +119,7 @@ namespace Emby.Notifications
|
|||||||
var config = GetConfiguration();
|
var config = GetConfiguration();
|
||||||
|
|
||||||
return _userManager.Users
|
return _userManager.Users
|
||||||
.Where(i => config.IsEnabledToSendToUser(request.NotificationType, i.Id.ToString("N", CultureInfo.InvariantCulture), i.Policy))
|
.Where(i => config.IsEnabledToSendToUser(request.NotificationType, i.Id.ToString("N", CultureInfo.InvariantCulture), i))
|
||||||
.Select(i => i.Id);
|
.Select(i => i.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +144,7 @@ namespace Emby.Notifications
|
|||||||
User = user
|
User = user
|
||||||
};
|
};
|
||||||
|
|
||||||
_logger.LogDebug("Sending notification via {0} to user {1}", service.Name, user.Name);
|
_logger.LogDebug("Sending notification via {0} to user {1}", service.Name, user.Username);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -88,25 +88,26 @@ namespace Emby.Server.Implementations.Activity
|
|||||||
|
|
||||||
_subManager.SubtitleDownloadFailure += OnSubtitleDownloadFailure;
|
_subManager.SubtitleDownloadFailure += OnSubtitleDownloadFailure;
|
||||||
|
|
||||||
_userManager.UserCreated += OnUserCreated;
|
_userManager.OnUserCreated += OnUserCreated;
|
||||||
_userManager.UserPasswordChanged += OnUserPasswordChanged;
|
_userManager.OnUserPasswordChanged += OnUserPasswordChanged;
|
||||||
_userManager.UserDeleted += OnUserDeleted;
|
_userManager.OnUserDeleted += OnUserDeleted;
|
||||||
_userManager.UserPolicyUpdated += OnUserPolicyUpdated;
|
_userManager.OnUserLockedOut += OnUserLockedOut;
|
||||||
_userManager.UserLockedOut += OnUserLockedOut;
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OnUserLockedOut(object sender, GenericEventArgs<MediaBrowser.Controller.Entities.User> e)
|
private async void OnUserLockedOut(object sender, GenericEventArgs<User> e)
|
||||||
{
|
{
|
||||||
await CreateLogEntry(new ActivityLog(
|
await CreateLogEntry(new ActivityLog(
|
||||||
string.Format(
|
string.Format(
|
||||||
CultureInfo.InvariantCulture,
|
CultureInfo.InvariantCulture,
|
||||||
_localization.GetLocalizedString("UserLockedOutWithName"),
|
_localization.GetLocalizedString("UserLockedOutWithName"),
|
||||||
e.Argument.Name),
|
e.Argument.Username),
|
||||||
NotificationType.UserLockedOut.ToString(),
|
NotificationType.UserLockedOut.ToString(),
|
||||||
e.Argument.Id))
|
e.Argument.Id)
|
||||||
.ConfigureAwait(false);
|
{
|
||||||
|
LogSeverity = LogLevel.Error
|
||||||
|
}).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OnSubtitleDownloadFailure(object sender, SubtitleDownloadFailureEventArgs e)
|
private async void OnSubtitleDownloadFailure(object sender, SubtitleDownloadFailureEventArgs e)
|
||||||
@ -152,7 +153,7 @@ namespace Emby.Server.Implementations.Activity
|
|||||||
string.Format(
|
string.Format(
|
||||||
CultureInfo.InvariantCulture,
|
CultureInfo.InvariantCulture,
|
||||||
_localization.GetLocalizedString("UserStoppedPlayingItemWithValues"),
|
_localization.GetLocalizedString("UserStoppedPlayingItemWithValues"),
|
||||||
user.Name,
|
user.Username,
|
||||||
GetItemName(item),
|
GetItemName(item),
|
||||||
e.DeviceName),
|
e.DeviceName),
|
||||||
GetPlaybackStoppedNotificationType(item.MediaType),
|
GetPlaybackStoppedNotificationType(item.MediaType),
|
||||||
@ -187,7 +188,7 @@ namespace Emby.Server.Implementations.Activity
|
|||||||
string.Format(
|
string.Format(
|
||||||
CultureInfo.InvariantCulture,
|
CultureInfo.InvariantCulture,
|
||||||
_localization.GetLocalizedString("UserStartedPlayingItemWithValues"),
|
_localization.GetLocalizedString("UserStartedPlayingItemWithValues"),
|
||||||
user.Name,
|
user.Username,
|
||||||
GetItemName(item),
|
GetItemName(item),
|
||||||
e.DeviceName),
|
e.DeviceName),
|
||||||
GetPlaybackNotificationType(item.MediaType),
|
GetPlaybackNotificationType(item.MediaType),
|
||||||
@ -304,49 +305,37 @@ namespace Emby.Server.Implementations.Activity
|
|||||||
}).ConfigureAwait(false);
|
}).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OnUserPolicyUpdated(object sender, GenericEventArgs<MediaBrowser.Controller.Entities.User> e)
|
private async void OnUserDeleted(object sender, GenericEventArgs<User> e)
|
||||||
{
|
|
||||||
await CreateLogEntry(new ActivityLog(
|
|
||||||
string.Format(
|
|
||||||
CultureInfo.InvariantCulture,
|
|
||||||
_localization.GetLocalizedString("UserPolicyUpdatedWithName"),
|
|
||||||
e.Argument.Name),
|
|
||||||
"UserPolicyUpdated",
|
|
||||||
e.Argument.Id))
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void OnUserDeleted(object sender, GenericEventArgs<MediaBrowser.Controller.Entities.User> e)
|
|
||||||
{
|
{
|
||||||
await CreateLogEntry(new ActivityLog(
|
await CreateLogEntry(new ActivityLog(
|
||||||
string.Format(
|
string.Format(
|
||||||
CultureInfo.InvariantCulture,
|
CultureInfo.InvariantCulture,
|
||||||
_localization.GetLocalizedString("UserDeletedWithName"),
|
_localization.GetLocalizedString("UserDeletedWithName"),
|
||||||
e.Argument.Name),
|
e.Argument.Username),
|
||||||
"UserDeleted",
|
"UserDeleted",
|
||||||
Guid.Empty))
|
Guid.Empty))
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OnUserPasswordChanged(object sender, GenericEventArgs<MediaBrowser.Controller.Entities.User> e)
|
private async void OnUserPasswordChanged(object sender, GenericEventArgs<User> e)
|
||||||
{
|
{
|
||||||
await CreateLogEntry(new ActivityLog(
|
await CreateLogEntry(new ActivityLog(
|
||||||
string.Format(
|
string.Format(
|
||||||
CultureInfo.InvariantCulture,
|
CultureInfo.InvariantCulture,
|
||||||
_localization.GetLocalizedString("UserPasswordChangedWithName"),
|
_localization.GetLocalizedString("UserPasswordChangedWithName"),
|
||||||
e.Argument.Name),
|
e.Argument.Username),
|
||||||
"UserPasswordChanged",
|
"UserPasswordChanged",
|
||||||
e.Argument.Id))
|
e.Argument.Id))
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OnUserCreated(object sender, GenericEventArgs<MediaBrowser.Controller.Entities.User> e)
|
private async void OnUserCreated(object sender, GenericEventArgs<User> e)
|
||||||
{
|
{
|
||||||
await CreateLogEntry(new ActivityLog(
|
await CreateLogEntry(new ActivityLog(
|
||||||
string.Format(
|
string.Format(
|
||||||
CultureInfo.InvariantCulture,
|
CultureInfo.InvariantCulture,
|
||||||
_localization.GetLocalizedString("UserCreatedWithName"),
|
_localization.GetLocalizedString("UserCreatedWithName"),
|
||||||
e.Argument.Name),
|
e.Argument.Username),
|
||||||
"UserCreated",
|
"UserCreated",
|
||||||
e.Argument.Id))
|
e.Argument.Id))
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
@ -510,11 +499,10 @@ namespace Emby.Server.Implementations.Activity
|
|||||||
|
|
||||||
_subManager.SubtitleDownloadFailure -= OnSubtitleDownloadFailure;
|
_subManager.SubtitleDownloadFailure -= OnSubtitleDownloadFailure;
|
||||||
|
|
||||||
_userManager.UserCreated -= OnUserCreated;
|
_userManager.OnUserCreated -= OnUserCreated;
|
||||||
_userManager.UserPasswordChanged -= OnUserPasswordChanged;
|
_userManager.OnUserPasswordChanged -= OnUserPasswordChanged;
|
||||||
_userManager.UserDeleted -= OnUserDeleted;
|
_userManager.OnUserDeleted -= OnUserDeleted;
|
||||||
_userManager.UserPolicyUpdated -= OnUserPolicyUpdated;
|
_userManager.OnUserLockedOut -= OnUserLockedOut;
|
||||||
_userManager.UserLockedOut -= OnUserLockedOut;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -562,11 +562,8 @@ namespace Emby.Server.Implementations
|
|||||||
|
|
||||||
serviceCollection.AddSingleton<IAuthenticationRepository, AuthenticationRepository>();
|
serviceCollection.AddSingleton<IAuthenticationRepository, AuthenticationRepository>();
|
||||||
|
|
||||||
serviceCollection.AddSingleton<IUserRepository, SqliteUserRepository>();
|
|
||||||
|
|
||||||
// TODO: Refactor to eliminate the circular dependency here so that Lazy<T> isn't required
|
// TODO: Refactor to eliminate the circular dependency here so that Lazy<T> isn't required
|
||||||
serviceCollection.AddTransient(provider => new Lazy<IDtoService>(provider.GetRequiredService<IDtoService>));
|
serviceCollection.AddTransient(provider => new Lazy<IDtoService>(provider.GetRequiredService<IDtoService>));
|
||||||
serviceCollection.AddSingleton<IUserManager, UserManager>();
|
|
||||||
|
|
||||||
// TODO: Refactor to eliminate the circular dependency here so that Lazy<T> isn't required
|
// TODO: Refactor to eliminate the circular dependency here so that Lazy<T> isn't required
|
||||||
// TODO: Add StartupOptions.FFmpegPath to IConfiguration and remove this custom activation
|
// TODO: Add StartupOptions.FFmpegPath to IConfiguration and remove this custom activation
|
||||||
@ -659,15 +656,11 @@ namespace Emby.Server.Implementations
|
|||||||
|
|
||||||
((SqliteDisplayPreferencesRepository)Resolve<IDisplayPreferencesRepository>()).Initialize();
|
((SqliteDisplayPreferencesRepository)Resolve<IDisplayPreferencesRepository>()).Initialize();
|
||||||
((AuthenticationRepository)Resolve<IAuthenticationRepository>()).Initialize();
|
((AuthenticationRepository)Resolve<IAuthenticationRepository>()).Initialize();
|
||||||
((SqliteUserRepository)Resolve<IUserRepository>()).Initialize();
|
|
||||||
|
|
||||||
SetStaticProperties();
|
SetStaticProperties();
|
||||||
|
|
||||||
var userManager = (UserManager)Resolve<IUserManager>();
|
|
||||||
userManager.Initialize();
|
|
||||||
|
|
||||||
var userDataRepo = (SqliteUserDataRepository)Resolve<IUserDataRepository>();
|
var userDataRepo = (SqliteUserDataRepository)Resolve<IUserDataRepository>();
|
||||||
((SqliteItemRepository)Resolve<IItemRepository>()).Initialize(userDataRepo, userManager);
|
((SqliteItemRepository)Resolve<IItemRepository>()).Initialize(userDataRepo, Resolve<IUserManager>());
|
||||||
|
|
||||||
FindParts();
|
FindParts();
|
||||||
}
|
}
|
||||||
@ -750,7 +743,6 @@ namespace Emby.Server.Implementations
|
|||||||
BaseItem.ProviderManager = Resolve<IProviderManager>();
|
BaseItem.ProviderManager = Resolve<IProviderManager>();
|
||||||
BaseItem.LocalizationManager = Resolve<ILocalizationManager>();
|
BaseItem.LocalizationManager = Resolve<ILocalizationManager>();
|
||||||
BaseItem.ItemRepository = Resolve<IItemRepository>();
|
BaseItem.ItemRepository = Resolve<IItemRepository>();
|
||||||
User.UserManager = Resolve<IUserManager>();
|
|
||||||
BaseItem.FileSystem = _fileSystemManager;
|
BaseItem.FileSystem = _fileSystemManager;
|
||||||
BaseItem.UserDataManager = Resolve<IUserDataManager>();
|
BaseItem.UserDataManager = Resolve<IUserDataManager>();
|
||||||
BaseItem.ChannelManager = Resolve<IChannelManager>();
|
BaseItem.ChannelManager = Resolve<IChannelManager>();
|
||||||
@ -964,7 +956,7 @@ namespace Emby.Server.Implementations
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Notifies that the kernel that a change has been made that requires a restart
|
/// Notifies that the kernel that a change has been made that requires a restart.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void NotifyPendingRestart()
|
public void NotifyPendingRestart()
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Progress;
|
using MediaBrowser.Common.Progress;
|
||||||
using MediaBrowser.Controller.Channels;
|
using MediaBrowser.Controller.Channels;
|
||||||
@ -13,8 +14,6 @@ using MediaBrowser.Controller.Configuration;
|
|||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
using MediaBrowser.Controller.Entities.Movies;
|
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Channels;
|
using MediaBrowser.Model.Channels;
|
||||||
@ -24,6 +23,11 @@ using MediaBrowser.Model.IO;
|
|||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Episode = MediaBrowser.Controller.Entities.TV.Episode;
|
||||||
|
using Movie = MediaBrowser.Controller.Entities.Movies.Movie;
|
||||||
|
using MusicAlbum = MediaBrowser.Controller.Entities.Audio.MusicAlbum;
|
||||||
|
using Season = MediaBrowser.Controller.Entities.TV.Season;
|
||||||
|
using Series = MediaBrowser.Controller.Entities.TV.Series;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Channels
|
namespace Emby.Server.Implementations.Channels
|
||||||
{
|
{
|
||||||
@ -791,7 +795,8 @@ namespace Emby.Server.Implementations.Channels
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<ChannelItemResult> GetChannelItems(IChannel channel,
|
private async Task<ChannelItemResult> GetChannelItems(
|
||||||
|
IChannel channel,
|
||||||
User user,
|
User user,
|
||||||
string externalFolderId,
|
string externalFolderId,
|
||||||
ChannelItemSortField? sortField,
|
ChannelItemSortField? sortField,
|
||||||
@ -1067,7 +1072,7 @@ namespace Emby.Server.Implementations.Channels
|
|||||||
}
|
}
|
||||||
|
|
||||||
// was used for status
|
// was used for status
|
||||||
//if (!string.Equals(item.ExternalEtag ?? string.Empty, info.Etag ?? string.Empty, StringComparison.Ordinal))
|
// if (!string.Equals(item.ExternalEtag ?? string.Empty, info.Etag ?? string.Empty, StringComparison.Ordinal))
|
||||||
//{
|
//{
|
||||||
// item.ExternalEtag = info.Etag;
|
// item.ExternalEtag = info.Etag;
|
||||||
// forceUpdate = true;
|
// forceUpdate = true;
|
||||||
|
@ -5,6 +5,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Controller.Collections;
|
using MediaBrowser.Controller.Collections;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
|
@ -162,7 +162,6 @@ namespace Emby.Server.Implementations.Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}, ReadTransactionMode);
|
}, ReadTransactionMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,12 +247,12 @@ namespace Emby.Server.Implementations.Data
|
|||||||
public enum SynchronousMode
|
public enum SynchronousMode
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SQLite continues without syncing as soon as it has handed data off to the operating system
|
/// SQLite continues without syncing as soon as it has handed data off to the operating system.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Off = 0,
|
Off = 0,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SQLite database engine will still sync at the most critical moments
|
/// SQLite database engine will still sync at the most critical moments.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Normal = 1,
|
Normal = 1,
|
||||||
|
|
||||||
|
@ -51,7 +51,6 @@ namespace Emby.Server.Implementations.Data
|
|||||||
_libraryManager.DeleteItem(item, new DeleteOptions
|
_libraryManager.DeleteItem(item, new DeleteOptions
|
||||||
{
|
{
|
||||||
DeleteFileLocation = false
|
DeleteFileLocation = false
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -59,7 +59,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Opens the connection to the database
|
/// Opens the connection to the database.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
private void InitializeInternal()
|
private void InitializeInternal()
|
||||||
@ -77,7 +77,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Save the display preferences associated with an item in the repo
|
/// Save the display preferences associated with an item in the repo.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="displayPreferences">The display preferences.</param>
|
/// <param name="displayPreferences">The display preferences.</param>
|
||||||
/// <param name="userId">The user id.</param>
|
/// <param name="userId">The user id.</param>
|
||||||
@ -122,7 +122,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Save all display preferences associated with a user in the repo
|
/// Save all display preferences associated with a user in the repo.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="displayPreferences">The display preferences.</param>
|
/// <param name="displayPreferences">The display preferences.</param>
|
||||||
/// <param name="userId">The user id.</param>
|
/// <param name="userId">The user id.</param>
|
||||||
|
@ -102,7 +102,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
protected override TempStoreMode TempStore => TempStoreMode.Memory;
|
protected override TempStoreMode TempStore => TempStoreMode.Memory;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Opens the connection to the database
|
/// Opens the connection to the database.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Initialize(SqliteUserDataRepository userDataRepo, IUserManager userManager)
|
public void Initialize(SqliteUserDataRepository userDataRepo, IUserManager userManager)
|
||||||
{
|
{
|
||||||
@ -321,7 +321,6 @@ namespace Emby.Server.Implementations.Data
|
|||||||
AddColumn(db, "MediaStreams", "ColorPrimaries", "TEXT", existingColumnNames);
|
AddColumn(db, "MediaStreams", "ColorPrimaries", "TEXT", existingColumnNames);
|
||||||
AddColumn(db, "MediaStreams", "ColorSpace", "TEXT", existingColumnNames);
|
AddColumn(db, "MediaStreams", "ColorSpace", "TEXT", existingColumnNames);
|
||||||
AddColumn(db, "MediaStreams", "ColorTransfer", "TEXT", existingColumnNames);
|
AddColumn(db, "MediaStreams", "ColorTransfer", "TEXT", existingColumnNames);
|
||||||
|
|
||||||
}, TransactionMode);
|
}, TransactionMode);
|
||||||
|
|
||||||
connection.RunQueries(postQueries);
|
connection.RunQueries(postQueries);
|
||||||
@ -549,7 +548,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Save a standard item in the repo
|
/// Save a standard item in the repo.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="item">The item.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
@ -794,6 +793,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
saveItemStatement.TryBindNull("@Width");
|
saveItemStatement.TryBindNull("@Width");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.Height > 0)
|
if (item.Height > 0)
|
||||||
{
|
{
|
||||||
saveItemStatement.TryBind("@Height", item.Height);
|
saveItemStatement.TryBind("@Height", item.Height);
|
||||||
@ -933,6 +933,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
saveItemStatement.TryBindNull("@SeriesName");
|
saveItemStatement.TryBindNull("@SeriesName");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(userDataKey))
|
if (string.IsNullOrWhiteSpace(userDataKey))
|
||||||
{
|
{
|
||||||
saveItemStatement.TryBindNull("@UserDataKey");
|
saveItemStatement.TryBindNull("@UserDataKey");
|
||||||
@ -1008,6 +1009,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
artists = string.Join("|", hasArtists.Artists);
|
artists = string.Join("|", hasArtists.Artists);
|
||||||
}
|
}
|
||||||
|
|
||||||
saveItemStatement.TryBind("@Artists", artists);
|
saveItemStatement.TryBind("@Artists", artists);
|
||||||
|
|
||||||
string albumArtists = null;
|
string albumArtists = null;
|
||||||
@ -1107,6 +1109,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
str.Append(ToValueString(i) + "|");
|
str.Append(ToValueString(i) + "|");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1205,7 +1208,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Internal retrieve from items or users table
|
/// Internal retrieve from items or users table.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id">The id.</param>
|
/// <param name="id">The id.</param>
|
||||||
/// <returns>BaseItem.</returns>
|
/// <returns>BaseItem.</returns>
|
||||||
@ -1367,6 +1370,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
hasStartDate.StartDate = reader[index].ReadDateTime();
|
hasStartDate.StartDate = reader[index].ReadDateTime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1374,12 +1378,14 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.EndDate = reader[index].TryReadDateTime();
|
item.EndDate = reader[index].TryReadDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (!reader.IsDBNull(index))
|
if (!reader.IsDBNull(index))
|
||||||
{
|
{
|
||||||
item.ChannelId = new Guid(reader.GetString(index));
|
item.ChannelId = new Guid(reader.GetString(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (enableProgramAttributes)
|
if (enableProgramAttributes)
|
||||||
@ -1390,24 +1396,28 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
hasProgramAttributes.IsMovie = reader.GetBoolean(index);
|
hasProgramAttributes.IsMovie = reader.GetBoolean(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (!reader.IsDBNull(index))
|
if (!reader.IsDBNull(index))
|
||||||
{
|
{
|
||||||
hasProgramAttributes.IsSeries = reader.GetBoolean(index);
|
hasProgramAttributes.IsSeries = reader.GetBoolean(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (!reader.IsDBNull(index))
|
if (!reader.IsDBNull(index))
|
||||||
{
|
{
|
||||||
hasProgramAttributes.EpisodeTitle = reader.GetString(index);
|
hasProgramAttributes.EpisodeTitle = reader.GetString(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (!reader.IsDBNull(index))
|
if (!reader.IsDBNull(index))
|
||||||
{
|
{
|
||||||
hasProgramAttributes.IsRepeat = reader.GetBoolean(index);
|
hasProgramAttributes.IsRepeat = reader.GetBoolean(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1420,6 +1430,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.CommunityRating = reader.GetFloat(index);
|
item.CommunityRating = reader.GetFloat(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (HasField(query, ItemFields.CustomRating))
|
if (HasField(query, ItemFields.CustomRating))
|
||||||
@ -1428,6 +1439,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.CustomRating = reader.GetString(index);
|
item.CustomRating = reader.GetString(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1435,6 +1447,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.IndexNumber = reader.GetInt32(index);
|
item.IndexNumber = reader.GetInt32(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (HasField(query, ItemFields.Settings))
|
if (HasField(query, ItemFields.Settings))
|
||||||
@ -1443,18 +1456,21 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.IsLocked = reader.GetBoolean(index);
|
item.IsLocked = reader.GetBoolean(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (!reader.IsDBNull(index))
|
if (!reader.IsDBNull(index))
|
||||||
{
|
{
|
||||||
item.PreferredMetadataLanguage = reader.GetString(index);
|
item.PreferredMetadataLanguage = reader.GetString(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (!reader.IsDBNull(index))
|
if (!reader.IsDBNull(index))
|
||||||
{
|
{
|
||||||
item.PreferredMetadataCountryCode = reader.GetString(index);
|
item.PreferredMetadataCountryCode = reader.GetString(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1464,6 +1480,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.Width = reader.GetInt32(index);
|
item.Width = reader.GetInt32(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1473,6 +1490,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.Height = reader.GetInt32(index);
|
item.Height = reader.GetInt32(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1482,6 +1500,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.DateLastRefreshed = reader[index].ReadDateTime();
|
item.DateLastRefreshed = reader[index].ReadDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1489,18 +1508,21 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.Name = reader.GetString(index);
|
item.Name = reader.GetString(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (!reader.IsDBNull(index))
|
if (!reader.IsDBNull(index))
|
||||||
{
|
{
|
||||||
item.Path = RestorePath(reader.GetString(index));
|
item.Path = RestorePath(reader.GetString(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (!reader.IsDBNull(index))
|
if (!reader.IsDBNull(index))
|
||||||
{
|
{
|
||||||
item.PremiereDate = reader[index].TryReadDateTime();
|
item.PremiereDate = reader[index].TryReadDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (HasField(query, ItemFields.Overview))
|
if (HasField(query, ItemFields.Overview))
|
||||||
@ -1509,6 +1531,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.Overview = reader.GetString(index);
|
item.Overview = reader.GetString(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1516,18 +1539,21 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.ParentIndexNumber = reader.GetInt32(index);
|
item.ParentIndexNumber = reader.GetInt32(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (!reader.IsDBNull(index))
|
if (!reader.IsDBNull(index))
|
||||||
{
|
{
|
||||||
item.ProductionYear = reader.GetInt32(index);
|
item.ProductionYear = reader.GetInt32(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (!reader.IsDBNull(index))
|
if (!reader.IsDBNull(index))
|
||||||
{
|
{
|
||||||
item.OfficialRating = reader.GetString(index);
|
item.OfficialRating = reader.GetString(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (HasField(query, ItemFields.SortName))
|
if (HasField(query, ItemFields.SortName))
|
||||||
@ -1536,6 +1562,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.ForcedSortName = reader.GetString(index);
|
item.ForcedSortName = reader.GetString(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1543,12 +1570,14 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.RunTimeTicks = reader.GetInt64(index);
|
item.RunTimeTicks = reader.GetInt64(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (!reader.IsDBNull(index))
|
if (!reader.IsDBNull(index))
|
||||||
{
|
{
|
||||||
item.Size = reader.GetInt64(index);
|
item.Size = reader.GetInt64(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (HasField(query, ItemFields.DateCreated))
|
if (HasField(query, ItemFields.DateCreated))
|
||||||
@ -1557,6 +1586,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.DateCreated = reader[index].ReadDateTime();
|
item.DateCreated = reader[index].ReadDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1564,6 +1594,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.DateModified = reader[index].ReadDateTime();
|
item.DateModified = reader[index].ReadDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
item.Id = reader.GetGuid(index);
|
item.Id = reader.GetGuid(index);
|
||||||
@ -1575,6 +1606,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.Genres = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
|
item.Genres = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1582,6 +1614,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.ParentId = reader.GetGuid(index);
|
item.ParentId = reader.GetGuid(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (!reader.IsDBNull(index))
|
if (!reader.IsDBNull(index))
|
||||||
@ -1591,6 +1624,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
item.Audio = audio;
|
item.Audio = audio;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
// TODO: Even if not needed by apps, the server needs it internally
|
// TODO: Even if not needed by apps, the server needs it internally
|
||||||
@ -1604,6 +1638,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
liveTvChannel.ServiceName = reader.GetString(index);
|
liveTvChannel.ServiceName = reader.GetString(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1611,6 +1646,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.IsInMixedFolder = reader.GetBoolean(index);
|
item.IsInMixedFolder = reader.GetBoolean(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (HasField(query, ItemFields.DateLastSaved))
|
if (HasField(query, ItemFields.DateLastSaved))
|
||||||
@ -1619,6 +1655,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.DateLastSaved = reader[index].ReadDateTime();
|
item.DateLastSaved = reader[index].ReadDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1636,8 +1673,10 @@ namespace Emby.Server.Implementations.Data
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
item.LockedFields = GetLockedFields(reader.GetString(index)).ToArray();
|
item.LockedFields = GetLockedFields(reader.GetString(index)).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1647,6 +1686,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.Studios = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
|
item.Studios = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1656,6 +1696,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.Tags = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
|
item.Tags = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1675,9 +1716,11 @@ namespace Emby.Server.Implementations.Data
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trailer.TrailerTypes = GetTrailerTypes(reader.GetString(index)).ToArray();
|
trailer.TrailerTypes = GetTrailerTypes(reader.GetString(index)).ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1687,6 +1730,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.OriginalTitle = reader.GetString(index);
|
item.OriginalTitle = reader.GetString(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1697,6 +1741,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
video.PrimaryVersionId = reader.GetString(index);
|
video.PrimaryVersionId = reader.GetString(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (HasField(query, ItemFields.DateLastMediaAdded))
|
if (HasField(query, ItemFields.DateLastMediaAdded))
|
||||||
@ -1705,6 +1750,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
folder.DateLastMediaAdded = reader[index].TryReadDateTime();
|
folder.DateLastMediaAdded = reader[index].TryReadDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1712,18 +1758,21 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.Album = reader.GetString(index);
|
item.Album = reader.GetString(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (!reader.IsDBNull(index))
|
if (!reader.IsDBNull(index))
|
||||||
{
|
{
|
||||||
item.CriticRating = reader.GetFloat(index);
|
item.CriticRating = reader.GetFloat(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (!reader.IsDBNull(index))
|
if (!reader.IsDBNull(index))
|
||||||
{
|
{
|
||||||
item.IsVirtualItem = reader.GetBoolean(index);
|
item.IsVirtualItem = reader.GetBoolean(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (item is IHasSeries hasSeriesName)
|
if (item is IHasSeries hasSeriesName)
|
||||||
@ -1733,6 +1782,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
hasSeriesName.SeriesName = reader.GetString(index);
|
hasSeriesName.SeriesName = reader.GetString(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (hasEpisodeAttributes)
|
if (hasEpisodeAttributes)
|
||||||
@ -1743,6 +1793,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
episode.SeasonName = reader.GetString(index);
|
episode.SeasonName = reader.GetString(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
if (!reader.IsDBNull(index))
|
if (!reader.IsDBNull(index))
|
||||||
{
|
{
|
||||||
@ -1753,6 +1804,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1766,6 +1818,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
hasSeries.SeriesId = reader.GetGuid(index);
|
hasSeries.SeriesId = reader.GetGuid(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1775,6 +1828,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.PresentationUniqueKey = reader.GetString(index);
|
item.PresentationUniqueKey = reader.GetString(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1784,6 +1838,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.InheritedParentalRatingValue = reader.GetInt32(index);
|
item.InheritedParentalRatingValue = reader.GetInt32(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1793,6 +1848,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.ExternalSeriesId = reader.GetString(index);
|
item.ExternalSeriesId = reader.GetString(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1802,6 +1858,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.Tagline = reader.GetString(index);
|
item.Tagline = reader.GetString(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1809,6 +1866,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
DeserializeProviderIds(reader.GetString(index), item);
|
DeserializeProviderIds(reader.GetString(index), item);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (query.DtoOptions.EnableImages)
|
if (query.DtoOptions.EnableImages)
|
||||||
@ -1817,6 +1875,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
DeserializeImages(reader.GetString(index), item);
|
DeserializeImages(reader.GetString(index), item);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1826,6 +1885,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.ProductionLocations = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries).ToArray();
|
item.ProductionLocations = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1835,6 +1895,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.ExtraIds = SplitToGuids(reader.GetString(index));
|
item.ExtraIds = SplitToGuids(reader.GetString(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1842,6 +1903,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.TotalBitrate = reader.GetInt32(index);
|
item.TotalBitrate = reader.GetInt32(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (!reader.IsDBNull(index))
|
if (!reader.IsDBNull(index))
|
||||||
@ -1851,6 +1913,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
item.ExtraType = extraType;
|
item.ExtraType = extraType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (hasArtistFields)
|
if (hasArtistFields)
|
||||||
@ -1859,12 +1922,14 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
hasArtists.Artists = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
|
hasArtists.Artists = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (item is IHasAlbumArtist hasAlbumArtists && !reader.IsDBNull(index))
|
if (item is IHasAlbumArtist hasAlbumArtists && !reader.IsDBNull(index))
|
||||||
{
|
{
|
||||||
hasAlbumArtists.AlbumArtists = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
|
hasAlbumArtists.AlbumArtists = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1872,6 +1937,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.ExternalId = reader.GetString(index);
|
item.ExternalId = reader.GetString(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (HasField(query, ItemFields.SeriesPresentationUniqueKey))
|
if (HasField(query, ItemFields.SeriesPresentationUniqueKey))
|
||||||
@ -1883,6 +1949,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
hasSeries.SeriesPresentationUniqueKey = reader.GetString(index);
|
hasSeries.SeriesPresentationUniqueKey = reader.GetString(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1892,6 +1959,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
program.ShowId = reader.GetString(index);
|
program.ShowId = reader.GetString(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1899,6 +1967,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
item.OwnerId = reader.GetGuid(index);
|
item.OwnerId = reader.GetGuid(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
@ -1919,7 +1988,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets chapters for an item
|
/// Gets chapters for an item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="item">The item.</param>
|
||||||
/// <returns>IEnumerable{ChapterInfo}.</returns>
|
/// <returns>IEnumerable{ChapterInfo}.</returns>
|
||||||
@ -1947,7 +2016,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a single chapter for an item
|
/// Gets a single chapter for an item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="item">The item.</param>
|
||||||
/// <param name="index">The index.</param>
|
/// <param name="index">The index.</param>
|
||||||
@ -2044,7 +2113,6 @@ namespace Emby.Server.Implementations.Data
|
|||||||
db.Execute("delete from " + ChaptersTableName + " where ItemId=@ItemId", idBlob);
|
db.Execute("delete from " + ChaptersTableName + " where ItemId=@ItemId", idBlob);
|
||||||
|
|
||||||
InsertChapters(idBlob, chapters, db);
|
InsertChapters(idBlob, chapters, db);
|
||||||
|
|
||||||
}, TransactionMode);
|
}, TransactionMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2475,6 +2543,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
statement.TryBind("@SearchTermStartsWith", searchTerm + "%");
|
statement.TryBind("@SearchTermStartsWith", searchTerm + "%");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commandText.IndexOf("@SearchTermContains", StringComparison.OrdinalIgnoreCase) != -1)
|
if (commandText.IndexOf("@SearchTermContains", StringComparison.OrdinalIgnoreCase) != -1)
|
||||||
{
|
{
|
||||||
statement.TryBind("@SearchTermContains", "%" + searchTerm + "%");
|
statement.TryBind("@SearchTermContains", "%" + searchTerm + "%");
|
||||||
@ -2745,6 +2814,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
items[i] = newItem;
|
items[i] = newItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2837,6 +2907,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
statementTexts.Add(commandText);
|
statementTexts.Add(commandText);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.EnableTotalRecordCount)
|
if (query.EnableTotalRecordCount)
|
||||||
{
|
{
|
||||||
commandText = string.Empty;
|
commandText = string.Empty;
|
||||||
@ -3241,6 +3312,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
statementTexts.Add(commandText);
|
statementTexts.Add(commandText);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.EnableTotalRecordCount)
|
if (query.EnableTotalRecordCount)
|
||||||
{
|
{
|
||||||
commandText = string.Empty;
|
commandText = string.Empty;
|
||||||
@ -3594,11 +3666,13 @@ namespace Emby.Server.Implementations.Data
|
|||||||
whereClauses.Add("IndexNumber=@IndexNumber");
|
whereClauses.Add("IndexNumber=@IndexNumber");
|
||||||
statement?.TryBind("@IndexNumber", query.IndexNumber.Value);
|
statement?.TryBind("@IndexNumber", query.IndexNumber.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.ParentIndexNumber.HasValue)
|
if (query.ParentIndexNumber.HasValue)
|
||||||
{
|
{
|
||||||
whereClauses.Add("ParentIndexNumber=@ParentIndexNumber");
|
whereClauses.Add("ParentIndexNumber=@ParentIndexNumber");
|
||||||
statement?.TryBind("@ParentIndexNumber", query.ParentIndexNumber.Value);
|
statement?.TryBind("@ParentIndexNumber", query.ParentIndexNumber.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.ParentIndexNumberNotEquals.HasValue)
|
if (query.ParentIndexNumberNotEquals.HasValue)
|
||||||
{
|
{
|
||||||
whereClauses.Add("(ParentIndexNumber<>@ParentIndexNumberNotEquals or ParentIndexNumber is null)");
|
whereClauses.Add("(ParentIndexNumber<>@ParentIndexNumberNotEquals or ParentIndexNumber is null)");
|
||||||
@ -3884,6 +3958,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
statement.TryBind(paramName, artistId.ToByteArray());
|
statement.TryBind(paramName, artistId.ToByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3904,6 +3979,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
statement.TryBind(paramName, artistId.ToByteArray());
|
statement.TryBind(paramName, artistId.ToByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3924,8 +4000,10 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
statement.TryBind(paramName, artistId.ToByteArray());
|
statement.TryBind(paramName, artistId.ToByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var clause = "(" + string.Join(" OR ", clauses) + ")";
|
var clause = "(" + string.Join(" OR ", clauses) + ")";
|
||||||
whereClauses.Add(clause);
|
whereClauses.Add(clause);
|
||||||
}
|
}
|
||||||
@ -3943,8 +4021,10 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
statement.TryBind(paramName, albumId.ToByteArray());
|
statement.TryBind(paramName, albumId.ToByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var clause = "(" + string.Join(" OR ", clauses) + ")";
|
var clause = "(" + string.Join(" OR ", clauses) + ")";
|
||||||
whereClauses.Add(clause);
|
whereClauses.Add(clause);
|
||||||
}
|
}
|
||||||
@ -3962,8 +4042,10 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
statement.TryBind(paramName, artistId.ToByteArray());
|
statement.TryBind(paramName, artistId.ToByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var clause = "(" + string.Join(" OR ", clauses) + ")";
|
var clause = "(" + string.Join(" OR ", clauses) + ")";
|
||||||
whereClauses.Add(clause);
|
whereClauses.Add(clause);
|
||||||
}
|
}
|
||||||
@ -3981,8 +4063,10 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
statement.TryBind(paramName, genreId.ToByteArray());
|
statement.TryBind(paramName, genreId.ToByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var clause = "(" + string.Join(" OR ", clauses) + ")";
|
var clause = "(" + string.Join(" OR ", clauses) + ")";
|
||||||
whereClauses.Add(clause);
|
whereClauses.Add(clause);
|
||||||
}
|
}
|
||||||
@ -3998,8 +4082,10 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
statement.TryBind("@Genre" + index, GetCleanValue(item));
|
statement.TryBind("@Genre" + index, GetCleanValue(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var clause = "(" + string.Join(" OR ", clauses) + ")";
|
var clause = "(" + string.Join(" OR ", clauses) + ")";
|
||||||
whereClauses.Add(clause);
|
whereClauses.Add(clause);
|
||||||
}
|
}
|
||||||
@ -4015,8 +4101,10 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
statement.TryBind("@Tag" + index, GetCleanValue(item));
|
statement.TryBind("@Tag" + index, GetCleanValue(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var clause = "(" + string.Join(" OR ", clauses) + ")";
|
var clause = "(" + string.Join(" OR ", clauses) + ")";
|
||||||
whereClauses.Add(clause);
|
whereClauses.Add(clause);
|
||||||
}
|
}
|
||||||
@ -4032,8 +4120,10 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
statement.TryBind("@ExcludeTag" + index, GetCleanValue(item));
|
statement.TryBind("@ExcludeTag" + index, GetCleanValue(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var clause = "(" + string.Join(" OR ", clauses) + ")";
|
var clause = "(" + string.Join(" OR ", clauses) + ")";
|
||||||
whereClauses.Add(clause);
|
whereClauses.Add(clause);
|
||||||
}
|
}
|
||||||
@ -4052,8 +4142,10 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
statement.TryBind(paramName, studioId.ToByteArray());
|
statement.TryBind(paramName, studioId.ToByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var clause = "(" + string.Join(" OR ", clauses) + ")";
|
var clause = "(" + string.Join(" OR ", clauses) + ")";
|
||||||
whereClauses.Add(clause);
|
whereClauses.Add(clause);
|
||||||
}
|
}
|
||||||
@ -4069,8 +4161,10 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
statement.TryBind("@OfficialRating" + index, item);
|
statement.TryBind("@OfficialRating" + index, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var clause = "(" + string.Join(" OR ", clauses) + ")";
|
var clause = "(" + string.Join(" OR ", clauses) + ")";
|
||||||
whereClauses.Add(clause);
|
whereClauses.Add(clause);
|
||||||
}
|
}
|
||||||
@ -4245,6 +4339,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
statement.TryBind("@IsVirtualItem", isVirtualItem.Value);
|
statement.TryBind("@IsVirtualItem", isVirtualItem.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.IsSpecialSeason.HasValue)
|
if (query.IsSpecialSeason.HasValue)
|
||||||
{
|
{
|
||||||
if (query.IsSpecialSeason.Value)
|
if (query.IsSpecialSeason.Value)
|
||||||
@ -4256,6 +4351,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
whereClauses.Add("IndexNumber <> 0");
|
whereClauses.Add("IndexNumber <> 0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.IsUnaired.HasValue)
|
if (query.IsUnaired.HasValue)
|
||||||
{
|
{
|
||||||
if (query.IsUnaired.Value)
|
if (query.IsUnaired.Value)
|
||||||
@ -4267,6 +4363,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
whereClauses.Add("PremiereDate < DATETIME('now')");
|
whereClauses.Add("PremiereDate < DATETIME('now')");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var queryMediaTypes = query.MediaTypes.Where(IsValidMediaType).ToArray();
|
var queryMediaTypes = query.MediaTypes.Where(IsValidMediaType).ToArray();
|
||||||
if (queryMediaTypes.Length == 1)
|
if (queryMediaTypes.Length == 1)
|
||||||
{
|
{
|
||||||
@ -4282,6 +4379,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
|
|
||||||
whereClauses.Add("MediaType in (" + val + ")");
|
whereClauses.Add("MediaType in (" + val + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.ItemIds.Length > 0)
|
if (query.ItemIds.Length > 0)
|
||||||
{
|
{
|
||||||
var includeIds = new List<string>();
|
var includeIds = new List<string>();
|
||||||
@ -4294,11 +4392,13 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
statement.TryBind("@IncludeId" + index, id);
|
statement.TryBind("@IncludeId" + index, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
whereClauses.Add("(" + string.Join(" OR ", includeIds) + ")");
|
whereClauses.Add("(" + string.Join(" OR ", includeIds) + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.ExcludeItemIds.Length > 0)
|
if (query.ExcludeItemIds.Length > 0)
|
||||||
{
|
{
|
||||||
var excludeIds = new List<string>();
|
var excludeIds = new List<string>();
|
||||||
@ -4311,6 +4411,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
statement.TryBind("@ExcludeId" + index, id);
|
statement.TryBind("@ExcludeId" + index, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4335,6 +4436,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
statement.TryBind(paramName, "%" + pair.Key + "=" + pair.Value + "%");
|
statement.TryBind(paramName, "%" + pair.Key + "=" + pair.Value + "%");
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -4360,7 +4462,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
|
|
||||||
// TODO this seems to be an idea for a better schema where ProviderIds are their own table
|
// TODO this seems to be an idea for a better schema where ProviderIds are their own table
|
||||||
// buut this is not implemented
|
// buut this is not implemented
|
||||||
//hasProviderIds.Add("(COALESCE((select value from ProviderIds where ItemId=Guid and Name = '" + pair.Key + "'), '') <> " + paramName + ")");
|
// hasProviderIds.Add("(COALESCE((select value from ProviderIds where ItemId=Guid and Name = '" + pair.Key + "'), '') <> " + paramName + ")");
|
||||||
|
|
||||||
// TODO this is a really BAD way to do it since the pair:
|
// TODO this is a really BAD way to do it since the pair:
|
||||||
// Tmdb, 1234 matches Tmdb=1234 but also Tmdb=1234567
|
// Tmdb, 1234 matches Tmdb=1234 but also Tmdb=1234567
|
||||||
@ -4377,6 +4479,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
statement.TryBind(paramName, "%" + pair.Key + "=" + pair.Value + "%");
|
statement.TryBind(paramName, "%" + pair.Key + "=" + pair.Value + "%");
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -4427,6 +4530,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
whereClauses.Add("(TopParentId=@TopParentId)");
|
whereClauses.Add("(TopParentId=@TopParentId)");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statement != null)
|
if (statement != null)
|
||||||
{
|
{
|
||||||
statement.TryBind("@TopParentId", queryTopParentIds[0].ToString("N", CultureInfo.InvariantCulture));
|
statement.TryBind("@TopParentId", queryTopParentIds[0].ToString("N", CultureInfo.InvariantCulture));
|
||||||
@ -4464,11 +4568,13 @@ namespace Emby.Server.Implementations.Data
|
|||||||
statement.TryBind("@AncestorId", query.AncestorIds[0]);
|
statement.TryBind("@AncestorId", query.AncestorIds[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.AncestorIds.Length > 1)
|
if (query.AncestorIds.Length > 1)
|
||||||
{
|
{
|
||||||
var inClause = string.Join(",", query.AncestorIds.Select(i => "'" + i.ToString("N", CultureInfo.InvariantCulture) + "'"));
|
var inClause = string.Join(",", query.AncestorIds.Select(i => "'" + i.ToString("N", CultureInfo.InvariantCulture) + "'"));
|
||||||
whereClauses.Add(string.Format("Guid in (select itemId from AncestorIds where AncestorIdText in ({0}))", inClause));
|
whereClauses.Add(string.Format("Guid in (select itemId from AncestorIds where AncestorIdText in ({0}))", inClause));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(query.AncestorWithPresentationUniqueKey))
|
if (!string.IsNullOrWhiteSpace(query.AncestorWithPresentationUniqueKey))
|
||||||
{
|
{
|
||||||
var inClause = "select guid from TypedBaseItems where PresentationUniqueKey=@AncestorWithPresentationUniqueKey";
|
var inClause = "select guid from TypedBaseItems where PresentationUniqueKey=@AncestorWithPresentationUniqueKey";
|
||||||
@ -4497,6 +4603,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
statement.TryBind("@UnratedType", query.BlockUnratedItems[0].ToString());
|
statement.TryBind("@UnratedType", query.BlockUnratedItems[0].ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.BlockUnratedItems.Length > 1)
|
if (query.BlockUnratedItems.Length > 1)
|
||||||
{
|
{
|
||||||
var inClause = string.Join(",", query.BlockUnratedItems.Select(i => "'" + i.ToString() + "'"));
|
var inClause = string.Join(",", query.BlockUnratedItems.Select(i => "'" + i.ToString() + "'"));
|
||||||
@ -4789,7 +4896,6 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
|
|||||||
connection.RunInTransaction(db =>
|
connection.RunInTransaction(db =>
|
||||||
{
|
{
|
||||||
connection.ExecuteAll(sql);
|
connection.ExecuteAll(sql);
|
||||||
|
|
||||||
}, TransactionMode);
|
}, TransactionMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4972,6 +5078,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
|
|||||||
statement.TryBind("@ItemId", query.ItemId.ToByteArray());
|
statement.TryBind("@ItemId", query.ItemId.ToByteArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!query.AppearsInItemId.Equals(Guid.Empty))
|
if (!query.AppearsInItemId.Equals(Guid.Empty))
|
||||||
{
|
{
|
||||||
whereClauses.Add("Name in (Select Name from People where ItemId=@AppearsInItemId)");
|
whereClauses.Add("Name in (Select Name from People where ItemId=@AppearsInItemId)");
|
||||||
@ -4980,6 +5087,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
|
|||||||
statement.TryBind("@AppearsInItemId", query.AppearsInItemId.ToByteArray());
|
statement.TryBind("@AppearsInItemId", query.AppearsInItemId.ToByteArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var queryPersonTypes = query.PersonTypes.Where(IsValidPersonType).ToList();
|
var queryPersonTypes = query.PersonTypes.Where(IsValidPersonType).ToList();
|
||||||
|
|
||||||
if (queryPersonTypes.Count == 1)
|
if (queryPersonTypes.Count == 1)
|
||||||
@ -4996,6 +5104,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
|
|||||||
|
|
||||||
whereClauses.Add("PersonType in (" + val + ")");
|
whereClauses.Add("PersonType in (" + val + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
var queryExcludePersonTypes = query.ExcludePersonTypes.Where(IsValidPersonType).ToList();
|
var queryExcludePersonTypes = query.ExcludePersonTypes.Where(IsValidPersonType).ToList();
|
||||||
|
|
||||||
if (queryExcludePersonTypes.Count == 1)
|
if (queryExcludePersonTypes.Count == 1)
|
||||||
@ -5012,6 +5121,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
|
|||||||
|
|
||||||
whereClauses.Add("PersonType not in (" + val + ")");
|
whereClauses.Add("PersonType not in (" + val + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.MaxListOrder.HasValue)
|
if (query.MaxListOrder.HasValue)
|
||||||
{
|
{
|
||||||
whereClauses.Add("ListOrder<=@MaxListOrder");
|
whereClauses.Add("ListOrder<=@MaxListOrder");
|
||||||
@ -5020,6 +5130,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
|
|||||||
statement.TryBind("@MaxListOrder", query.MaxListOrder.Value);
|
statement.TryBind("@MaxListOrder", query.MaxListOrder.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(query.NameContains))
|
if (!string.IsNullOrWhiteSpace(query.NameContains))
|
||||||
{
|
{
|
||||||
whereClauses.Add("Name like @NameContains");
|
whereClauses.Add("Name like @NameContains");
|
||||||
@ -5159,6 +5270,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
|
|||||||
var typeString = string.Join(",", withItemTypes.Select(i => "'" + i + "'"));
|
var typeString = string.Join(",", withItemTypes.Select(i => "'" + i + "'"));
|
||||||
commandText += " AND ItemId In (select guid from typedbaseitems where type in (" + typeString + "))";
|
commandText += " AND ItemId In (select guid from typedbaseitems where type in (" + typeString + "))";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (excludeItemTypes.Count > 0)
|
if (excludeItemTypes.Count > 0)
|
||||||
{
|
{
|
||||||
var typeString = string.Join(",", excludeItemTypes.Select(i => "'" + i + "'"));
|
var typeString = string.Join(",", excludeItemTypes.Select(i => "'" + i + "'"));
|
||||||
@ -5180,7 +5292,6 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LogQueryTime("GetItemValueNames", commandText, now);
|
LogQueryTime("GetItemValueNames", commandText, now);
|
||||||
@ -5631,7 +5742,6 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
|
|||||||
db.Execute("delete from People where ItemId=@ItemId", itemIdBlob);
|
db.Execute("delete from People where ItemId=@ItemId", itemIdBlob);
|
||||||
|
|
||||||
InsertPeople(itemIdBlob, people, db);
|
InsertPeople(itemIdBlob, people, db);
|
||||||
|
|
||||||
}, TransactionMode);
|
}, TransactionMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5788,7 +5898,6 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
|
|||||||
db.Execute("delete from mediastreams where ItemId=@ItemId", itemIdBlob);
|
db.Execute("delete from mediastreams where ItemId=@ItemId", itemIdBlob);
|
||||||
|
|
||||||
InsertMediaStreams(itemIdBlob, streams, db);
|
InsertMediaStreams(itemIdBlob, streams, db);
|
||||||
|
|
||||||
}, TransactionMode);
|
}, TransactionMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6134,7 +6243,6 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
|
|||||||
db.Execute("delete from mediaattachments where ItemId=@ItemId", itemIdBlob);
|
db.Execute("delete from mediaattachments where ItemId=@ItemId", itemIdBlob);
|
||||||
|
|
||||||
InsertMediaAttachments(itemIdBlob, attachments, db, cancellationToken);
|
InsertMediaAttachments(itemIdBlob, attachments, db, cancellationToken);
|
||||||
|
|
||||||
}, TransactionMode);
|
}, TransactionMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
@ -134,10 +135,12 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(userData));
|
throw new ArgumentNullException(nameof(userData));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (internalUserId <= 0)
|
if (internalUserId <= 0)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(internalUserId));
|
throw new ArgumentNullException(nameof(internalUserId));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(key))
|
if (string.IsNullOrEmpty(key))
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(key));
|
throw new ArgumentNullException(nameof(key));
|
||||||
@ -152,6 +155,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(userData));
|
throw new ArgumentNullException(nameof(userData));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (internalUserId <= 0)
|
if (internalUserId <= 0)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(internalUserId));
|
throw new ArgumentNullException(nameof(internalUserId));
|
||||||
@ -234,7 +238,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Persist all user data for the specified user
|
/// Persist all user data for the specified user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void PersistAllUserData(long internalUserId, UserItemData[] userDataList, CancellationToken cancellationToken)
|
private void PersistAllUserData(long internalUserId, UserItemData[] userDataList, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
@ -308,7 +312,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return all user-data associated with the given user
|
/// Return all user-data associated with the given user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="internalUserId"></param>
|
/// <param name="internalUserId"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
@ -338,7 +342,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read a row from the specified reader into the provided userData object
|
/// Read a row from the specified reader into the provided userData object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="reader"></param>
|
/// <param name="reader"></param>
|
||||||
private UserItemData ReadRow(IReadOnlyList<IResultSetValue> reader)
|
private UserItemData ReadRow(IReadOnlyList<IResultSetValue> reader)
|
||||||
@ -346,7 +350,7 @@ namespace Emby.Server.Implementations.Data
|
|||||||
var userData = new UserItemData();
|
var userData = new UserItemData();
|
||||||
|
|
||||||
userData.Key = reader[0].ToString();
|
userData.Key = reader[0].ToString();
|
||||||
//userData.UserId = reader[1].ReadGuidFromBlob();
|
// userData.UserId = reader[1].ReadGuidFromBlob();
|
||||||
|
|
||||||
if (reader[2].SQLiteType != SQLiteType.Null)
|
if (reader[2].SQLiteType != SQLiteType.Null)
|
||||||
{
|
{
|
||||||
|
@ -1,240 +0,0 @@
|
|||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Text.Json;
|
|
||||||
using MediaBrowser.Common.Json;
|
|
||||||
using MediaBrowser.Controller;
|
|
||||||
using MediaBrowser.Controller.Entities;
|
|
||||||
using MediaBrowser.Controller.Persistence;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using SQLitePCL.pretty;
|
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Data
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Class SQLiteUserRepository
|
|
||||||
/// </summary>
|
|
||||||
public class SqliteUserRepository : BaseSqliteRepository, IUserRepository
|
|
||||||
{
|
|
||||||
private readonly JsonSerializerOptions _jsonOptions;
|
|
||||||
|
|
||||||
public SqliteUserRepository(
|
|
||||||
ILogger<SqliteUserRepository> logger,
|
|
||||||
IServerApplicationPaths appPaths)
|
|
||||||
: base(logger)
|
|
||||||
{
|
|
||||||
_jsonOptions = JsonDefaults.GetOptions();
|
|
||||||
|
|
||||||
DbFilePath = Path.Combine(appPaths.DataPath, "users.db");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the name of the repository
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The name.</value>
|
|
||||||
public string Name => "SQLite";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Opens the connection to the database.
|
|
||||||
/// </summary>
|
|
||||||
public void Initialize()
|
|
||||||
{
|
|
||||||
using (var connection = GetConnection())
|
|
||||||
{
|
|
||||||
var localUsersTableExists = TableExists(connection, "LocalUsersv2");
|
|
||||||
|
|
||||||
connection.RunQueries(new[] {
|
|
||||||
"create table if not exists LocalUsersv2 (Id INTEGER PRIMARY KEY, guid GUID NOT NULL, data BLOB NOT NULL)",
|
|
||||||
"drop index if exists idx_users"
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!localUsersTableExists && TableExists(connection, "Users"))
|
|
||||||
{
|
|
||||||
TryMigrateToLocalUsersTable(connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveEmptyPasswordHashes(connection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void TryMigrateToLocalUsersTable(ManagedConnection connection)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
connection.RunQueries(new[]
|
|
||||||
{
|
|
||||||
"INSERT INTO LocalUsersv2 (guid, data) SELECT guid,data from users"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logger.LogError(ex, "Error migrating users database");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RemoveEmptyPasswordHashes(ManagedConnection connection)
|
|
||||||
{
|
|
||||||
foreach (var user in RetrieveAllUsers(connection))
|
|
||||||
{
|
|
||||||
// If the user password is the sha1 hash of the empty string, remove it
|
|
||||||
if (!string.Equals(user.Password, "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", StringComparison.Ordinal)
|
|
||||||
&& !string.Equals(user.Password, "$SHA1$DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
user.Password = null;
|
|
||||||
var serialized = JsonSerializer.SerializeToUtf8Bytes(user, _jsonOptions);
|
|
||||||
|
|
||||||
connection.RunInTransaction(db =>
|
|
||||||
{
|
|
||||||
using (var statement = db.PrepareStatement("update LocalUsersv2 set data=@data where Id=@InternalId"))
|
|
||||||
{
|
|
||||||
statement.TryBind("@InternalId", user.InternalId);
|
|
||||||
statement.TryBind("@data", serialized);
|
|
||||||
statement.MoveNext();
|
|
||||||
}
|
|
||||||
}, TransactionMode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Save a user in the repo
|
|
||||||
/// </summary>
|
|
||||||
public void CreateUser(User user)
|
|
||||||
{
|
|
||||||
if (user == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
var serialized = JsonSerializer.SerializeToUtf8Bytes(user, _jsonOptions);
|
|
||||||
|
|
||||||
using (var connection = GetConnection())
|
|
||||||
{
|
|
||||||
connection.RunInTransaction(db =>
|
|
||||||
{
|
|
||||||
using (var statement = db.PrepareStatement("insert into LocalUsersv2 (guid, data) values (@guid, @data)"))
|
|
||||||
{
|
|
||||||
statement.TryBind("@guid", user.Id.ToByteArray());
|
|
||||||
statement.TryBind("@data", serialized);
|
|
||||||
|
|
||||||
statement.MoveNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
var createdUser = GetUser(user.Id, connection);
|
|
||||||
|
|
||||||
if (createdUser == null)
|
|
||||||
{
|
|
||||||
throw new ApplicationException("created user should never be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
user.InternalId = createdUser.InternalId;
|
|
||||||
|
|
||||||
}, TransactionMode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateUser(User user)
|
|
||||||
{
|
|
||||||
if (user == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
var serialized = JsonSerializer.SerializeToUtf8Bytes(user, _jsonOptions);
|
|
||||||
|
|
||||||
using (var connection = GetConnection())
|
|
||||||
{
|
|
||||||
connection.RunInTransaction(db =>
|
|
||||||
{
|
|
||||||
using (var statement = db.PrepareStatement("update LocalUsersv2 set data=@data where Id=@InternalId"))
|
|
||||||
{
|
|
||||||
statement.TryBind("@InternalId", user.InternalId);
|
|
||||||
statement.TryBind("@data", serialized);
|
|
||||||
statement.MoveNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
}, TransactionMode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private User GetUser(Guid guid, ManagedConnection connection)
|
|
||||||
{
|
|
||||||
using (var statement = connection.PrepareStatement("select id,guid,data from LocalUsersv2 where guid=@guid"))
|
|
||||||
{
|
|
||||||
statement.TryBind("@guid", guid);
|
|
||||||
|
|
||||||
foreach (var row in statement.ExecuteQuery())
|
|
||||||
{
|
|
||||||
return GetUser(row);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private User GetUser(IReadOnlyList<IResultSetValue> row)
|
|
||||||
{
|
|
||||||
var id = row[0].ToInt64();
|
|
||||||
var guid = row[1].ReadGuidFromBlob();
|
|
||||||
|
|
||||||
var user = JsonSerializer.Deserialize<User>(row[2].ToBlob(), _jsonOptions);
|
|
||||||
user.InternalId = id;
|
|
||||||
user.Id = guid;
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieve all users from the database
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>IEnumerable{User}.</returns>
|
|
||||||
public List<User> RetrieveAllUsers()
|
|
||||||
{
|
|
||||||
using (var connection = GetConnection(true))
|
|
||||||
{
|
|
||||||
return new List<User>(RetrieveAllUsers(connection));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieve all users from the database
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>IEnumerable{User}.</returns>
|
|
||||||
private IEnumerable<User> RetrieveAllUsers(ManagedConnection connection)
|
|
||||||
{
|
|
||||||
foreach (var row in connection.Query("select id,guid,data from LocalUsersv2"))
|
|
||||||
{
|
|
||||||
yield return GetUser(row);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deletes the user.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user">The user.</param>
|
|
||||||
/// <returns>Task.</returns>
|
|
||||||
/// <exception cref="ArgumentNullException">user</exception>
|
|
||||||
public void DeleteUser(User user)
|
|
||||||
{
|
|
||||||
if (user == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
using (var connection = GetConnection())
|
|
||||||
{
|
|
||||||
connection.RunInTransaction(db =>
|
|
||||||
{
|
|
||||||
using (var statement = db.PrepareStatement("delete from LocalUsersv2 where Id=@id"))
|
|
||||||
{
|
|
||||||
statement.TryBind("@id", user.InternalId);
|
|
||||||
statement.MoveNext();
|
|
||||||
}
|
|
||||||
}, TransactionMode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,10 +5,11 @@ using System.Collections.Generic;
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Jellyfin.Data.Enums;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Devices;
|
using MediaBrowser.Controller.Devices;
|
||||||
using MediaBrowser.Controller.Entities;
|
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Security;
|
using MediaBrowser.Controller.Security;
|
||||||
using MediaBrowser.Model.Devices;
|
using MediaBrowser.Model.Devices;
|
||||||
@ -16,7 +17,6 @@ using MediaBrowser.Model.Events;
|
|||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using MediaBrowser.Model.Session;
|
using MediaBrowser.Model.Session;
|
||||||
using MediaBrowser.Model.Users;
|
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Devices
|
namespace Emby.Server.Implementations.Devices
|
||||||
{
|
{
|
||||||
@ -27,11 +27,10 @@ namespace Emby.Server.Implementations.Devices
|
|||||||
private readonly IServerConfigurationManager _config;
|
private readonly IServerConfigurationManager _config;
|
||||||
private readonly IAuthenticationRepository _authRepo;
|
private readonly IAuthenticationRepository _authRepo;
|
||||||
private readonly Dictionary<string, ClientCapabilities> _capabilitiesCache;
|
private readonly Dictionary<string, ClientCapabilities> _capabilitiesCache;
|
||||||
|
private readonly object _capabilitiesSyncLock = new object();
|
||||||
|
|
||||||
public event EventHandler<GenericEventArgs<Tuple<string, DeviceOptions>>> DeviceOptionsUpdated;
|
public event EventHandler<GenericEventArgs<Tuple<string, DeviceOptions>>> DeviceOptionsUpdated;
|
||||||
|
|
||||||
private readonly object _capabilitiesSyncLock = new object();
|
|
||||||
|
|
||||||
public DeviceManager(
|
public DeviceManager(
|
||||||
IAuthenticationRepository authRepo,
|
IAuthenticationRepository authRepo,
|
||||||
IJsonSerializer json,
|
IJsonSerializer json,
|
||||||
@ -113,7 +112,7 @@ namespace Emby.Server.Implementations.Devices
|
|||||||
{
|
{
|
||||||
IEnumerable<AuthenticationInfo> sessions = _authRepo.Get(new AuthenticationInfoQuery
|
IEnumerable<AuthenticationInfo> sessions = _authRepo.Get(new AuthenticationInfoQuery
|
||||||
{
|
{
|
||||||
//UserId = query.UserId
|
// UserId = query.UserId
|
||||||
HasUser = true
|
HasUser = true
|
||||||
}).Items;
|
}).Items;
|
||||||
|
|
||||||
@ -170,12 +169,18 @@ namespace Emby.Server.Implementations.Devices
|
|||||||
{
|
{
|
||||||
throw new ArgumentException("user not found");
|
throw new ArgumentException("user not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(deviceId))
|
if (string.IsNullOrEmpty(deviceId))
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(deviceId));
|
throw new ArgumentNullException(nameof(deviceId));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CanAccessDevice(user.Policy, deviceId))
|
if (user.HasPermission(PermissionKind.EnableAllDevices) || user.HasPermission(PermissionKind.IsAdministrator))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user.GetPreference(PreferenceKind.EnabledDevices).Contains(deviceId, StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
var capabilities = GetCapabilities(deviceId);
|
var capabilities = GetCapabilities(deviceId);
|
||||||
|
|
||||||
@ -187,20 +192,5 @@ namespace Emby.Server.Implementations.Devices
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool CanAccessDevice(UserPolicy policy, string id)
|
|
||||||
{
|
|
||||||
if (policy.EnableAllDevices)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (policy.IsAdministrator)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return policy.EnabledDevices.Contains(id, StringComparer.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,14 @@ using System.Globalization;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Common;
|
using MediaBrowser.Common;
|
||||||
using MediaBrowser.Controller.Channels;
|
using MediaBrowser.Controller.Channels;
|
||||||
using MediaBrowser.Controller.Drawing;
|
using MediaBrowser.Controller.Drawing;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
using MediaBrowser.Controller.Entities.Movies;
|
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.LiveTv;
|
using MediaBrowser.Controller.LiveTv;
|
||||||
using MediaBrowser.Controller.Persistence;
|
using MediaBrowser.Controller.Persistence;
|
||||||
@ -24,6 +24,14 @@ using MediaBrowser.Model.Dto;
|
|||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Book = MediaBrowser.Controller.Entities.Book;
|
||||||
|
using Episode = MediaBrowser.Controller.Entities.TV.Episode;
|
||||||
|
using Movie = MediaBrowser.Controller.Entities.Movies.Movie;
|
||||||
|
using MusicAlbum = MediaBrowser.Controller.Entities.Audio.MusicAlbum;
|
||||||
|
using Person = MediaBrowser.Controller.Entities.Person;
|
||||||
|
using Photo = MediaBrowser.Controller.Entities.Photo;
|
||||||
|
using Season = MediaBrowser.Controller.Entities.TV.Season;
|
||||||
|
using Series = MediaBrowser.Controller.Entities.TV.Series;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Dto
|
namespace Emby.Server.Implementations.Dto
|
||||||
{
|
{
|
||||||
@ -66,7 +74,7 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts a BaseItem to a DTOBaseItem
|
/// Converts a BaseItem to a DTOBaseItem.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="item">The item.</param>
|
||||||
/// <param name="fields">The fields.</param>
|
/// <param name="fields">The fields.</param>
|
||||||
@ -269,6 +277,7 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
dto.EpisodeTitle = dto.Name;
|
dto.EpisodeTitle = dto.Name;
|
||||||
dto.Name = dto.SeriesName;
|
dto.Name = dto.SeriesName;
|
||||||
}
|
}
|
||||||
|
|
||||||
liveTvManager.AddInfoToRecordingDto(item, dto, activeRecording, user);
|
liveTvManager.AddInfoToRecordingDto(item, dto, activeRecording, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,6 +293,7 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var containers = container.Split(new[] { ',' });
|
var containers = container.Split(new[] { ',' });
|
||||||
if (containers.Length < 2)
|
if (containers.Length < 2)
|
||||||
{
|
{
|
||||||
@ -384,7 +394,7 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
|
|
||||||
if (options.ContainsField(ItemFields.ChildCount))
|
if (options.ContainsField(ItemFields.ChildCount))
|
||||||
{
|
{
|
||||||
dto.ChildCount = dto.ChildCount ?? GetChildCount(folder, user);
|
dto.ChildCount ??= GetChildCount(folder, user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,7 +408,6 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
dto.DateLastMediaAdded = folder.DateLastMediaAdded;
|
dto.DateLastMediaAdded = folder.DateLastMediaAdded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (options.EnableUserData)
|
if (options.EnableUserData)
|
||||||
@ -414,7 +423,7 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
|
|
||||||
if (options.ContainsField(ItemFields.BasicSyncInfo))
|
if (options.ContainsField(ItemFields.BasicSyncInfo))
|
||||||
{
|
{
|
||||||
var userCanSync = user != null && user.Policy.EnableContentDownloading;
|
var userCanSync = user != null && user.HasPermission(PermissionKind.EnableContentDownloading);
|
||||||
if (userCanSync && item.SupportsExternalTransfer)
|
if (userCanSync && item.SupportsExternalTransfer)
|
||||||
{
|
{
|
||||||
dto.SupportsSync = true;
|
dto.SupportsSync = true;
|
||||||
@ -435,7 +444,7 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets client-side Id of a server-side BaseItem
|
/// Gets client-side Id of a server-side BaseItem.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="item">The item.</param>
|
||||||
/// <returns>System.String.</returns>
|
/// <returns>System.String.</returns>
|
||||||
@ -449,6 +458,7 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
{
|
{
|
||||||
dto.SeriesName = item.SeriesName;
|
dto.SeriesName = item.SeriesName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SetPhotoProperties(BaseItemDto dto, Photo item)
|
private static void SetPhotoProperties(BaseItemDto dto, Photo item)
|
||||||
{
|
{
|
||||||
dto.CameraMake = item.CameraMake;
|
dto.CameraMake = item.CameraMake;
|
||||||
@ -530,7 +540,7 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Attaches People DTO's to a DTOBaseItem
|
/// Attaches People DTO's to a DTOBaseItem.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dto">The dto.</param>
|
/// <param name="dto">The dto.</param>
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="item">The item.</param>
|
||||||
@ -547,22 +557,27 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.IsType(PersonType.GuestStar))
|
if (i.IsType(PersonType.GuestStar))
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.IsType(PersonType.Director))
|
if (i.IsType(PersonType.Director))
|
||||||
{
|
{
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.IsType(PersonType.Writer))
|
if (i.IsType(PersonType.Writer))
|
||||||
{
|
{
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.IsType(PersonType.Producer))
|
if (i.IsType(PersonType.Producer))
|
||||||
{
|
{
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.IsType(PersonType.Composer))
|
if (i.IsType(PersonType.Composer))
|
||||||
{
|
{
|
||||||
return 4;
|
return 4;
|
||||||
@ -586,7 +601,6 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
_logger.LogError(ex, "Error getting person {Name}", c);
|
_logger.LogError(ex, "Error getting person {Name}", c);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}).Where(i => i != null)
|
}).Where(i => i != null)
|
||||||
.GroupBy(i => i.Name, StringComparer.OrdinalIgnoreCase)
|
.GroupBy(i => i.Name, StringComparer.OrdinalIgnoreCase)
|
||||||
.Select(x => x.First())
|
.Select(x => x.First())
|
||||||
@ -719,7 +733,7 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets simple property values on a DTOBaseItem
|
/// Sets simple property values on a DTOBaseItem.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dto">The dto.</param>
|
/// <param name="dto">The dto.</param>
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="item">The item.</param>
|
||||||
@ -939,7 +953,7 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
dto.AlbumPrimaryImageTag = GetTagAndFillBlurhash(dto, albumParent, ImageType.Primary);
|
dto.AlbumPrimaryImageTag = GetTagAndFillBlurhash(dto, albumParent, ImageType.Primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (options.ContainsField(ItemFields.MediaSourceCount))
|
// if (options.ContainsField(ItemFields.MediaSourceCount))
|
||||||
//{
|
//{
|
||||||
// Songs always have one
|
// Songs always have one
|
||||||
//}
|
//}
|
||||||
@ -949,13 +963,13 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
{
|
{
|
||||||
dto.Artists = hasArtist.Artists;
|
dto.Artists = hasArtist.Artists;
|
||||||
|
|
||||||
//var artistItems = _libraryManager.GetArtists(new InternalItemsQuery
|
// var artistItems = _libraryManager.GetArtists(new InternalItemsQuery
|
||||||
//{
|
//{
|
||||||
// EnableTotalRecordCount = false,
|
// EnableTotalRecordCount = false,
|
||||||
// ItemIds = new[] { item.Id.ToString("N", CultureInfo.InvariantCulture) }
|
// ItemIds = new[] { item.Id.ToString("N", CultureInfo.InvariantCulture) }
|
||||||
//});
|
//});
|
||||||
|
|
||||||
//dto.ArtistItems = artistItems.Items
|
// dto.ArtistItems = artistItems.Items
|
||||||
// .Select(i =>
|
// .Select(i =>
|
||||||
// {
|
// {
|
||||||
// var artist = i.Item1;
|
// var artist = i.Item1;
|
||||||
@ -968,7 +982,7 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
// .ToList();
|
// .ToList();
|
||||||
|
|
||||||
// Include artists that are not in the database yet, e.g., just added via metadata editor
|
// Include artists that are not in the database yet, e.g., just added via metadata editor
|
||||||
//var foundArtists = artistItems.Items.Select(i => i.Item1.Name).ToList();
|
// var foundArtists = artistItems.Items.Select(i => i.Item1.Name).ToList();
|
||||||
dto.ArtistItems = hasArtist.Artists
|
dto.ArtistItems = hasArtist.Artists
|
||||||
//.Except(foundArtists, new DistinctNameComparer())
|
//.Except(foundArtists, new DistinctNameComparer())
|
||||||
.Select(i =>
|
.Select(i =>
|
||||||
@ -993,7 +1007,6 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}).Where(i => i != null).ToArray();
|
}).Where(i => i != null).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1002,13 +1015,13 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
{
|
{
|
||||||
dto.AlbumArtist = hasAlbumArtist.AlbumArtists.FirstOrDefault();
|
dto.AlbumArtist = hasAlbumArtist.AlbumArtists.FirstOrDefault();
|
||||||
|
|
||||||
//var artistItems = _libraryManager.GetAlbumArtists(new InternalItemsQuery
|
// var artistItems = _libraryManager.GetAlbumArtists(new InternalItemsQuery
|
||||||
//{
|
//{
|
||||||
// EnableTotalRecordCount = false,
|
// EnableTotalRecordCount = false,
|
||||||
// ItemIds = new[] { item.Id.ToString("N", CultureInfo.InvariantCulture) }
|
// ItemIds = new[] { item.Id.ToString("N", CultureInfo.InvariantCulture) }
|
||||||
//});
|
//});
|
||||||
|
|
||||||
//dto.AlbumArtists = artistItems.Items
|
// dto.AlbumArtists = artistItems.Items
|
||||||
// .Select(i =>
|
// .Select(i =>
|
||||||
// {
|
// {
|
||||||
// var artist = i.Item1;
|
// var artist = i.Item1;
|
||||||
@ -1044,7 +1057,6 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}).Where(i => i != null).ToArray();
|
}).Where(i => i != null).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1158,7 +1170,7 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
|
|
||||||
// this block will add the series poster for episodes without a poster
|
// this block will add the series poster for episodes without a poster
|
||||||
// TODO maybe remove the if statement entirely
|
// TODO maybe remove the if statement entirely
|
||||||
//if (options.ContainsField(ItemFields.SeriesPrimaryImage))
|
// if (options.ContainsField(ItemFields.SeriesPrimaryImage))
|
||||||
{
|
{
|
||||||
episodeSeries = episodeSeries ?? episode.Series;
|
episodeSeries = episodeSeries ?? episode.Series;
|
||||||
if (episodeSeries != null)
|
if (episodeSeries != null)
|
||||||
@ -1204,7 +1216,7 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
|
|
||||||
// this block will add the series poster for seasons without a poster
|
// this block will add the series poster for seasons without a poster
|
||||||
// TODO maybe remove the if statement entirely
|
// TODO maybe remove the if statement entirely
|
||||||
//if (options.ContainsField(ItemFields.SeriesPrimaryImage))
|
// if (options.ContainsField(ItemFields.SeriesPrimaryImage))
|
||||||
{
|
{
|
||||||
series = series ?? season.Series;
|
series = series ?? season.Series;
|
||||||
if (series != null)
|
if (series != null)
|
||||||
@ -1342,6 +1354,7 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
dto.ParentLogoImageTag = GetTagAndFillBlurhash(dto, parent, image);
|
dto.ParentLogoImageTag = GetTagAndFillBlurhash(dto, parent, image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (artLimit > 0 && !(imageTags != null && imageTags.ContainsKey(ImageType.Art)) && dto.ParentArtItemId == null)
|
if (artLimit > 0 && !(imageTags != null && imageTags.ContainsKey(ImageType.Art)) && dto.ParentArtItemId == null)
|
||||||
{
|
{
|
||||||
var image = allImages.FirstOrDefault(i => i.Type == ImageType.Art);
|
var image = allImages.FirstOrDefault(i => i.Type == ImageType.Art);
|
||||||
@ -1352,6 +1365,7 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
dto.ParentArtImageTag = GetTagAndFillBlurhash(dto, parent, image);
|
dto.ParentArtImageTag = GetTagAndFillBlurhash(dto, parent, image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thumbLimit > 0 && !(imageTags != null && imageTags.ContainsKey(ImageType.Thumb)) && (dto.ParentThumbItemId == null || parent is Series) && !(parent is ICollectionFolder) && !(parent is UserView))
|
if (thumbLimit > 0 && !(imageTags != null && imageTags.ContainsKey(ImageType.Thumb)) && (dto.ParentThumbItemId == null || parent is Series) && !(parent is ICollectionFolder) && !(parent is UserView))
|
||||||
{
|
{
|
||||||
var image = allImages.FirstOrDefault(i => i.Type == ImageType.Thumb);
|
var image = allImages.FirstOrDefault(i => i.Type == ImageType.Thumb);
|
||||||
@ -1362,6 +1376,7 @@ namespace Emby.Server.Implementations.Dto
|
|||||||
dto.ParentThumbImageTag = GetTagAndFillBlurhash(dto, parent, image);
|
dto.ParentThumbImageTag = GetTagAndFillBlurhash(dto, parent, image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (backdropLimit > 0 && !((dto.BackdropImageTags != null && dto.BackdropImageTags.Length > 0) || (dto.ParentBackdropImageTags != null && dto.ParentBackdropImageTags.Length > 0)))
|
if (backdropLimit > 0 && !((dto.BackdropImageTags != null && dto.BackdropImageTags.Length > 0) || (dto.ParentBackdropImageTags != null && dto.ParentBackdropImageTags.Length > 0)))
|
||||||
{
|
{
|
||||||
var images = allImages.Where(i => i.Type == ImageType.Backdrop).Take(backdropLimit).ToList();
|
var images = allImages.Where(i => i.Type == ImageType.Backdrop).Take(backdropLimit).ToList();
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="IPNetwork2" Version="2.4.0.126" />
|
<PackageReference Include="IPNetwork2" Version="2.5.211" />
|
||||||
<PackageReference Include="Jellyfin.XmlTv" Version="10.4.3" />
|
<PackageReference Include="Jellyfin.XmlTv" Version="10.4.3" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
|
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
|
||||||
@ -41,7 +41,7 @@
|
|||||||
<PackageReference Include="Mono.Nat" Version="2.0.1" />
|
<PackageReference Include="Mono.Nat" Version="2.0.1" />
|
||||||
<PackageReference Include="prometheus-net.DotNetRuntime" Version="3.3.1" />
|
<PackageReference Include="prometheus-net.DotNetRuntime" Version="3.3.1" />
|
||||||
<PackageReference Include="ServiceStack.Text.Core" Version="5.9.0" />
|
<PackageReference Include="ServiceStack.Text.Core" Version="5.9.0" />
|
||||||
<PackageReference Include="sharpcompress" Version="0.25.0" />
|
<PackageReference Include="sharpcompress" Version="0.25.1" />
|
||||||
<PackageReference Include="SQLitePCL.pretty.netstandard" Version="2.1.0" />
|
<PackageReference Include="SQLitePCL.pretty.netstandard" Version="2.1.0" />
|
||||||
<PackageReference Include="DotNet.Glob" Version="3.0.9" />
|
<PackageReference Include="DotNet.Glob" Version="3.0.9" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -6,6 +6,7 @@ using System.Globalization;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
using MediaBrowser.Controller.Channels;
|
using MediaBrowser.Controller.Channels;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
@ -131,7 +132,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ using System;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.LiveTv;
|
using MediaBrowser.Controller.LiveTv;
|
||||||
using MediaBrowser.Controller.Plugins;
|
using MediaBrowser.Controller.Plugins;
|
||||||
@ -64,7 +65,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||||||
|
|
||||||
private async Task SendMessage(string name, TimerEventInfo info)
|
private async Task SendMessage(string name, TimerEventInfo info)
|
||||||
{
|
{
|
||||||
var users = _userManager.Users.Where(i => i.Policy.EnableLiveTvAccess).Select(i => i.Id).ToList();
|
var users = _userManager.Users.Where(i => i.HasPermission(PermissionKind.EnableLiveTvAccess)).Select(i => i.Id).ToList();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -1,77 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using MediaBrowser.Controller.Library;
|
|
||||||
using MediaBrowser.Controller.Providers;
|
|
||||||
using MediaBrowser.Model.IO;
|
|
||||||
using MediaBrowser.Model.Tasks;
|
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.EntryPoints
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Class RefreshUsersMetadata.
|
|
||||||
/// </summary>
|
|
||||||
public class RefreshUsersMetadata : IScheduledTask, IConfigurableScheduledTask
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The user manager.
|
|
||||||
/// </summary>
|
|
||||||
private readonly IUserManager _userManager;
|
|
||||||
private readonly IFileSystem _fileSystem;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="RefreshUsersMetadata" /> class.
|
|
||||||
/// </summary>
|
|
||||||
public RefreshUsersMetadata(IUserManager userManager, IFileSystem fileSystem)
|
|
||||||
{
|
|
||||||
_userManager = userManager;
|
|
||||||
_fileSystem = fileSystem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string Name => "Refresh Users";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string Key => "RefreshUsers";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string Description => "Refresh user infos";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string Category => "Library";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool IsHidden => true;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool IsEnabled => true;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool IsLogged => true;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
|
|
||||||
{
|
|
||||||
foreach (var user in _userManager.Users)
|
|
||||||
{
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
|
||||||
|
|
||||||
await user.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_fileSystem)), cancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
|
||||||
{
|
|
||||||
return new[]
|
|
||||||
{
|
|
||||||
new TaskTriggerInfo
|
|
||||||
{
|
|
||||||
IntervalTicks = TimeSpan.FromDays(1).Ticks,
|
|
||||||
Type = TaskTriggerInfo.TriggerInterval
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,10 +3,10 @@ using System.Collections.Generic;
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
using MediaBrowser.Common.Plugins;
|
using MediaBrowser.Common.Plugins;
|
||||||
using MediaBrowser.Common.Updates;
|
using MediaBrowser.Common.Updates;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Entities;
|
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Plugins;
|
using MediaBrowser.Controller.Plugins;
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
@ -68,10 +68,8 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task RunAsync()
|
public Task RunAsync()
|
||||||
{
|
{
|
||||||
_userManager.UserDeleted += OnUserDeleted;
|
_userManager.OnUserDeleted += OnUserDeleted;
|
||||||
_userManager.UserUpdated += OnUserUpdated;
|
_userManager.OnUserUpdated += OnUserUpdated;
|
||||||
_userManager.UserPolicyUpdated += OnUserPolicyUpdated;
|
|
||||||
_userManager.UserConfigurationUpdated += OnUserConfigurationUpdated;
|
|
||||||
|
|
||||||
_appHost.HasPendingRestartChanged += OnHasPendingRestartChanged;
|
_appHost.HasPendingRestartChanged += OnHasPendingRestartChanged;
|
||||||
|
|
||||||
@ -153,20 +151,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||||||
await SendMessageToUserSession(e.Argument, "UserDeleted", e.Argument.Id.ToString("N", CultureInfo.InvariantCulture)).ConfigureAwait(false);
|
await SendMessageToUserSession(e.Argument, "UserDeleted", e.Argument.Id.ToString("N", CultureInfo.InvariantCulture)).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OnUserPolicyUpdated(object sender, GenericEventArgs<User> e)
|
|
||||||
{
|
|
||||||
var dto = _userManager.GetUserDto(e.Argument);
|
|
||||||
|
|
||||||
await SendMessageToUserSession(e.Argument, "UserPolicyUpdated", dto).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void OnUserConfigurationUpdated(object sender, GenericEventArgs<User> e)
|
|
||||||
{
|
|
||||||
var dto = _userManager.GetUserDto(e.Argument);
|
|
||||||
|
|
||||||
await SendMessageToUserSession(e.Argument, "UserConfigurationUpdated", dto).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SendMessageToAdminSessions<T>(string name, T data)
|
private async Task SendMessageToAdminSessions<T>(string name, T data)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -175,7 +159,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,7 +174,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,10 +192,8 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||||||
{
|
{
|
||||||
if (dispose)
|
if (dispose)
|
||||||
{
|
{
|
||||||
_userManager.UserDeleted -= OnUserDeleted;
|
_userManager.OnUserDeleted -= OnUserDeleted;
|
||||||
_userManager.UserUpdated -= OnUserUpdated;
|
_userManager.OnUserUpdated -= OnUserUpdated;
|
||||||
_userManager.UserPolicyUpdated -= OnUserPolicyUpdated;
|
|
||||||
_userManager.UserConfigurationUpdated -= OnUserConfigurationUpdated;
|
|
||||||
|
|
||||||
_installationManager.PluginUninstalled -= OnPluginUninstalled;
|
_installationManager.PluginUninstalled -= OnPluginUninstalled;
|
||||||
_installationManager.PackageInstalling -= OnPackageInstalling;
|
_installationManager.PackageInstalling -= OnPackageInstalling;
|
||||||
|
@ -43,7 +43,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
_appHost = appHost;
|
_appHost = appHost;
|
||||||
_config = configuration;
|
_config = configuration;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -140,7 +140,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
|||||||
=> SendAsync(options, HttpMethod.Get);
|
=> SendAsync(options, HttpMethod.Get);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs a GET request and returns the resulting stream
|
/// Performs a GET request and returns the resulting stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="options">The options.</param>
|
/// <param name="options">The options.</param>
|
||||||
/// <returns>Task{Stream}.</returns>
|
/// <returns>Task{Stream}.</returns>
|
||||||
|
@ -32,12 +32,12 @@ namespace Emby.Server.Implementations.HttpServer
|
|||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _options
|
/// The _options.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IDictionary<string, string> _options = new Dictionary<string, string>();
|
private readonly IDictionary<string, string> _options = new Dictionary<string, string>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _requested ranges
|
/// The _requested ranges.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private List<KeyValuePair<long, long?>> _requestedRanges;
|
private List<KeyValuePair<long, long?>> _requestedRanges;
|
||||||
|
|
||||||
|
@ -453,6 +453,7 @@ namespace Emby.Server.Implementations.HttpServer
|
|||||||
{
|
{
|
||||||
httpRes.Headers.Add(key, value);
|
httpRes.Headers.Add(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
httpRes.ContentType = "text/plain";
|
httpRes.ContentType = "text/plain";
|
||||||
await httpRes.WriteAsync(string.Empty, cancellationToken).ConfigureAwait(false);
|
await httpRes.WriteAsync(string.Empty, cancellationToken).ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
@ -591,7 +592,7 @@ namespace Emby.Server.Implementations.HttpServer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the default CORS headers
|
/// Get the default CORS headers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="req"></param>
|
/// <param name="req"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
|
@ -580,7 +580,6 @@ namespace Emby.Server.Implementations.HttpServer
|
|||||||
}
|
}
|
||||||
catch (NotSupportedException)
|
catch (NotSupportedException)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -693,7 +692,7 @@ namespace Emby.Server.Implementations.HttpServer
|
|||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// When the browser sends the IfModifiedDate, it's precision is limited to seconds, so this will account for that
|
/// When the browser sends the IfModifiedDate, it's precision is limited to seconds, so this will account for that.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="date">The date.</param>
|
/// <param name="date">The date.</param>
|
||||||
/// <returns>DateTime.</returns>
|
/// <returns>DateTime.</returns>
|
||||||
|
@ -20,31 +20,37 @@ namespace Emby.Server.Implementations.HttpServer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The source stream.</value>
|
/// <value>The source stream.</value>
|
||||||
private Stream SourceStream { get; set; }
|
private Stream SourceStream { get; set; }
|
||||||
|
|
||||||
private string RangeHeader { get; set; }
|
private string RangeHeader { get; set; }
|
||||||
|
|
||||||
private bool IsHeadRequest { get; set; }
|
private bool IsHeadRequest { get; set; }
|
||||||
|
|
||||||
private long RangeStart { get; set; }
|
private long RangeStart { get; set; }
|
||||||
|
|
||||||
private long RangeEnd { get; set; }
|
private long RangeEnd { get; set; }
|
||||||
|
|
||||||
private long RangeLength { get; set; }
|
private long RangeLength { get; set; }
|
||||||
|
|
||||||
private long TotalContentLength { get; set; }
|
private long TotalContentLength { get; set; }
|
||||||
|
|
||||||
public Action OnComplete { get; set; }
|
public Action OnComplete { get; set; }
|
||||||
|
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
private const int BufferSize = 81920;
|
private const int BufferSize = 81920;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _options
|
/// The _options.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly Dictionary<string, string> _options = new Dictionary<string, string>();
|
private readonly Dictionary<string, string> _options = new Dictionary<string, string>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The us culture
|
/// The us culture.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Additional HTTP Headers
|
/// Additional HTTP Headers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The headers.</value>
|
/// <value>The headers.</value>
|
||||||
public IDictionary<string, string> Headers => _options;
|
public IDictionary<string, string> Headers => _options;
|
||||||
@ -110,7 +116,7 @@ namespace Emby.Server.Implementations.HttpServer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _requested ranges
|
/// The _requested ranges.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private List<KeyValuePair<long, long?>> _requestedRanges;
|
private List<KeyValuePair<long, long?>> _requestedRanges;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -139,6 +145,7 @@ namespace Emby.Server.Implementations.HttpServer
|
|||||||
{
|
{
|
||||||
start = long.Parse(vals[0], UsCulture);
|
start = long.Parse(vals[0], UsCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(vals[1]))
|
if (!string.IsNullOrEmpty(vals[1]))
|
||||||
{
|
{
|
||||||
end = long.Parse(vals[1], UsCulture);
|
end = long.Parse(vals[1], UsCulture);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
|
@ -3,10 +3,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Emby.Server.Implementations.SocketSharp;
|
using Emby.Server.Implementations.SocketSharp;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Controller.Authentication;
|
using MediaBrowser.Controller.Authentication;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Entities;
|
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Controller.Security;
|
using MediaBrowser.Controller.Security;
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
@ -90,7 +91,8 @@ namespace Emby.Server.Implementations.HttpServer.Security
|
|||||||
!string.IsNullOrEmpty(auth.Client) &&
|
!string.IsNullOrEmpty(auth.Client) &&
|
||||||
!string.IsNullOrEmpty(auth.Device))
|
!string.IsNullOrEmpty(auth.Device))
|
||||||
{
|
{
|
||||||
_sessionManager.LogSessionActivity(auth.Client,
|
_sessionManager.LogSessionActivity(
|
||||||
|
auth.Client,
|
||||||
auth.Version,
|
auth.Version,
|
||||||
auth.DeviceId,
|
auth.DeviceId,
|
||||||
auth.Device,
|
auth.Device,
|
||||||
@ -104,21 +106,21 @@ namespace Emby.Server.Implementations.HttpServer.Security
|
|||||||
private void ValidateUserAccess(
|
private void ValidateUserAccess(
|
||||||
User user,
|
User user,
|
||||||
IRequest request,
|
IRequest request,
|
||||||
IAuthenticationAttributes authAttribtues,
|
IAuthenticationAttributes authAttributes,
|
||||||
AuthorizationInfo auth)
|
AuthorizationInfo auth)
|
||||||
{
|
{
|
||||||
if (user.Policy.IsDisabled)
|
if (user.HasPermission(PermissionKind.IsDisabled))
|
||||||
{
|
{
|
||||||
throw new SecurityException("User account has been disabled.");
|
throw new SecurityException("User account has been disabled.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.Policy.EnableRemoteAccess && !_networkManager.IsInLocalNetwork(request.RemoteIp))
|
if (!user.HasPermission(PermissionKind.EnableRemoteAccess) && !_networkManager.IsInLocalNetwork(request.RemoteIp))
|
||||||
{
|
{
|
||||||
throw new SecurityException("User account has been disabled.");
|
throw new SecurityException("User account has been disabled.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.Policy.IsAdministrator
|
if (!user.HasPermission(PermissionKind.IsAdministrator)
|
||||||
&& !authAttribtues.EscapeParentalControl
|
&& !authAttributes.EscapeParentalControl
|
||||||
&& !user.IsParentalScheduleAllowed())
|
&& !user.IsParentalScheduleAllowed())
|
||||||
{
|
{
|
||||||
request.Response.Headers.Add("X-Application-Error-Code", "ParentalControl");
|
request.Response.Headers.Add("X-Application-Error-Code", "ParentalControl");
|
||||||
@ -138,6 +140,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (authAttribtues.AllowLocalOnly && request.IsLocal)
|
if (authAttribtues.AllowLocalOnly && request.IsLocal)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@ -180,7 +183,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
|
|||||||
{
|
{
|
||||||
if (roles.Contains("admin", StringComparer.OrdinalIgnoreCase))
|
if (roles.Contains("admin", StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (user == null || !user.Policy.IsAdministrator)
|
if (user == null || !user.HasPermission(PermissionKind.IsAdministrator))
|
||||||
{
|
{
|
||||||
throw new SecurityException("User does not have admin access.");
|
throw new SecurityException("User does not have admin access.");
|
||||||
}
|
}
|
||||||
@ -188,7 +191,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
|
|||||||
|
|
||||||
if (roles.Contains("delete", StringComparer.OrdinalIgnoreCase))
|
if (roles.Contains("delete", StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (user == null || !user.Policy.EnableContentDeletion)
|
if (user == null || !user.HasPermission(PermissionKind.EnableContentDeletion))
|
||||||
{
|
{
|
||||||
throw new SecurityException("User does not have delete access.");
|
throw new SecurityException("User does not have delete access.");
|
||||||
}
|
}
|
||||||
@ -196,7 +199,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
|
|||||||
|
|
||||||
if (roles.Contains("download", StringComparer.OrdinalIgnoreCase))
|
if (roles.Contains("download", StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (user == null || !user.Policy.EnableContentDownloading)
|
if (user == null || !user.HasPermission(PermissionKind.EnableContentDownloading))
|
||||||
{
|
{
|
||||||
throw new SecurityException("User does not have download access.");
|
throw new SecurityException("User does not have download access.");
|
||||||
}
|
}
|
||||||
@ -223,7 +226,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
|
|||||||
throw new AuthenticationException("Access token is invalid or expired.");
|
throw new AuthenticationException("Access token is invalid or expired.");
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (!string.IsNullOrEmpty(info.UserId))
|
// if (!string.IsNullOrEmpty(info.UserId))
|
||||||
//{
|
//{
|
||||||
// var user = _userManager.GetUserById(info.UserId);
|
// var user = _userManager.GetUserById(info.UserId);
|
||||||
|
|
||||||
|
@ -71,6 +71,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
|
|||||||
{
|
{
|
||||||
token = httpReq.Headers["X-MediaBrowser-Token"];
|
token = httpReq.Headers["X-MediaBrowser-Token"];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(token))
|
if (string.IsNullOrEmpty(token))
|
||||||
{
|
{
|
||||||
token = httpReq.QueryString["api_key"];
|
token = httpReq.QueryString["api_key"];
|
||||||
@ -116,7 +117,6 @@ namespace Emby.Server.Implementations.HttpServer.Security
|
|||||||
{
|
{
|
||||||
info.Device = tokenInfo.DeviceName;
|
info.Device = tokenInfo.DeviceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (!string.Equals(info.Device, tokenInfo.DeviceName, StringComparison.OrdinalIgnoreCase))
|
else if (!string.Equals(info.Device, tokenInfo.DeviceName, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (allowTokenInfoUpdate)
|
if (allowTokenInfoUpdate)
|
||||||
@ -149,9 +149,9 @@ namespace Emby.Server.Implementations.HttpServer.Security
|
|||||||
{
|
{
|
||||||
info.User = _userManager.GetUserById(tokenInfo.UserId);
|
info.User = _userManager.GetUserById(tokenInfo.UserId);
|
||||||
|
|
||||||
if (info.User != null && !string.Equals(info.User.Name, tokenInfo.UserName, StringComparison.OrdinalIgnoreCase))
|
if (info.User != null && !string.Equals(info.User.Username, tokenInfo.UserName, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
tokenInfo.UserName = info.User.Name;
|
tokenInfo.UserName = info.User.Username;
|
||||||
updateToken = true;
|
updateToken = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,6 +161,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
|
|||||||
_authRepo.Update(tokenInfo);
|
_authRepo.Update(tokenInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
httpReq.Items["OriginalAuthenticationInfo"] = tokenInfo;
|
httpReq.Items["OriginalAuthenticationInfo"] = tokenInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using MediaBrowser.Controller.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Controller.Security;
|
using MediaBrowser.Controller.Security;
|
||||||
|
@ -234,10 +234,12 @@ namespace Emby.Server.Implementations.HttpServer
|
|||||||
private Task SendKeepAliveResponse()
|
private Task SendKeepAliveResponse()
|
||||||
{
|
{
|
||||||
LastKeepAliveDate = DateTime.UtcNow;
|
LastKeepAliveDate = DateTime.UtcNow;
|
||||||
return SendAsync(new WebSocketMessage<string>
|
return SendAsync(
|
||||||
{
|
new WebSocketMessage<string>
|
||||||
MessageType = "KeepAlive"
|
{
|
||||||
}, CancellationToken.None);
|
MessageId = Guid.NewGuid(),
|
||||||
|
MessageType = "KeepAlive"
|
||||||
|
}, CancellationToken.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -266,7 +266,6 @@ namespace Emby.Server.Implementations.IO
|
|||||||
{
|
{
|
||||||
DisposeWatcher(newWatcher, false);
|
DisposeWatcher(newWatcher, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -393,7 +392,6 @@ namespace Emby.Server.Implementations.IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
monitorPath = false;
|
monitorPath = false;
|
||||||
|
@ -237,7 +237,7 @@ namespace Emby.Server.Implementations.IO
|
|||||||
{
|
{
|
||||||
result.IsDirectory = info is DirectoryInfo || (info.Attributes & FileAttributes.Directory) == FileAttributes.Directory;
|
result.IsDirectory = info is DirectoryInfo || (info.Attributes & FileAttributes.Directory) == FileAttributes.Directory;
|
||||||
|
|
||||||
//if (!result.IsDirectory)
|
// if (!result.IsDirectory)
|
||||||
//{
|
//{
|
||||||
// result.IsHidden = (info.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden;
|
// result.IsHidden = (info.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden;
|
||||||
//}
|
//}
|
||||||
@ -628,6 +628,7 @@ namespace Emby.Server.Implementations.IO
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return extensions.Contains(ext, StringComparer.OrdinalIgnoreCase);
|
return extensions.Contains(ext, StringComparer.OrdinalIgnoreCase);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -682,6 +683,7 @@ namespace Emby.Server.Implementations.IO
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return extensions.Contains(ext, StringComparer.OrdinalIgnoreCase);
|
return extensions.Contains(ext, StringComparer.OrdinalIgnoreCase);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,6 @@ namespace Emby.Server.Implementations.Images
|
|||||||
new ValueTuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending)
|
new ValueTuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending)
|
||||||
},
|
},
|
||||||
IncludeItemTypes = includeItemTypes
|
IncludeItemTypes = includeItemTypes
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,6 @@ namespace Emby.Server.Implementations.Images
|
|||||||
}
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
}).GroupBy(x => x.Id)
|
}).GroupBy(x => x.Id)
|
||||||
.Select(x => x.First());
|
.Select(x => x.First());
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ using MediaBrowser.Model.IO;
|
|||||||
namespace Emby.Server.Implementations.Library
|
namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides the core resolver ignore rules
|
/// Provides the core resolver ignore rules.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CoreResolutionIgnoreRule : IResolverIgnoreRule
|
public class CoreResolutionIgnoreRule : IResolverIgnoreRule
|
||||||
{
|
{
|
||||||
|
@ -12,11 +12,13 @@ namespace Emby.Server.Implementations.Library
|
|||||||
public class ExclusiveLiveStream : ILiveStream
|
public class ExclusiveLiveStream : ILiveStream
|
||||||
{
|
{
|
||||||
public int ConsumerCount { get; set; }
|
public int ConsumerCount { get; set; }
|
||||||
|
|
||||||
public string OriginalStreamId { get; set; }
|
public string OriginalStreamId { get; set; }
|
||||||
|
|
||||||
public string TunerHostId => null;
|
public string TunerHostId => null;
|
||||||
|
|
||||||
public bool EnableStreamSharing { get; set; }
|
public bool EnableStreamSharing { get; set; }
|
||||||
|
|
||||||
public MediaSourceInfo MediaSource { get; set; }
|
public MediaSourceInfo MediaSource { get; set; }
|
||||||
|
|
||||||
public string UniqueId { get; private set; }
|
public string UniqueId { get; private set; }
|
||||||
|
@ -4,12 +4,12 @@ using DotNet.Globbing;
|
|||||||
namespace Emby.Server.Implementations.Library
|
namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Glob patterns for files to ignore
|
/// Glob patterns for files to ignore.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class IgnorePatterns
|
public static class IgnorePatterns
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Files matching these glob patterns will be ignored
|
/// Files matching these glob patterns will be ignored.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly string[] Patterns = new string[]
|
public static readonly string[] Patterns = new string[]
|
||||||
{
|
{
|
||||||
@ -64,7 +64,7 @@ namespace Emby.Server.Implementations.Library
|
|||||||
private static readonly Glob[] _globs = Patterns.Select(p => Glob.Parse(p, _globOptions)).ToArray();
|
private static readonly Glob[] _globs = Patterns.Select(p => Glob.Parse(p, _globOptions)).ToArray();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if the supplied path should be ignored
|
/// Returns true if the supplied path should be ignored.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool ShouldIgnore(string path)
|
public static bool ShouldIgnore(string path)
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,8 @@ using Emby.Server.Implementations.Library.Resolvers;
|
|||||||
using Emby.Server.Implementations.Library.Validators;
|
using Emby.Server.Implementations.Library.Validators;
|
||||||
using Emby.Server.Implementations.Playlists;
|
using Emby.Server.Implementations.Playlists;
|
||||||
using Emby.Server.Implementations.ScheduledTasks;
|
using Emby.Server.Implementations.ScheduledTasks;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Progress;
|
using MediaBrowser.Common.Progress;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
@ -25,7 +27,6 @@ using MediaBrowser.Controller.Drawing;
|
|||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
|
||||||
using MediaBrowser.Controller.IO;
|
using MediaBrowser.Controller.IO;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.LiveTv;
|
using MediaBrowser.Controller.LiveTv;
|
||||||
@ -46,6 +47,9 @@ using MediaBrowser.Model.Querying;
|
|||||||
using MediaBrowser.Model.Tasks;
|
using MediaBrowser.Model.Tasks;
|
||||||
using MediaBrowser.Providers.MediaInfo;
|
using MediaBrowser.Providers.MediaInfo;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Episode = MediaBrowser.Controller.Entities.TV.Episode;
|
||||||
|
using Genre = MediaBrowser.Controller.Entities.Genre;
|
||||||
|
using Person = MediaBrowser.Controller.Entities.Person;
|
||||||
using SortOrder = MediaBrowser.Model.Entities.SortOrder;
|
using SortOrder = MediaBrowser.Model.Entities.SortOrder;
|
||||||
using VideoResolver = Emby.Naming.Video.VideoResolver;
|
using VideoResolver = Emby.Naming.Video.VideoResolver;
|
||||||
|
|
||||||
@ -93,13 +97,13 @@ namespace Emby.Server.Implementations.Library
|
|||||||
private IIntroProvider[] IntroProviders { get; set; }
|
private IIntroProvider[] IntroProviders { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the list of entity resolution ignore rules
|
/// Gets or sets the list of entity resolution ignore rules.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The entity resolution ignore rules.</value>
|
/// <value>The entity resolution ignore rules.</value>
|
||||||
private IResolverIgnoreRule[] EntityResolutionIgnoreRules { get; set; }
|
private IResolverIgnoreRule[] EntityResolutionIgnoreRules { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the list of currently registered entity resolvers
|
/// Gets or sets the list of currently registered entity resolvers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The entity resolvers enumerable.</value>
|
/// <value>The entity resolvers enumerable.</value>
|
||||||
private IItemResolver[] EntityResolvers { get; set; }
|
private IItemResolver[] EntityResolvers { get; set; }
|
||||||
@ -205,12 +209,12 @@ namespace Emby.Server.Implementations.Library
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _root folder
|
/// The _root folder.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private volatile AggregateFolder _rootFolder;
|
private volatile AggregateFolder _rootFolder;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _root folder sync lock
|
/// The _root folder sync lock.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly object _rootFolderSyncLock = new object();
|
private readonly object _rootFolderSyncLock = new object();
|
||||||
|
|
||||||
@ -623,7 +627,7 @@ namespace Emby.Server.Implementations.Library
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether a path should be ignored based on its contents - called after the contents have been read
|
/// Determines whether a path should be ignored based on its contents - called after the contents have been read.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="args">The args.</param>
|
/// <param name="args">The args.</param>
|
||||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
||||||
@ -905,7 +909,7 @@ namespace Emby.Server.Implementations.Library
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a Genre
|
/// Gets a Genre.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name.</param>
|
/// <param name="name">The name.</param>
|
||||||
/// <returns>Task{Genre}.</returns>
|
/// <returns>Task{Genre}.</returns>
|
||||||
@ -986,7 +990,7 @@ namespace Emby.Server.Implementations.Library
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reloads the root media folder
|
/// Reloads the root media folder.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="progress">The progress.</param>
|
/// <param name="progress">The progress.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
@ -1539,7 +1543,8 @@ namespace Emby.Server.Implementations.Library
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle grouping
|
// Handle grouping
|
||||||
if (user != null && !string.IsNullOrEmpty(view.ViewType) && UserView.IsEligibleForGrouping(view.ViewType) && user.Configuration.GroupedFolders.Length > 0)
|
if (user != null && !string.IsNullOrEmpty(view.ViewType) && UserView.IsEligibleForGrouping(view.ViewType)
|
||||||
|
&& user.GetPreference(PreferenceKind.GroupedFolders).Length > 0)
|
||||||
{
|
{
|
||||||
return GetUserRootFolder()
|
return GetUserRootFolder()
|
||||||
.GetChildren(user, true)
|
.GetChildren(user, true)
|
||||||
@ -2590,7 +2595,7 @@ namespace Emby.Server.Implementations.Library
|
|||||||
Anime series don't generally have a season in their file name, however,
|
Anime series don't generally have a season in their file name, however,
|
||||||
tvdb needs a season to correctly get the metadata.
|
tvdb needs a season to correctly get the metadata.
|
||||||
Hence, a null season needs to be filled with something. */
|
Hence, a null season needs to be filled with something. */
|
||||||
//FIXME perhaps this would be better for tvdb parser to ask for season 1 if no season is specified
|
// FIXME perhaps this would be better for tvdb parser to ask for season 1 if no season is specified
|
||||||
episode.ParentIndexNumber = 1;
|
episode.ParentIndexNumber = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2779,10 +2784,12 @@ namespace Emby.Server.Implementations.Library
|
|||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(path));
|
throw new ArgumentNullException(nameof(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(from))
|
if (string.IsNullOrWhiteSpace(from))
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(from));
|
throw new ArgumentNullException(nameof(from));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(to))
|
if (string.IsNullOrWhiteSpace(to))
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(to));
|
throw new ArgumentNullException(nameof(to));
|
||||||
@ -2856,7 +2863,6 @@ namespace Emby.Server.Implementations.Library
|
|||||||
_logger.LogError(ex, "Error getting person");
|
_logger.LogError(ex, "Error getting person");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}).Where(i => i != null).ToList();
|
}).Where(i => i != null).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2986,7 +2992,7 @@ namespace Emby.Server.Implementations.Library
|
|||||||
|
|
||||||
private static bool ValidateNetworkPath(string path)
|
private static bool ValidateNetworkPath(string path)
|
||||||
{
|
{
|
||||||
//if (Environment.OSVersion.Platform == PlatformID.Win32NT)
|
// if (Environment.OSVersion.Platform == PlatformID.Win32NT)
|
||||||
//{
|
//{
|
||||||
// // We can't validate protocol-based paths, so just allow them
|
// // We can't validate protocol-based paths, so just allow them
|
||||||
// if (path.IndexOf("://", StringComparison.OrdinalIgnoreCase) == -1)
|
// if (path.IndexOf("://", StringComparison.OrdinalIgnoreCase) == -1)
|
||||||
|
@ -50,7 +50,7 @@ namespace Emby.Server.Implementations.Library
|
|||||||
{
|
{
|
||||||
mediaInfo = _json.DeserializeFromFile<MediaInfo>(cacheFilePath);
|
mediaInfo = _json.DeserializeFromFile<MediaInfo>(cacheFilePath);
|
||||||
|
|
||||||
//_logger.LogDebug("Found cached media info");
|
// _logger.LogDebug("Found cached media info");
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@ -85,7 +85,7 @@ namespace Emby.Server.Implementations.Library
|
|||||||
Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath));
|
Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath));
|
||||||
_json.SerializeToFile(mediaInfo, cacheFilePath);
|
_json.SerializeToFile(mediaInfo, cacheFilePath);
|
||||||
|
|
||||||
//_logger.LogDebug("Saved media info to {0}", cacheFilePath);
|
// _logger.LogDebug("Saved media info to {0}", cacheFilePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,17 +148,14 @@ namespace Emby.Server.Implementations.Library
|
|||||||
{
|
{
|
||||||
videoStream.BitRate = 30000000;
|
videoStream.BitRate = 30000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (width >= 1900)
|
else if (width >= 1900)
|
||||||
{
|
{
|
||||||
videoStream.BitRate = 20000000;
|
videoStream.BitRate = 20000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (width >= 1200)
|
else if (width >= 1200)
|
||||||
{
|
{
|
||||||
videoStream.BitRate = 8000000;
|
videoStream.BitRate = 8000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (width >= 700)
|
else if (width >= 700)
|
||||||
{
|
{
|
||||||
videoStream.BitRate = 2000000;
|
videoStream.BitRate = 2000000;
|
||||||
|
@ -7,6 +7,8 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
@ -14,7 +16,6 @@ using MediaBrowser.Controller.Library;
|
|||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Controller.Persistence;
|
using MediaBrowser.Controller.Persistence;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Configuration;
|
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
@ -190,10 +191,7 @@ namespace Emby.Server.Implementations.Library
|
|||||||
{
|
{
|
||||||
if (string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (!user.Policy.EnableAudioPlaybackTranscoding)
|
source.SupportsTranscoding = user.HasPermission(PermissionKind.EnableAudioPlaybackTranscoding);
|
||||||
{
|
|
||||||
source.SupportsTranscoding = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -207,22 +205,27 @@ namespace Emby.Server.Implementations.Library
|
|||||||
{
|
{
|
||||||
return MediaProtocol.Rtsp;
|
return MediaProtocol.Rtsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path.StartsWith("Rtmp", StringComparison.OrdinalIgnoreCase))
|
if (path.StartsWith("Rtmp", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return MediaProtocol.Rtmp;
|
return MediaProtocol.Rtmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path.StartsWith("Http", StringComparison.OrdinalIgnoreCase))
|
if (path.StartsWith("Http", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return MediaProtocol.Http;
|
return MediaProtocol.Http;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path.StartsWith("rtp", StringComparison.OrdinalIgnoreCase))
|
if (path.StartsWith("rtp", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return MediaProtocol.Rtp;
|
return MediaProtocol.Rtp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path.StartsWith("ftp", StringComparison.OrdinalIgnoreCase))
|
if (path.StartsWith("ftp", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return MediaProtocol.Ftp;
|
return MediaProtocol.Ftp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path.StartsWith("udp", StringComparison.OrdinalIgnoreCase))
|
if (path.StartsWith("udp", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return MediaProtocol.Udp;
|
return MediaProtocol.Udp;
|
||||||
@ -352,7 +355,9 @@ namespace Emby.Server.Implementations.Library
|
|||||||
|
|
||||||
private void SetDefaultSubtitleStreamIndex(MediaSourceInfo source, UserItemData userData, User user, bool allowRememberingSelection)
|
private void SetDefaultSubtitleStreamIndex(MediaSourceInfo source, UserItemData userData, User user, bool allowRememberingSelection)
|
||||||
{
|
{
|
||||||
if (userData.SubtitleStreamIndex.HasValue && user.Configuration.RememberSubtitleSelections && user.Configuration.SubtitleMode != SubtitlePlaybackMode.None && allowRememberingSelection)
|
if (userData.SubtitleStreamIndex.HasValue
|
||||||
|
&& user.RememberSubtitleSelections
|
||||||
|
&& user.SubtitleMode != SubtitlePlaybackMode.None && allowRememberingSelection)
|
||||||
{
|
{
|
||||||
var index = userData.SubtitleStreamIndex.Value;
|
var index = userData.SubtitleStreamIndex.Value;
|
||||||
// Make sure the saved index is still valid
|
// Make sure the saved index is still valid
|
||||||
@ -363,26 +368,27 @@ namespace Emby.Server.Implementations.Library
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var preferredSubs = string.IsNullOrEmpty(user.Configuration.SubtitleLanguagePreference)
|
|
||||||
? Array.Empty<string>() : NormalizeLanguage(user.Configuration.SubtitleLanguagePreference);
|
var preferredSubs = string.IsNullOrEmpty(user.SubtitleLanguagePreference)
|
||||||
|
? Array.Empty<string>() : NormalizeLanguage(user.SubtitleLanguagePreference);
|
||||||
|
|
||||||
var defaultAudioIndex = source.DefaultAudioStreamIndex;
|
var defaultAudioIndex = source.DefaultAudioStreamIndex;
|
||||||
var audioLangage = defaultAudioIndex == null
|
var audioLangage = defaultAudioIndex == null
|
||||||
? null
|
? null
|
||||||
: source.MediaStreams.Where(i => i.Type == MediaStreamType.Audio && i.Index == defaultAudioIndex).Select(i => i.Language).FirstOrDefault();
|
: source.MediaStreams.Where(i => i.Type == MediaStreamType.Audio && i.Index == defaultAudioIndex).Select(i => i.Language).FirstOrDefault();
|
||||||
|
|
||||||
source.DefaultSubtitleStreamIndex = MediaStreamSelector.GetDefaultSubtitleStreamIndex(source.MediaStreams,
|
source.DefaultSubtitleStreamIndex = MediaStreamSelector.GetDefaultSubtitleStreamIndex(
|
||||||
|
source.MediaStreams,
|
||||||
preferredSubs,
|
preferredSubs,
|
||||||
user.Configuration.SubtitleMode,
|
user.SubtitleMode,
|
||||||
audioLangage);
|
audioLangage);
|
||||||
|
|
||||||
MediaStreamSelector.SetSubtitleStreamScores(source.MediaStreams, preferredSubs,
|
MediaStreamSelector.SetSubtitleStreamScores(source.MediaStreams, preferredSubs, user.SubtitleMode, audioLangage);
|
||||||
user.Configuration.SubtitleMode, audioLangage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetDefaultAudioStreamIndex(MediaSourceInfo source, UserItemData userData, User user, bool allowRememberingSelection)
|
private void SetDefaultAudioStreamIndex(MediaSourceInfo source, UserItemData userData, User user, bool allowRememberingSelection)
|
||||||
{
|
{
|
||||||
if (userData.AudioStreamIndex.HasValue && user.Configuration.RememberAudioSelections && allowRememberingSelection)
|
if (userData.AudioStreamIndex.HasValue && user.RememberAudioSelections && allowRememberingSelection)
|
||||||
{
|
{
|
||||||
var index = userData.AudioStreamIndex.Value;
|
var index = userData.AudioStreamIndex.Value;
|
||||||
// Make sure the saved index is still valid
|
// Make sure the saved index is still valid
|
||||||
@ -393,11 +399,11 @@ namespace Emby.Server.Implementations.Library
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var preferredAudio = string.IsNullOrEmpty(user.Configuration.AudioLanguagePreference)
|
var preferredAudio = string.IsNullOrEmpty(user.AudioLanguagePreference)
|
||||||
? Array.Empty<string>()
|
? Array.Empty<string>()
|
||||||
: NormalizeLanguage(user.Configuration.AudioLanguagePreference);
|
: NormalizeLanguage(user.AudioLanguagePreference);
|
||||||
|
|
||||||
source.DefaultAudioStreamIndex = MediaStreamSelector.GetDefaultAudioStreamIndex(source.MediaStreams, preferredAudio, user.Configuration.PlayDefaultAudioTrack);
|
source.DefaultAudioStreamIndex = MediaStreamSelector.GetDefaultAudioStreamIndex(source.MediaStreams, preferredAudio, user.PlayDefaultAudioTrack);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetDefaultAudioAndSubtitleStreamIndexes(BaseItem item, MediaSourceInfo source, User user)
|
public void SetDefaultAudioAndSubtitleStreamIndexes(BaseItem item, MediaSourceInfo source, User user)
|
||||||
@ -435,7 +441,6 @@ namespace Emby.Server.Implementations.Library
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}).ThenBy(i => i.Video3DFormat.HasValue ? 1 : 0)
|
}).ThenBy(i => i.Video3DFormat.HasValue ? 1 : 0)
|
||||||
.ThenByDescending(i =>
|
.ThenByDescending(i =>
|
||||||
{
|
{
|
||||||
@ -534,7 +539,7 @@ namespace Emby.Server.Implementations.Library
|
|||||||
mediaSource.RunTimeTicks = null;
|
mediaSource.RunTimeTicks = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var audioStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == MediaBrowser.Model.Entities.MediaStreamType.Audio);
|
var audioStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio);
|
||||||
|
|
||||||
if (audioStream == null || audioStream.Index == -1)
|
if (audioStream == null || audioStream.Index == -1)
|
||||||
{
|
{
|
||||||
@ -545,7 +550,7 @@ namespace Emby.Server.Implementations.Library
|
|||||||
mediaSource.DefaultAudioStreamIndex = audioStream.Index;
|
mediaSource.DefaultAudioStreamIndex = audioStream.Index;
|
||||||
}
|
}
|
||||||
|
|
||||||
var videoStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == MediaBrowser.Model.Entities.MediaStreamType.Video);
|
var videoStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video);
|
||||||
if (videoStream != null)
|
if (videoStream != null)
|
||||||
{
|
{
|
||||||
if (!videoStream.BitRate.HasValue)
|
if (!videoStream.BitRate.HasValue)
|
||||||
@ -556,17 +561,14 @@ namespace Emby.Server.Implementations.Library
|
|||||||
{
|
{
|
||||||
videoStream.BitRate = 30000000;
|
videoStream.BitRate = 30000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (width >= 1900)
|
else if (width >= 1900)
|
||||||
{
|
{
|
||||||
videoStream.BitRate = 20000000;
|
videoStream.BitRate = 20000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (width >= 1200)
|
else if (width >= 1200)
|
||||||
{
|
{
|
||||||
videoStream.BitRate = 8000000;
|
videoStream.BitRate = 8000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (width >= 700)
|
else if (width >= 700)
|
||||||
{
|
{
|
||||||
videoStream.BitRate = 2000000;
|
videoStream.BitRate = 2000000;
|
||||||
@ -622,7 +624,6 @@ namespace Emby.Server.Implementations.Library
|
|||||||
MediaSource = mediaSource,
|
MediaSource = mediaSource,
|
||||||
ExtractChapters = false,
|
ExtractChapters = false,
|
||||||
MediaType = DlnaProfileType.Video
|
MediaType = DlnaProfileType.Video
|
||||||
|
|
||||||
}, cancellationToken).ConfigureAwait(false);
|
}, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
mediaSource.MediaStreams = info.MediaStreams;
|
mediaSource.MediaStreams = info.MediaStreams;
|
||||||
@ -648,7 +649,7 @@ namespace Emby.Server.Implementations.Library
|
|||||||
{
|
{
|
||||||
mediaInfo = _jsonSerializer.DeserializeFromFile<MediaInfo>(cacheFilePath);
|
mediaInfo = _jsonSerializer.DeserializeFromFile<MediaInfo>(cacheFilePath);
|
||||||
|
|
||||||
//_logger.LogDebug("Found cached media info");
|
// _logger.LogDebug("Found cached media info");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -670,20 +671,21 @@ namespace Emby.Server.Implementations.Library
|
|||||||
mediaSource.AnalyzeDurationMs = 3000;
|
mediaSource.AnalyzeDurationMs = 3000;
|
||||||
}
|
}
|
||||||
|
|
||||||
mediaInfo = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest
|
mediaInfo = await _mediaEncoder.GetMediaInfo(
|
||||||
|
new MediaInfoRequest
|
||||||
{
|
{
|
||||||
MediaSource = mediaSource,
|
MediaSource = mediaSource,
|
||||||
MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video,
|
MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video,
|
||||||
ExtractChapters = false
|
ExtractChapters = false
|
||||||
|
},
|
||||||
}, cancellationToken).ConfigureAwait(false);
|
cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
if (cacheFilePath != null)
|
if (cacheFilePath != null)
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath));
|
Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath));
|
||||||
_jsonSerializer.SerializeToFile(mediaInfo, cacheFilePath);
|
_jsonSerializer.SerializeToFile(mediaInfo, cacheFilePath);
|
||||||
|
|
||||||
//_logger.LogDebug("Saved media info to {0}", cacheFilePath);
|
// _logger.LogDebug("Saved media info to {0}", cacheFilePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -749,17 +751,14 @@ namespace Emby.Server.Implementations.Library
|
|||||||
{
|
{
|
||||||
videoStream.BitRate = 30000000;
|
videoStream.BitRate = 30000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (width >= 1900)
|
else if (width >= 1900)
|
||||||
{
|
{
|
||||||
videoStream.BitRate = 20000000;
|
videoStream.BitRate = 20000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (width >= 1200)
|
else if (width >= 1200)
|
||||||
{
|
{
|
||||||
videoStream.BitRate = 8000000;
|
videoStream.BitRate = 8000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (width >= 700)
|
else if (width >= 700)
|
||||||
{
|
{
|
||||||
videoStream.BitRate = 2000000;
|
videoStream.BitRate = 2000000;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using MediaBrowser.Model.Configuration;
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library
|
namespace Emby.Server.Implementations.Library
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
@ -10,6 +11,7 @@ using MediaBrowser.Controller.Library;
|
|||||||
using MediaBrowser.Controller.Playlists;
|
using MediaBrowser.Controller.Playlists;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
|
using MusicAlbum = MediaBrowser.Controller.Entities.Audio.MusicAlbum;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library
|
namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
@ -75,7 +77,6 @@ namespace Emby.Server.Implementations.Library
|
|||||||
{
|
{
|
||||||
return Guid.Empty;
|
return Guid.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
}).Where(i => !i.Equals(Guid.Empty)).ToArray();
|
}).Where(i => !i.Equals(Guid.Empty)).ToArray();
|
||||||
|
|
||||||
return GetInstantMixFromGenreIds(genreIds, user, dtoOptions);
|
return GetInstantMixFromGenreIds(genreIds, user, dtoOptions);
|
||||||
@ -105,32 +106,27 @@ namespace Emby.Server.Implementations.Library
|
|||||||
return GetInstantMixFromGenreIds(new[] { item.Id }, user, dtoOptions);
|
return GetInstantMixFromGenreIds(new[] { item.Id }, user, dtoOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
var playlist = item as Playlist;
|
if (item is Playlist playlist)
|
||||||
if (playlist != null)
|
|
||||||
{
|
{
|
||||||
return GetInstantMixFromPlaylist(playlist, user, dtoOptions);
|
return GetInstantMixFromPlaylist(playlist, user, dtoOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
var album = item as MusicAlbum;
|
if (item is MusicAlbum album)
|
||||||
if (album != null)
|
|
||||||
{
|
{
|
||||||
return GetInstantMixFromAlbum(album, user, dtoOptions);
|
return GetInstantMixFromAlbum(album, user, dtoOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
var artist = item as MusicArtist;
|
if (item is MusicArtist artist)
|
||||||
if (artist != null)
|
|
||||||
{
|
{
|
||||||
return GetInstantMixFromArtist(artist, user, dtoOptions);
|
return GetInstantMixFromArtist(artist, user, dtoOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
var song = item as Audio;
|
if (item is Audio song)
|
||||||
if (song != null)
|
|
||||||
{
|
{
|
||||||
return GetInstantMixFromSong(song, user, dtoOptions);
|
return GetInstantMixFromSong(song, user, dtoOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
var folder = item as Folder;
|
if (item is Folder folder)
|
||||||
if (folder != null)
|
|
||||||
{
|
{
|
||||||
return GetInstantMixFromFolder(folder, user, dtoOptions);
|
return GetInstantMixFromFolder(folder, user, dtoOptions);
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ namespace Emby.Server.Implementations.Library
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ensures DateCreated and DateModified have values
|
/// Ensures DateCreated and DateModified have values.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fileSystem">The file system.</param>
|
/// <param name="fileSystem">The file system.</param>
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="item">The item.</param>
|
||||||
|
@ -209,8 +209,8 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
|||||||
Name = parseName ?
|
Name = parseName ?
|
||||||
resolvedItem.Name :
|
resolvedItem.Name :
|
||||||
Path.GetFileNameWithoutExtension(firstMedia.Path),
|
Path.GetFileNameWithoutExtension(firstMedia.Path),
|
||||||
//AdditionalParts = resolvedItem.Files.Skip(1).Select(i => i.Path).ToArray(),
|
// AdditionalParts = resolvedItem.Files.Skip(1).Select(i => i.Path).ToArray(),
|
||||||
//LocalAlternateVersions = resolvedItem.AlternateVersions.Select(i => i.Path).ToArray()
|
// LocalAlternateVersions = resolvedItem.AlternateVersions.Select(i => i.Path).ToArray()
|
||||||
};
|
};
|
||||||
|
|
||||||
result.Items.Add(libraryItem);
|
result.Items.Add(libraryItem);
|
||||||
|
@ -92,7 +92,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
|||||||
// Args points to an album if parent is an Artist folder or it directly contains music
|
// Args points to an album if parent is an Artist folder or it directly contains music
|
||||||
if (args.IsDirectory)
|
if (args.IsDirectory)
|
||||||
{
|
{
|
||||||
// if (args.Parent is MusicArtist) return true; //saves us from testing children twice
|
// if (args.Parent is MusicArtist) return true; // saves us from testing children twice
|
||||||
if (ContainsMusic(args.FileSystemChildren, true, args.DirectoryService, _logger, _fileSystem, _libraryManager))
|
if (ContainsMusic(args.FileSystemChildren, true, args.DirectoryService, _logger, _fileSystem, _libraryManager))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -292,7 +292,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
//var blurayExtensions = new[]
|
// var blurayExtensions = new[]
|
||||||
//{
|
//{
|
||||||
// ".mts",
|
// ".mts",
|
||||||
// ".m2ts",
|
// ".m2ts",
|
||||||
@ -300,7 +300,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
|
|||||||
// ".mpls"
|
// ".mpls"
|
||||||
//};
|
//};
|
||||||
|
|
||||||
//return directoryService.GetFiles(fullPath).Any(i => blurayExtensions.Contains(i.Extension ?? string.Empty, StringComparer.OrdinalIgnoreCase));
|
// return directoryService.GetFiles(fullPath).Any(i => blurayExtensions.Contains(i.Extension ?? string.Empty, StringComparer.OrdinalIgnoreCase));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
|
|||||||
public virtual ResolverPriority Priority => ResolverPriority.First;
|
public virtual ResolverPriority Priority => ResolverPriority.First;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets initial values on the newly resolved item
|
/// Sets initial values on the newly resolved item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="item">The item.</param>
|
||||||
/// <param name="args">The args.</param>
|
/// <param name="args">The args.</param>
|
||||||
|
@ -41,10 +41,12 @@ namespace Emby.Server.Implementations.Library.Resolvers
|
|||||||
{
|
{
|
||||||
return new AggregateFolder();
|
return new AggregateFolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.Equals(args.Path, _appPaths.DefaultUserViewsPath, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(args.Path, _appPaths.DefaultUserViewsPath, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return new UserRootFolder(); //if we got here and still a root - must be user root
|
return new UserRootFolder(); // if we got here and still a root - must be user root
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.IsVf)
|
if (args.IsVf)
|
||||||
{
|
{
|
||||||
return new CollectionFolder
|
return new CollectionFolder
|
||||||
@ -73,7 +75,6 @@ namespace Emby.Server.Implementations.Library.Resolvers
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.Select(i => _fileSystem.GetFileNameWithoutExtension(i))
|
.Select(i => _fileSystem.GetFileNameWithoutExtension(i))
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
|
@ -55,6 +55,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
|
|||||||
episode.SeriesId = series.Id;
|
episode.SeriesId = series.Id;
|
||||||
episode.SeriesName = series.Name;
|
episode.SeriesName = series.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (season != null)
|
if (season != null)
|
||||||
{
|
{
|
||||||
episode.SeasonId = season.Id;
|
episode.SeasonId = season.Id;
|
||||||
|
@ -94,7 +94,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
|
|||||||
_localization.GetLocalizedString("NameSeasonNumber"),
|
_localization.GetLocalizedString("NameSeasonNumber"),
|
||||||
seasonNumber,
|
seasonNumber,
|
||||||
args.GetLibraryOptions().PreferredMetadataLanguage);
|
args.GetLibraryOptions().PreferredMetadataLanguage);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return season;
|
return season;
|
||||||
|
@ -59,7 +59,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
|
|||||||
var collectionType = args.GetCollectionType();
|
var collectionType = args.GetCollectionType();
|
||||||
if (string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
//if (args.ContainsFileSystemEntryByName("tvshow.nfo"))
|
// if (args.ContainsFileSystemEntryByName("tvshow.nfo"))
|
||||||
//{
|
//{
|
||||||
// return new Series
|
// return new Series
|
||||||
// {
|
// {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
@ -12,6 +13,8 @@ using MediaBrowser.Model.Entities;
|
|||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using MediaBrowser.Model.Search;
|
using MediaBrowser.Model.Search;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Genre = MediaBrowser.Controller.Entities.Genre;
|
||||||
|
using Person = MediaBrowser.Controller.Entities.Person;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library
|
namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
@ -191,6 +194,7 @@ namespace Emby.Server.Implementations.Library
|
|||||||
{
|
{
|
||||||
searchQuery.AncestorIds = new[] { searchQuery.ParentId };
|
searchQuery.AncestorIds = new[] { searchQuery.ParentId };
|
||||||
}
|
}
|
||||||
|
|
||||||
searchQuery.ParentId = Guid.Empty;
|
searchQuery.ParentId = Guid.Empty;
|
||||||
searchQuery.IncludeItemsByName = true;
|
searchQuery.IncludeItemsByName = true;
|
||||||
searchQuery.IncludeItemTypes = Array.Empty<string>();
|
searchQuery.IncludeItemTypes = Array.Empty<string>();
|
||||||
@ -204,7 +208,6 @@ namespace Emby.Server.Implementations.Library
|
|||||||
return mediaItems.Select(i => new SearchHintInfo
|
return mediaItems.Select(i => new SearchHintInfo
|
||||||
{
|
{
|
||||||
Item = i
|
Item = i
|
||||||
|
|
||||||
}).ToList();
|
}).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ using System.Collections.Concurrent;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
@ -13,6 +14,7 @@ using MediaBrowser.Controller.Persistence;
|
|||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Book = MediaBrowser.Controller.Entities.Book;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library
|
namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
@ -101,7 +103,7 @@ namespace Emby.Server.Implementations.Library
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieve all user data for the given user
|
/// Retrieve all user data for the given user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="userId"></param>
|
/// <param name="userId"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
@ -186,7 +188,7 @@ namespace Emby.Server.Implementations.Library
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts a UserItemData to a DTOUserItemData
|
/// Converts a UserItemData to a DTOUserItemData.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="data">The data.</param>
|
/// <param name="data">The data.</param>
|
||||||
/// <returns>DtoUserItemData.</returns>
|
/// <returns>DtoUserItemData.</returns>
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,8 @@ using System.Collections.Generic;
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Controller.Channels;
|
using MediaBrowser.Controller.Channels;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
@ -17,6 +19,8 @@ using MediaBrowser.Model.Entities;
|
|||||||
using MediaBrowser.Model.Globalization;
|
using MediaBrowser.Model.Globalization;
|
||||||
using MediaBrowser.Model.Library;
|
using MediaBrowser.Model.Library;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
|
using Genre = MediaBrowser.Controller.Entities.Genre;
|
||||||
|
using Person = MediaBrowser.Controller.Entities.Person;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library
|
namespace Emby.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
@ -125,12 +129,12 @@ namespace Emby.Server.Implementations.Library
|
|||||||
|
|
||||||
if (!query.IncludeHidden)
|
if (!query.IncludeHidden)
|
||||||
{
|
{
|
||||||
list = list.Where(i => !user.Configuration.MyMediaExcludes.Contains(i.Id.ToString("N", CultureInfo.InvariantCulture))).ToList();
|
list = list.Where(i => !user.GetPreference(PreferenceKind.MyMediaExcludes).Contains(i.Id.ToString("N", CultureInfo.InvariantCulture))).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
var sorted = _libraryManager.Sort(list, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).ToList();
|
var sorted = _libraryManager.Sort(list, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).ToList();
|
||||||
|
|
||||||
var orders = user.Configuration.OrderedViews.ToList();
|
var orders = user.GetPreference(PreferenceKind.OrderedViews).ToList();
|
||||||
|
|
||||||
return list
|
return list
|
||||||
.OrderBy(i =>
|
.OrderBy(i =>
|
||||||
@ -165,7 +169,13 @@ namespace Emby.Server.Implementations.Library
|
|||||||
return GetUserSubViewWithName(name, parentId, type, sortName);
|
return GetUserSubViewWithName(name, parentId, type, sortName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Folder GetUserView(List<ICollectionFolder> parents, string viewType, string localizationKey, string sortName, User user, string[] presetViews)
|
private Folder GetUserView(
|
||||||
|
List<ICollectionFolder> parents,
|
||||||
|
string viewType,
|
||||||
|
string localizationKey,
|
||||||
|
string sortName,
|
||||||
|
Jellyfin.Data.Entities.User user,
|
||||||
|
string[] presetViews)
|
||||||
{
|
{
|
||||||
if (parents.Count == 1 && parents.All(i => string.Equals(i.CollectionType, viewType, StringComparison.OrdinalIgnoreCase)))
|
if (parents.Count == 1 && parents.All(i => string.Equals(i.CollectionType, viewType, StringComparison.OrdinalIgnoreCase)))
|
||||||
{
|
{
|
||||||
@ -270,7 +280,8 @@ namespace Emby.Server.Implementations.Library
|
|||||||
{
|
{
|
||||||
parents = _libraryManager.GetUserRootFolder().GetChildren(user, true)
|
parents = _libraryManager.GetUserRootFolder().GetChildren(user, true)
|
||||||
.Where(i => i is Folder)
|
.Where(i => i is Folder)
|
||||||
.Where(i => !user.Configuration.LatestItemsExcludes.Contains(i.Id.ToString("N", CultureInfo.InvariantCulture)))
|
.Where(i => !user.GetPreference(PreferenceKind.LatestItemExcludes)
|
||||||
|
.Contains(i.Id.ToString("N", CultureInfo.InvariantCulture)))
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,12 +342,11 @@ namespace Emby.Server.Implementations.Library
|
|||||||
|
|
||||||
var excludeItemTypes = includeItemTypes.Length == 0 && mediaTypes.Count == 0 ? new[]
|
var excludeItemTypes = includeItemTypes.Length == 0 && mediaTypes.Count == 0 ? new[]
|
||||||
{
|
{
|
||||||
typeof(Person).Name,
|
nameof(Person),
|
||||||
typeof(Studio).Name,
|
nameof(Studio),
|
||||||
typeof(Year).Name,
|
nameof(Year),
|
||||||
typeof(MusicGenre).Name,
|
nameof(MusicGenre),
|
||||||
typeof(Genre).Name
|
nameof(Genre)
|
||||||
|
|
||||||
} : Array.Empty<string>();
|
} : Array.Empty<string>();
|
||||||
|
|
||||||
var query = new InternalItemsQuery(user)
|
var query = new InternalItemsQuery(user)
|
||||||
|
@ -98,7 +98,6 @@ namespace Emby.Server.Implementations.Library.Validators
|
|||||||
_libraryManager.DeleteItem(item, new DeleteOptions
|
_libraryManager.DeleteItem(item, new DeleteOptions
|
||||||
{
|
{
|
||||||
DeleteFileLocation = false
|
DeleteFileLocation = false
|
||||||
|
|
||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,6 @@ namespace Emby.Server.Implementations.Library.Validators
|
|||||||
_libraryManager.DeleteItem(item, new DeleteOptions
|
_libraryManager.DeleteItem(item, new DeleteOptions
|
||||||
{
|
{
|
||||||
DeleteFileLocation = false
|
DeleteFileLocation = false
|
||||||
|
|
||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1547,7 +1547,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||||||
IsFolder = false,
|
IsFolder = false,
|
||||||
Recursive = true,
|
Recursive = true,
|
||||||
DtoOptions = new DtoOptions(true)
|
DtoOptions = new DtoOptions(true)
|
||||||
|
|
||||||
})
|
})
|
||||||
.Where(i => i.IsFileProtocol && File.Exists(i.Path))
|
.Where(i => i.IsFileProtocol && File.Exists(i.Path))
|
||||||
.Skip(seriesTimer.KeepUpTo - 1)
|
.Skip(seriesTimer.KeepUpTo - 1)
|
||||||
|
@ -183,7 +183,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||||||
|
|
||||||
var subtitleArgs = CopySubtitles ? " -codec:s copy" : " -sn";
|
var subtitleArgs = CopySubtitles ? " -codec:s copy" : " -sn";
|
||||||
|
|
||||||
//var outputParam = string.Equals(Path.GetExtension(targetFile), ".mp4", StringComparison.OrdinalIgnoreCase) ?
|
// var outputParam = string.Equals(Path.GetExtension(targetFile), ".mp4", StringComparison.OrdinalIgnoreCase) ?
|
||||||
// " -f mp4 -movflags frag_keyframe+empty_moov" :
|
// " -f mp4 -movflags frag_keyframe+empty_moov" :
|
||||||
// string.Empty;
|
// string.Empty;
|
||||||
|
|
||||||
@ -206,13 +206,13 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||||||
{
|
{
|
||||||
return "-codec:a:0 copy";
|
return "-codec:a:0 copy";
|
||||||
|
|
||||||
//var audioChannels = 2;
|
// var audioChannels = 2;
|
||||||
//var audioStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio);
|
// var audioStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio);
|
||||||
//if (audioStream != null)
|
// if (audioStream != null)
|
||||||
//{
|
//{
|
||||||
// audioChannels = audioStream.Channels ?? audioChannels;
|
// audioChannels = audioStream.Channels ?? audioChannels;
|
||||||
//}
|
//}
|
||||||
//return "-codec:a:0 aac -strict experimental -ab 320000";
|
// return "-codec:a:0 aac -strict experimental -ab 320000";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool EncodeVideo(MediaSourceInfo mediaSource)
|
private static bool EncodeVideo(MediaSourceInfo mediaSource)
|
||||||
|
@ -56,7 +56,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||||||
name += " " + info.EpisodeTitle;
|
name += " " + info.EpisodeTitle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (info.IsMovie && info.ProductionYear != null)
|
else if (info.IsMovie && info.ProductionYear != null)
|
||||||
{
|
{
|
||||||
name += " (" + info.ProductionYear + ")";
|
name += " (" + info.ProductionYear + ")";
|
||||||
|
@ -145,7 +145,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
var programsInfo = new List<ProgramInfo>();
|
var programsInfo = new List<ProgramInfo>();
|
||||||
foreach (ScheduleDirect.Program schedule in dailySchedules.SelectMany(d => d.programs))
|
foreach (ScheduleDirect.Program schedule in dailySchedules.SelectMany(d => d.programs))
|
||||||
{
|
{
|
||||||
//_logger.LogDebug("Proccesing Schedule for statio ID " + stationID +
|
// _logger.LogDebug("Proccesing Schedule for statio ID " + stationID +
|
||||||
// " which corresponds to channel " + channelNumber + " and program id " +
|
// " which corresponds to channel " + channelNumber + " and program id " +
|
||||||
// schedule.programID + " which says it has images? " +
|
// schedule.programID + " which says it has images? " +
|
||||||
// programDict[schedule.programID].hasImageArtwork);
|
// programDict[schedule.programID].hasImageArtwork);
|
||||||
@ -178,7 +178,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
|
|
||||||
programEntry.backdropImage = GetProgramImage(ApiUrl, imagesWithoutText, true, WideAspect);
|
programEntry.backdropImage = GetProgramImage(ApiUrl, imagesWithoutText, true, WideAspect);
|
||||||
|
|
||||||
//programEntry.bannerImage = GetProgramImage(ApiUrl, data, "Banner", false) ??
|
// programEntry.bannerImage = GetProgramImage(ApiUrl, data, "Banner", false) ??
|
||||||
// GetProgramImage(ApiUrl, data, "Banner-L1", false) ??
|
// GetProgramImage(ApiUrl, data, "Banner-L1", false) ??
|
||||||
// GetProgramImage(ApiUrl, data, "Banner-LO", false) ??
|
// GetProgramImage(ApiUrl, data, "Banner-LO", false) ??
|
||||||
// GetProgramImage(ApiUrl, data, "Banner-LOT", false);
|
// GetProgramImage(ApiUrl, data, "Banner-LOT", false);
|
||||||
@ -212,6 +212,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
{
|
{
|
||||||
channelNumber = map.channel;
|
channelNumber = map.channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(channelNumber))
|
if (string.IsNullOrWhiteSpace(channelNumber))
|
||||||
{
|
{
|
||||||
channelNumber = map.atscMajor + "." + map.atscMinor;
|
channelNumber = map.atscMajor + "." + map.atscMinor;
|
||||||
@ -276,7 +277,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
CommunityRating = null,
|
CommunityRating = null,
|
||||||
EpisodeTitle = episodeTitle,
|
EpisodeTitle = episodeTitle,
|
||||||
Audio = audioType,
|
Audio = audioType,
|
||||||
//IsNew = programInfo.@new ?? false,
|
// IsNew = programInfo.@new ?? false,
|
||||||
IsRepeat = programInfo.@new == null,
|
IsRepeat = programInfo.@new == null,
|
||||||
IsSeries = string.Equals(details.entityType, "episode", StringComparison.OrdinalIgnoreCase),
|
IsSeries = string.Equals(details.entityType, "episode", StringComparison.OrdinalIgnoreCase),
|
||||||
ImageUrl = details.primaryImage,
|
ImageUrl = details.primaryImage,
|
||||||
@ -400,6 +401,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
{
|
{
|
||||||
date = DateTime.SpecifyKind(date, DateTimeKind.Utc);
|
date = DateTime.SpecifyKind(date, DateTimeKind.Utc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return date;
|
return date;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -622,6 +624,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
_lastErrorResponse = DateTime.UtcNow;
|
_lastErrorResponse = DateTime.UtcNow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@ -701,7 +704,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
CancellationToken = cancellationToken,
|
CancellationToken = cancellationToken,
|
||||||
LogErrorResponseBody = true
|
LogErrorResponseBody = true
|
||||||
};
|
};
|
||||||
//_logger.LogInformation("Obtaining token from Schedules Direct from addres: " + httpOptions.Url + " with body " +
|
// _logger.LogInformation("Obtaining token from Schedules Direct from addres: " + httpOptions.Url + " with body " +
|
||||||
// httpOptions.RequestContent);
|
// httpOptions.RequestContent);
|
||||||
|
|
||||||
using (var response = await Post(httpOptions, false, null).ConfigureAwait(false))
|
using (var response = await Post(httpOptions, false, null).ConfigureAwait(false))
|
||||||
@ -805,11 +808,13 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
{
|
{
|
||||||
throw new ArgumentException("Username is required");
|
throw new ArgumentException("Username is required");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(info.Password))
|
if (string.IsNullOrEmpty(info.Password))
|
||||||
{
|
{
|
||||||
throw new ArgumentException("Password is required");
|
throw new ArgumentException("Password is required");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (validateListings)
|
if (validateListings)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(info.ListingsId))
|
if (string.IsNullOrEmpty(info.ListingsId))
|
||||||
@ -932,24 +937,35 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
public class Token
|
public class Token
|
||||||
{
|
{
|
||||||
public int code { get; set; }
|
public int code { get; set; }
|
||||||
|
|
||||||
public string message { get; set; }
|
public string message { get; set; }
|
||||||
|
|
||||||
public string serverID { get; set; }
|
public string serverID { get; set; }
|
||||||
|
|
||||||
public string token { get; set; }
|
public string token { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Lineup
|
public class Lineup
|
||||||
{
|
{
|
||||||
public string lineup { get; set; }
|
public string lineup { get; set; }
|
||||||
|
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
|
|
||||||
public string transport { get; set; }
|
public string transport { get; set; }
|
||||||
|
|
||||||
public string location { get; set; }
|
public string location { get; set; }
|
||||||
|
|
||||||
public string uri { get; set; }
|
public string uri { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Lineups
|
public class Lineups
|
||||||
{
|
{
|
||||||
public int code { get; set; }
|
public int code { get; set; }
|
||||||
|
|
||||||
public string serverID { get; set; }
|
public string serverID { get; set; }
|
||||||
|
|
||||||
public string datetime { get; set; }
|
public string datetime { get; set; }
|
||||||
|
|
||||||
public List<Lineup> lineups { get; set; }
|
public List<Lineup> lineups { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -957,8 +973,11 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
public class Headends
|
public class Headends
|
||||||
{
|
{
|
||||||
public string headend { get; set; }
|
public string headend { get; set; }
|
||||||
|
|
||||||
public string transport { get; set; }
|
public string transport { get; set; }
|
||||||
|
|
||||||
public string location { get; set; }
|
public string location { get; set; }
|
||||||
|
|
||||||
public List<Lineup> lineups { get; set; }
|
public List<Lineup> lineups { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -967,59 +986,83 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
public class Map
|
public class Map
|
||||||
{
|
{
|
||||||
public string stationID { get; set; }
|
public string stationID { get; set; }
|
||||||
|
|
||||||
public string channel { get; set; }
|
public string channel { get; set; }
|
||||||
|
|
||||||
public string logicalChannelNumber { get; set; }
|
public string logicalChannelNumber { get; set; }
|
||||||
|
|
||||||
public int uhfVhf { get; set; }
|
public int uhfVhf { get; set; }
|
||||||
|
|
||||||
public int atscMajor { get; set; }
|
public int atscMajor { get; set; }
|
||||||
|
|
||||||
public int atscMinor { get; set; }
|
public int atscMinor { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Broadcaster
|
public class Broadcaster
|
||||||
{
|
{
|
||||||
public string city { get; set; }
|
public string city { get; set; }
|
||||||
|
|
||||||
public string state { get; set; }
|
public string state { get; set; }
|
||||||
|
|
||||||
public string postalcode { get; set; }
|
public string postalcode { get; set; }
|
||||||
|
|
||||||
public string country { get; set; }
|
public string country { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Logo
|
public class Logo
|
||||||
{
|
{
|
||||||
public string URL { get; set; }
|
public string URL { get; set; }
|
||||||
|
|
||||||
public int height { get; set; }
|
public int height { get; set; }
|
||||||
|
|
||||||
public int width { get; set; }
|
public int width { get; set; }
|
||||||
|
|
||||||
public string md5 { get; set; }
|
public string md5 { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Station
|
public class Station
|
||||||
{
|
{
|
||||||
public string stationID { get; set; }
|
public string stationID { get; set; }
|
||||||
|
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
|
|
||||||
public string callsign { get; set; }
|
public string callsign { get; set; }
|
||||||
|
|
||||||
public List<string> broadcastLanguage { get; set; }
|
public List<string> broadcastLanguage { get; set; }
|
||||||
|
|
||||||
public List<string> descriptionLanguage { get; set; }
|
public List<string> descriptionLanguage { get; set; }
|
||||||
|
|
||||||
public Broadcaster broadcaster { get; set; }
|
public Broadcaster broadcaster { get; set; }
|
||||||
|
|
||||||
public string affiliate { get; set; }
|
public string affiliate { get; set; }
|
||||||
|
|
||||||
public Logo logo { get; set; }
|
public Logo logo { get; set; }
|
||||||
|
|
||||||
public bool? isCommercialFree { get; set; }
|
public bool? isCommercialFree { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Metadata
|
public class Metadata
|
||||||
{
|
{
|
||||||
public string lineup { get; set; }
|
public string lineup { get; set; }
|
||||||
|
|
||||||
public string modified { get; set; }
|
public string modified { get; set; }
|
||||||
|
|
||||||
public string transport { get; set; }
|
public string transport { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Channel
|
public class Channel
|
||||||
{
|
{
|
||||||
public List<Map> map { get; set; }
|
public List<Map> map { get; set; }
|
||||||
|
|
||||||
public List<Station> stations { get; set; }
|
public List<Station> stations { get; set; }
|
||||||
|
|
||||||
public Metadata metadata { get; set; }
|
public Metadata metadata { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RequestScheduleForChannel
|
public class RequestScheduleForChannel
|
||||||
{
|
{
|
||||||
public string stationID { get; set; }
|
public string stationID { get; set; }
|
||||||
|
|
||||||
public List<string> date { get; set; }
|
public List<string> date { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1029,29 +1072,43 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
public class Rating
|
public class Rating
|
||||||
{
|
{
|
||||||
public string body { get; set; }
|
public string body { get; set; }
|
||||||
|
|
||||||
public string code { get; set; }
|
public string code { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Multipart
|
public class Multipart
|
||||||
{
|
{
|
||||||
public int partNumber { get; set; }
|
public int partNumber { get; set; }
|
||||||
|
|
||||||
public int totalParts { get; set; }
|
public int totalParts { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
public string programID { get; set; }
|
public string programID { get; set; }
|
||||||
|
|
||||||
public string airDateTime { get; set; }
|
public string airDateTime { get; set; }
|
||||||
|
|
||||||
public int duration { get; set; }
|
public int duration { get; set; }
|
||||||
|
|
||||||
public string md5 { get; set; }
|
public string md5 { get; set; }
|
||||||
|
|
||||||
public List<string> audioProperties { get; set; }
|
public List<string> audioProperties { get; set; }
|
||||||
|
|
||||||
public List<string> videoProperties { get; set; }
|
public List<string> videoProperties { get; set; }
|
||||||
|
|
||||||
public List<Rating> ratings { get; set; }
|
public List<Rating> ratings { get; set; }
|
||||||
|
|
||||||
public bool? @new { get; set; }
|
public bool? @new { get; set; }
|
||||||
|
|
||||||
public Multipart multipart { get; set; }
|
public Multipart multipart { get; set; }
|
||||||
|
|
||||||
public string liveTapeDelay { get; set; }
|
public string liveTapeDelay { get; set; }
|
||||||
|
|
||||||
public bool premiere { get; set; }
|
public bool premiere { get; set; }
|
||||||
|
|
||||||
public bool repeat { get; set; }
|
public bool repeat { get; set; }
|
||||||
|
|
||||||
public string isPremiereOrFinale { get; set; }
|
public string isPremiereOrFinale { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1060,16 +1117,22 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
public class MetadataSchedule
|
public class MetadataSchedule
|
||||||
{
|
{
|
||||||
public string modified { get; set; }
|
public string modified { get; set; }
|
||||||
|
|
||||||
public string md5 { get; set; }
|
public string md5 { get; set; }
|
||||||
|
|
||||||
public string startDate { get; set; }
|
public string startDate { get; set; }
|
||||||
|
|
||||||
public string endDate { get; set; }
|
public string endDate { get; set; }
|
||||||
|
|
||||||
public int days { get; set; }
|
public int days { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Day
|
public class Day
|
||||||
{
|
{
|
||||||
public string stationID { get; set; }
|
public string stationID { get; set; }
|
||||||
|
|
||||||
public List<Program> programs { get; set; }
|
public List<Program> programs { get; set; }
|
||||||
|
|
||||||
public MetadataSchedule metadata { get; set; }
|
public MetadataSchedule metadata { get; set; }
|
||||||
|
|
||||||
public Day()
|
public Day()
|
||||||
@ -1092,24 +1155,28 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
public class Description100
|
public class Description100
|
||||||
{
|
{
|
||||||
public string descriptionLanguage { get; set; }
|
public string descriptionLanguage { get; set; }
|
||||||
|
|
||||||
public string description { get; set; }
|
public string description { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Description1000
|
public class Description1000
|
||||||
{
|
{
|
||||||
public string descriptionLanguage { get; set; }
|
public string descriptionLanguage { get; set; }
|
||||||
|
|
||||||
public string description { get; set; }
|
public string description { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DescriptionsProgram
|
public class DescriptionsProgram
|
||||||
{
|
{
|
||||||
public List<Description100> description100 { get; set; }
|
public List<Description100> description100 { get; set; }
|
||||||
|
|
||||||
public List<Description1000> description1000 { get; set; }
|
public List<Description1000> description1000 { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Gracenote
|
public class Gracenote
|
||||||
{
|
{
|
||||||
public int season { get; set; }
|
public int season { get; set; }
|
||||||
|
|
||||||
public int episode { get; set; }
|
public int episode { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1121,104 +1188,154 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
public class ContentRating
|
public class ContentRating
|
||||||
{
|
{
|
||||||
public string body { get; set; }
|
public string body { get; set; }
|
||||||
|
|
||||||
public string code { get; set; }
|
public string code { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Cast
|
public class Cast
|
||||||
{
|
{
|
||||||
public string billingOrder { get; set; }
|
public string billingOrder { get; set; }
|
||||||
|
|
||||||
public string role { get; set; }
|
public string role { get; set; }
|
||||||
|
|
||||||
public string nameId { get; set; }
|
public string nameId { get; set; }
|
||||||
|
|
||||||
public string personId { get; set; }
|
public string personId { get; set; }
|
||||||
|
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
|
|
||||||
public string characterName { get; set; }
|
public string characterName { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Crew
|
public class Crew
|
||||||
{
|
{
|
||||||
public string billingOrder { get; set; }
|
public string billingOrder { get; set; }
|
||||||
|
|
||||||
public string role { get; set; }
|
public string role { get; set; }
|
||||||
|
|
||||||
public string nameId { get; set; }
|
public string nameId { get; set; }
|
||||||
|
|
||||||
public string personId { get; set; }
|
public string personId { get; set; }
|
||||||
|
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class QualityRating
|
public class QualityRating
|
||||||
{
|
{
|
||||||
public string ratingsBody { get; set; }
|
public string ratingsBody { get; set; }
|
||||||
|
|
||||||
public string rating { get; set; }
|
public string rating { get; set; }
|
||||||
|
|
||||||
public string minRating { get; set; }
|
public string minRating { get; set; }
|
||||||
|
|
||||||
public string maxRating { get; set; }
|
public string maxRating { get; set; }
|
||||||
|
|
||||||
public string increment { get; set; }
|
public string increment { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Movie
|
public class Movie
|
||||||
{
|
{
|
||||||
public string year { get; set; }
|
public string year { get; set; }
|
||||||
|
|
||||||
public int duration { get; set; }
|
public int duration { get; set; }
|
||||||
|
|
||||||
public List<QualityRating> qualityRating { get; set; }
|
public List<QualityRating> qualityRating { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Recommendation
|
public class Recommendation
|
||||||
{
|
{
|
||||||
public string programID { get; set; }
|
public string programID { get; set; }
|
||||||
|
|
||||||
public string title120 { get; set; }
|
public string title120 { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ProgramDetails
|
public class ProgramDetails
|
||||||
{
|
{
|
||||||
public string audience { get; set; }
|
public string audience { get; set; }
|
||||||
|
|
||||||
public string programID { get; set; }
|
public string programID { get; set; }
|
||||||
|
|
||||||
public List<Title> titles { get; set; }
|
public List<Title> titles { get; set; }
|
||||||
|
|
||||||
public EventDetails eventDetails { get; set; }
|
public EventDetails eventDetails { get; set; }
|
||||||
|
|
||||||
public DescriptionsProgram descriptions { get; set; }
|
public DescriptionsProgram descriptions { get; set; }
|
||||||
|
|
||||||
public string originalAirDate { get; set; }
|
public string originalAirDate { get; set; }
|
||||||
|
|
||||||
public List<string> genres { get; set; }
|
public List<string> genres { get; set; }
|
||||||
|
|
||||||
public string episodeTitle150 { get; set; }
|
public string episodeTitle150 { get; set; }
|
||||||
|
|
||||||
public List<MetadataPrograms> metadata { get; set; }
|
public List<MetadataPrograms> metadata { get; set; }
|
||||||
|
|
||||||
public List<ContentRating> contentRating { get; set; }
|
public List<ContentRating> contentRating { get; set; }
|
||||||
|
|
||||||
public List<Cast> cast { get; set; }
|
public List<Cast> cast { get; set; }
|
||||||
|
|
||||||
public List<Crew> crew { get; set; }
|
public List<Crew> crew { get; set; }
|
||||||
|
|
||||||
public string entityType { get; set; }
|
public string entityType { get; set; }
|
||||||
|
|
||||||
public string showType { get; set; }
|
public string showType { get; set; }
|
||||||
|
|
||||||
public bool hasImageArtwork { get; set; }
|
public bool hasImageArtwork { get; set; }
|
||||||
|
|
||||||
public string primaryImage { get; set; }
|
public string primaryImage { get; set; }
|
||||||
|
|
||||||
public string thumbImage { get; set; }
|
public string thumbImage { get; set; }
|
||||||
|
|
||||||
public string backdropImage { get; set; }
|
public string backdropImage { get; set; }
|
||||||
|
|
||||||
public string bannerImage { get; set; }
|
public string bannerImage { get; set; }
|
||||||
|
|
||||||
public string imageID { get; set; }
|
public string imageID { get; set; }
|
||||||
|
|
||||||
public string md5 { get; set; }
|
public string md5 { get; set; }
|
||||||
|
|
||||||
public List<string> contentAdvisory { get; set; }
|
public List<string> contentAdvisory { get; set; }
|
||||||
|
|
||||||
public Movie movie { get; set; }
|
public Movie movie { get; set; }
|
||||||
|
|
||||||
public List<Recommendation> recommendations { get; set; }
|
public List<Recommendation> recommendations { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Caption
|
public class Caption
|
||||||
{
|
{
|
||||||
public string content { get; set; }
|
public string content { get; set; }
|
||||||
|
|
||||||
public string lang { get; set; }
|
public string lang { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ImageData
|
public class ImageData
|
||||||
{
|
{
|
||||||
public string width { get; set; }
|
public string width { get; set; }
|
||||||
|
|
||||||
public string height { get; set; }
|
public string height { get; set; }
|
||||||
|
|
||||||
public string uri { get; set; }
|
public string uri { get; set; }
|
||||||
|
|
||||||
public string size { get; set; }
|
public string size { get; set; }
|
||||||
|
|
||||||
public string aspect { get; set; }
|
public string aspect { get; set; }
|
||||||
|
|
||||||
public string category { get; set; }
|
public string category { get; set; }
|
||||||
|
|
||||||
public string text { get; set; }
|
public string text { get; set; }
|
||||||
|
|
||||||
public string primary { get; set; }
|
public string primary { get; set; }
|
||||||
|
|
||||||
public string tier { get; set; }
|
public string tier { get; set; }
|
||||||
|
|
||||||
public Caption caption { get; set; }
|
public Caption caption { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ShowImages
|
public class ShowImages
|
||||||
{
|
{
|
||||||
public string programID { get; set; }
|
public string programID { get; set; }
|
||||||
|
|
||||||
public List<ImageData> data { get; set; }
|
public List<ImageData> data { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,6 +224,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
{
|
{
|
||||||
uniqueString = "-" + programInfo.SeasonNumber.Value.ToString(CultureInfo.InvariantCulture);
|
uniqueString = "-" + programInfo.SeasonNumber.Value.ToString(CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (programInfo.EpisodeNumber.HasValue)
|
if (programInfo.EpisodeNumber.HasValue)
|
||||||
{
|
{
|
||||||
uniqueString = "-" + programInfo.EpisodeNumber.Value.ToString(CultureInfo.InvariantCulture);
|
uniqueString = "-" + programInfo.EpisodeNumber.Value.ToString(CultureInfo.InvariantCulture);
|
||||||
|
@ -7,6 +7,8 @@ using System.Linq;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Emby.Server.Implementations.Library;
|
using Emby.Server.Implementations.Library;
|
||||||
|
using Jellyfin.Data.Entities;
|
||||||
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Progress;
|
using MediaBrowser.Common.Progress;
|
||||||
@ -14,8 +16,6 @@ using MediaBrowser.Controller.Channels;
|
|||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Movies;
|
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.LiveTv;
|
using MediaBrowser.Controller.LiveTv;
|
||||||
using MediaBrowser.Controller.Persistence;
|
using MediaBrowser.Controller.Persistence;
|
||||||
@ -31,6 +31,8 @@ using MediaBrowser.Model.Querying;
|
|||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using MediaBrowser.Model.Tasks;
|
using MediaBrowser.Model.Tasks;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Episode = MediaBrowser.Controller.Entities.TV.Episode;
|
||||||
|
using Movie = MediaBrowser.Controller.Entities.Movies.Movie;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.LiveTv
|
namespace Emby.Server.Implementations.LiveTv
|
||||||
{
|
{
|
||||||
@ -404,8 +406,8 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
if (!(service is EmbyTV.EmbyTV))
|
if (!(service is EmbyTV.EmbyTV))
|
||||||
{
|
{
|
||||||
// We can't trust that we'll be able to direct stream it through emby server, no matter what the provider says
|
// We can't trust that we'll be able to direct stream it through emby server, no matter what the provider says
|
||||||
//mediaSource.SupportsDirectPlay = false;
|
// mediaSource.SupportsDirectPlay = false;
|
||||||
//mediaSource.SupportsDirectStream = false;
|
// mediaSource.SupportsDirectStream = false;
|
||||||
mediaSource.SupportsTranscoding = true;
|
mediaSource.SupportsTranscoding = true;
|
||||||
foreach (var stream in mediaSource.MediaStreams)
|
foreach (var stream in mediaSource.MediaStreams)
|
||||||
{
|
{
|
||||||
@ -554,9 +556,10 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
{
|
{
|
||||||
forceUpdate = true;
|
forceUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
item.ParentId = channel.Id;
|
item.ParentId = channel.Id;
|
||||||
|
|
||||||
//item.ChannelType = channelType;
|
// item.ChannelType = channelType;
|
||||||
|
|
||||||
item.Audio = info.Audio;
|
item.Audio = info.Audio;
|
||||||
item.ChannelId = channel.Id;
|
item.ChannelId = channel.Id;
|
||||||
@ -573,6 +576,7 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
{
|
{
|
||||||
forceUpdate = true;
|
forceUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
item.ExternalSeriesId = seriesId;
|
item.ExternalSeriesId = seriesId;
|
||||||
|
|
||||||
var isSeries = info.IsSeries || !string.IsNullOrEmpty(info.EpisodeTitle);
|
var isSeries = info.IsSeries || !string.IsNullOrEmpty(info.EpisodeTitle);
|
||||||
@ -587,30 +591,37 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
{
|
{
|
||||||
tags.Add("Live");
|
tags.Add("Live");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.IsPremiere)
|
if (info.IsPremiere)
|
||||||
{
|
{
|
||||||
tags.Add("Premiere");
|
tags.Add("Premiere");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.IsNews)
|
if (info.IsNews)
|
||||||
{
|
{
|
||||||
tags.Add("News");
|
tags.Add("News");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.IsSports)
|
if (info.IsSports)
|
||||||
{
|
{
|
||||||
tags.Add("Sports");
|
tags.Add("Sports");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.IsKids)
|
if (info.IsKids)
|
||||||
{
|
{
|
||||||
tags.Add("Kids");
|
tags.Add("Kids");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.IsRepeat)
|
if (info.IsRepeat)
|
||||||
{
|
{
|
||||||
tags.Add("Repeat");
|
tags.Add("Repeat");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.IsMovie)
|
if (info.IsMovie)
|
||||||
{
|
{
|
||||||
tags.Add("Movie");
|
tags.Add("Movie");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSeries)
|
if (isSeries)
|
||||||
{
|
{
|
||||||
tags.Add("Series");
|
tags.Add("Series");
|
||||||
@ -633,6 +644,7 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
{
|
{
|
||||||
forceUpdate = true;
|
forceUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
item.IsSeries = isSeries;
|
item.IsSeries = isSeries;
|
||||||
|
|
||||||
item.Name = info.Name;
|
item.Name = info.Name;
|
||||||
@ -650,12 +662,14 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
{
|
{
|
||||||
forceUpdate = true;
|
forceUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
item.StartDate = info.StartDate;
|
item.StartDate = info.StartDate;
|
||||||
|
|
||||||
if (item.EndDate != info.EndDate)
|
if (item.EndDate != info.EndDate)
|
||||||
{
|
{
|
||||||
forceUpdate = true;
|
forceUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
item.EndDate = info.EndDate;
|
item.EndDate = info.EndDate;
|
||||||
|
|
||||||
item.ProductionYear = info.ProductionYear;
|
item.ProductionYear = info.ProductionYear;
|
||||||
@ -696,7 +710,6 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
{
|
{
|
||||||
Path = info.ThumbImageUrl,
|
Path = info.ThumbImageUrl,
|
||||||
Type = ImageType.Thumb
|
Type = ImageType.Thumb
|
||||||
|
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -709,7 +722,6 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
{
|
{
|
||||||
Path = info.LogoImageUrl,
|
Path = info.LogoImageUrl,
|
||||||
Type = ImageType.Logo
|
Type = ImageType.Logo
|
||||||
|
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -722,7 +734,6 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
{
|
{
|
||||||
Path = info.BackdropImageUrl,
|
Path = info.BackdropImageUrl,
|
||||||
Type = ImageType.Backdrop
|
Type = ImageType.Backdrop
|
||||||
|
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -760,7 +771,8 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
|
|
||||||
var dto = _dtoService.GetBaseItemDto(program, new DtoOptions(), user);
|
var dto = _dtoService.GetBaseItemDto(program, new DtoOptions(), user);
|
||||||
|
|
||||||
var list = new List<Tuple<BaseItemDto, string, string>>() {
|
var list = new List<Tuple<BaseItemDto, string, string>>
|
||||||
|
{
|
||||||
new Tuple<BaseItemDto, string, string>(dto, program.ExternalId, program.ExternalSeriesId)
|
new Tuple<BaseItemDto, string, string>(dto, program.ExternalId, program.ExternalSeriesId)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1168,7 +1180,6 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
IncludeItemTypes = new string[] { typeof(LiveTvProgram).Name },
|
IncludeItemTypes = new string[] { typeof(LiveTvProgram).Name },
|
||||||
ChannelIds = new Guid[] { currentChannel.Id },
|
ChannelIds = new Guid[] { currentChannel.Id },
|
||||||
DtoOptions = new DtoOptions(true)
|
DtoOptions = new DtoOptions(true)
|
||||||
|
|
||||||
}).Cast<LiveTvProgram>().ToDictionary(i => i.Id);
|
}).Cast<LiveTvProgram>().ToDictionary(i => i.Id);
|
||||||
|
|
||||||
var newPrograms = new List<LiveTvProgram>();
|
var newPrograms = new List<LiveTvProgram>();
|
||||||
@ -1368,10 +1379,10 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
// limit = (query.Limit ?? 10) * 2;
|
// limit = (query.Limit ?? 10) * 2;
|
||||||
limit = null;
|
limit = null;
|
||||||
|
|
||||||
//var allActivePaths = EmbyTV.EmbyTV.Current.GetAllActiveRecordings().Select(i => i.Path).ToArray();
|
// var allActivePaths = EmbyTV.EmbyTV.Current.GetAllActiveRecordings().Select(i => i.Path).ToArray();
|
||||||
//var items = allActivePaths.Select(i => _libraryManager.FindByPath(i, false)).Where(i => i != null).ToArray();
|
// var items = allActivePaths.Select(i => _libraryManager.FindByPath(i, false)).Where(i => i != null).ToArray();
|
||||||
|
|
||||||
//return new QueryResult<BaseItem>
|
// return new QueryResult<BaseItem>
|
||||||
//{
|
//{
|
||||||
// Items = items,
|
// Items = items,
|
||||||
// TotalRecordCount = items.Length
|
// TotalRecordCount = items.Length
|
||||||
@ -1738,7 +1749,6 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
var results = await GetTimers(new TimerQuery
|
var results = await GetTimers(new TimerQuery
|
||||||
{
|
{
|
||||||
Id = id
|
Id = id
|
||||||
|
|
||||||
}, cancellationToken).ConfigureAwait(false);
|
}, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
return results.Items.FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.OrdinalIgnoreCase));
|
return results.Items.FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.OrdinalIgnoreCase));
|
||||||
@ -1790,7 +1800,6 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
.Select(i =>
|
.Select(i =>
|
||||||
{
|
{
|
||||||
return i.Item1;
|
return i.Item1;
|
||||||
|
|
||||||
})
|
})
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
@ -1845,7 +1854,6 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
}
|
}
|
||||||
|
|
||||||
return _tvDtoService.GetSeriesTimerInfoDto(i.Item1, i.Item2, channelName);
|
return _tvDtoService.GetSeriesTimerInfoDto(i.Item1, i.Item2, channelName);
|
||||||
|
|
||||||
})
|
})
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
@ -1878,7 +1886,6 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
OrderBy = new[] { (ItemSortBy.StartDate, SortOrder.Ascending) },
|
OrderBy = new[] { (ItemSortBy.StartDate, SortOrder.Ascending) },
|
||||||
TopParentIds = new[] { GetInternalLiveTvFolder(CancellationToken.None).Id },
|
TopParentIds = new[] { GetInternalLiveTvFolder(CancellationToken.None).Id },
|
||||||
DtoOptions = options
|
DtoOptions = options
|
||||||
|
|
||||||
}) : new List<BaseItem>();
|
}) : new List<BaseItem>();
|
||||||
|
|
||||||
RemoveFields(options);
|
RemoveFields(options);
|
||||||
@ -1956,7 +1963,7 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
OriginalAirDate = program.PremiereDate,
|
OriginalAirDate = program.PremiereDate,
|
||||||
Overview = program.Overview,
|
Overview = program.Overview,
|
||||||
StartDate = program.StartDate,
|
StartDate = program.StartDate,
|
||||||
//ImagePath = program.ExternalImagePath,
|
// ImagePath = program.ExternalImagePath,
|
||||||
Name = program.Name,
|
Name = program.Name,
|
||||||
OfficialRating = program.OfficialRating
|
OfficialRating = program.OfficialRating
|
||||||
};
|
};
|
||||||
@ -2167,20 +2174,19 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
var info = new LiveTvInfo
|
var info = new LiveTvInfo
|
||||||
{
|
{
|
||||||
Services = services,
|
Services = services,
|
||||||
IsEnabled = services.Length > 0
|
IsEnabled = services.Length > 0,
|
||||||
|
EnabledUsers = _userManager.Users
|
||||||
|
.Where(IsLiveTvEnabled)
|
||||||
|
.Select(i => i.Id.ToString("N", CultureInfo.InvariantCulture))
|
||||||
|
.ToArray()
|
||||||
};
|
};
|
||||||
|
|
||||||
info.EnabledUsers = _userManager.Users
|
|
||||||
.Where(IsLiveTvEnabled)
|
|
||||||
.Select(i => i.Id.ToString("N", CultureInfo.InvariantCulture))
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsLiveTvEnabled(User user)
|
private bool IsLiveTvEnabled(User user)
|
||||||
{
|
{
|
||||||
return user.Policy.EnableLiveTvAccess && (Services.Count > 1 || GetConfiguration().TunerHosts.Length > 0);
|
return user.HasPermission(PermissionKind.EnableLiveTvAccess) && (Services.Count > 1 || GetConfiguration().TunerHosts.Length > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<User> GetEnabledUsers()
|
public IEnumerable<User> GetEnabledUsers()
|
||||||
@ -2457,7 +2463,6 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
UserId = user.Id,
|
UserId = user.Id,
|
||||||
IsRecordingsFolder = true,
|
IsRecordingsFolder = true,
|
||||||
RefreshLatestChannelItems = refreshChannels
|
RefreshLatestChannelItems = refreshChannels
|
||||||
|
|
||||||
}).Items);
|
}).Items);
|
||||||
|
|
||||||
return folders.Cast<BaseItem>().ToList();
|
return folders.Cast<BaseItem>().ToList();
|
||||||
|
@ -35,7 +35,7 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates the triggers that define when the task will run
|
/// Creates the triggers that define when the task will run.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
|
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
|
||||||
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
||||||
|
@ -54,7 +54,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
|
|
||||||
var result = await GetChannelsInternal(tuner, cancellationToken).ConfigureAwait(false);
|
var result = await GetChannelsInternal(tuner, cancellationToken).ConfigureAwait(false);
|
||||||
var list = result.ToList();
|
var list = result.ToList();
|
||||||
//logger.LogInformation("Channels from {0}: {1}", tuner.Url, JsonSerializer.SerializeToString(list));
|
// logger.LogInformation("Channels from {0}: {1}", tuner.Url, JsonSerializer.SerializeToString(list));
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(key) && list.Count > 0)
|
if (!string.IsNullOrEmpty(key) && list.Count > 0)
|
||||||
{
|
{
|
||||||
@ -99,7 +99,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
}
|
}
|
||||||
catch (IOException)
|
catch (IOException)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,7 +115,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
}
|
}
|
||||||
catch (IOException)
|
catch (IOException)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||||||
ChannelType = ChannelType.TV,
|
ChannelType = ChannelType.TV,
|
||||||
IsLegacyTuner = (i.URL ?? string.Empty).StartsWith("hdhomerun", StringComparison.OrdinalIgnoreCase),
|
IsLegacyTuner = (i.URL ?? string.Empty).StartsWith("hdhomerun", StringComparison.OrdinalIgnoreCase),
|
||||||
Path = i.URL
|
Path = i.URL
|
||||||
|
|
||||||
}).Cast<ChannelInfo>().ToList();
|
}).Cast<ChannelInfo>().ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,6 +170,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||||||
_modelCache[cacheKey] = response;
|
_modelCache[cacheKey] = response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,6 +202,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||||||
var name = line.Substring(0, index - 1);
|
var name = line.Substring(0, index - 1);
|
||||||
var currentChannel = line.Substring(index + 7);
|
var currentChannel = line.Substring(index + 7);
|
||||||
if (currentChannel != "none") { status = LiveTvTunerStatus.LiveTv; } else { status = LiveTvTunerStatus.Available; }
|
if (currentChannel != "none") { status = LiveTvTunerStatus.LiveTv; } else { status = LiveTvTunerStatus.Available; }
|
||||||
|
|
||||||
tuners.Add(new LiveTvTunerInfo
|
tuners.Add(new LiveTvTunerInfo
|
||||||
{
|
{
|
||||||
Name = name,
|
Name = name,
|
||||||
@ -230,11 +231,13 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||||||
inside = true;
|
inside = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (let == '>')
|
if (let == '>')
|
||||||
{
|
{
|
||||||
inside = false;
|
inside = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inside)
|
if (!inside)
|
||||||
{
|
{
|
||||||
buffer[bufferIndex] = let;
|
buffer[bufferIndex] = let;
|
||||||
@ -332,12 +335,19 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||||||
private class Channels
|
private class Channels
|
||||||
{
|
{
|
||||||
public string GuideNumber { get; set; }
|
public string GuideNumber { get; set; }
|
||||||
|
|
||||||
public string GuideName { get; set; }
|
public string GuideName { get; set; }
|
||||||
|
|
||||||
public string VideoCodec { get; set; }
|
public string VideoCodec { get; set; }
|
||||||
|
|
||||||
public string AudioCodec { get; set; }
|
public string AudioCodec { get; set; }
|
||||||
|
|
||||||
public string URL { get; set; }
|
public string URL { get; set; }
|
||||||
|
|
||||||
public bool Favorite { get; set; }
|
public bool Favorite { get; set; }
|
||||||
|
|
||||||
public bool DRM { get; set; }
|
public bool DRM { get; set; }
|
||||||
|
|
||||||
public int HD { get; set; }
|
public int HD { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,7 +491,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||||||
Height = height,
|
Height = height,
|
||||||
BitRate = videoBitrate,
|
BitRate = videoBitrate,
|
||||||
NalLengthSize = nal
|
NalLengthSize = nal
|
||||||
|
|
||||||
},
|
},
|
||||||
new MediaStream
|
new MediaStream
|
||||||
{
|
{
|
||||||
@ -502,8 +511,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||||||
SupportsTranscoding = true,
|
SupportsTranscoding = true,
|
||||||
IsInfiniteStream = true,
|
IsInfiniteStream = true,
|
||||||
IgnoreDts = true,
|
IgnoreDts = true,
|
||||||
//IgnoreIndex = true,
|
// IgnoreIndex = true,
|
||||||
//ReadAtNativeFramerate = true
|
// ReadAtNativeFramerate = true
|
||||||
};
|
};
|
||||||
|
|
||||||
mediaSource.InferTotalBitrate();
|
mediaSource.InferTotalBitrate();
|
||||||
@ -659,13 +668,21 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||||||
public class DiscoverResponse
|
public class DiscoverResponse
|
||||||
{
|
{
|
||||||
public string FriendlyName { get; set; }
|
public string FriendlyName { get; set; }
|
||||||
|
|
||||||
public string ModelNumber { get; set; }
|
public string ModelNumber { get; set; }
|
||||||
|
|
||||||
public string FirmwareName { get; set; }
|
public string FirmwareName { get; set; }
|
||||||
|
|
||||||
public string FirmwareVersion { get; set; }
|
public string FirmwareVersion { get; set; }
|
||||||
|
|
||||||
public string DeviceID { get; set; }
|
public string DeviceID { get; set; }
|
||||||
|
|
||||||
public string DeviceAuth { get; set; }
|
public string DeviceAuth { get; set; }
|
||||||
|
|
||||||
public string BaseURL { get; set; }
|
public string BaseURL { get; set; }
|
||||||
|
|
||||||
public string LineupURL { get; set; }
|
public string LineupURL { get; set; }
|
||||||
|
|
||||||
public int TunerCount { get; set; }
|
public int TunerCount { get; set; }
|
||||||
|
|
||||||
public bool SupportsTranscoding
|
public bool SupportsTranscoding
|
||||||
@ -722,7 +739,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
|
@ -117,17 +117,17 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||||||
taskCompletionSource,
|
taskCompletionSource,
|
||||||
LiveStreamCancellationTokenSource.Token).ConfigureAwait(false);
|
LiveStreamCancellationTokenSource.Token).ConfigureAwait(false);
|
||||||
|
|
||||||
//OpenedMediaSource.Protocol = MediaProtocol.File;
|
// OpenedMediaSource.Protocol = MediaProtocol.File;
|
||||||
//OpenedMediaSource.Path = tempFile;
|
// OpenedMediaSource.Path = tempFile;
|
||||||
//OpenedMediaSource.ReadAtNativeFramerate = true;
|
// OpenedMediaSource.ReadAtNativeFramerate = true;
|
||||||
|
|
||||||
MediaSource.Path = _appHost.GetLoopbackHttpApiUrl() + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
|
MediaSource.Path = _appHost.GetLoopbackHttpApiUrl() + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
|
||||||
MediaSource.Protocol = MediaProtocol.Http;
|
MediaSource.Protocol = MediaProtocol.Http;
|
||||||
//OpenedMediaSource.SupportsDirectPlay = false;
|
// OpenedMediaSource.SupportsDirectPlay = false;
|
||||||
//OpenedMediaSource.SupportsDirectStream = true;
|
// OpenedMediaSource.SupportsDirectStream = true;
|
||||||
//OpenedMediaSource.SupportsTranscoding = true;
|
// OpenedMediaSource.SupportsTranscoding = true;
|
||||||
|
|
||||||
//await Task.Delay(5000).ConfigureAwait(false);
|
// await Task.Delay(5000).ConfigureAwait(false);
|
||||||
await taskCompletionSource.Task.ConfigureAwait(false);
|
await taskCompletionSource.Task.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,12 +58,15 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
protected virtual int EmptyReadLimit => 1000;
|
protected virtual int EmptyReadLimit => 1000;
|
||||||
|
|
||||||
public MediaSourceInfo OriginalMediaSource { get; set; }
|
public MediaSourceInfo OriginalMediaSource { get; set; }
|
||||||
|
|
||||||
public MediaSourceInfo MediaSource { get; set; }
|
public MediaSourceInfo MediaSource { get; set; }
|
||||||
|
|
||||||
public int ConsumerCount { get; set; }
|
public int ConsumerCount { get; set; }
|
||||||
|
|
||||||
public string OriginalStreamId { get; set; }
|
public string OriginalStreamId { get; set; }
|
||||||
|
|
||||||
public bool EnableStreamSharing { get; set; }
|
public bool EnableStreamSharing { get; set; }
|
||||||
|
|
||||||
public string UniqueId { get; }
|
public string UniqueId { get; }
|
||||||
|
|
||||||
public string TunerHostId { get; }
|
public string TunerHostId { get; }
|
||||||
@ -220,11 +223,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
}
|
}
|
||||||
catch (IOException)
|
catch (IOException)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (ArgumentException)
|
catch (ArgumentException)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -127,7 +127,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
{
|
{
|
||||||
using (var stream = await new M3uParser(Logger, _httpClient, _appHost).GetListingsStream(info.Url, CancellationToken.None).ConfigureAwait(false))
|
using (var stream = await new M3uParser(Logger, _httpClient, _appHost).GetListingsStream(info.Url, CancellationToken.None).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,7 +210,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsValidChannelNumber(numberString))
|
if (!IsValidChannelNumber(numberString))
|
||||||
@ -284,7 +283,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
|
|
||||||
if (double.TryParse(numberPart, NumberStyles.Any, CultureInfo.InvariantCulture, out var number))
|
if (double.TryParse(numberPart, NumberStyles.Any, CultureInfo.InvariantCulture, out var number))
|
||||||
{
|
{
|
||||||
//channel.Number = number.ToString();
|
// channel.Number = number.ToString();
|
||||||
nameInExtInf = nameInExtInf.Substring(numberIndex + 1).Trim(new[] { ' ', '-' });
|
nameInExtInf = nameInExtInf.Substring(numberIndex + 1).Trim(new[] { ' ', '-' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,21 +103,21 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
|
|
||||||
_ = StartStreaming(response, taskCompletionSource, LiveStreamCancellationTokenSource.Token);
|
_ = StartStreaming(response, taskCompletionSource, LiveStreamCancellationTokenSource.Token);
|
||||||
|
|
||||||
//OpenedMediaSource.Protocol = MediaProtocol.File;
|
// OpenedMediaSource.Protocol = MediaProtocol.File;
|
||||||
//OpenedMediaSource.Path = tempFile;
|
// OpenedMediaSource.Path = tempFile;
|
||||||
//OpenedMediaSource.ReadAtNativeFramerate = true;
|
// OpenedMediaSource.ReadAtNativeFramerate = true;
|
||||||
|
|
||||||
MediaSource.Path = _appHost.GetLoopbackHttpApiUrl() + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
|
MediaSource.Path = _appHost.GetLoopbackHttpApiUrl() + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
|
||||||
MediaSource.Protocol = MediaProtocol.Http;
|
MediaSource.Protocol = MediaProtocol.Http;
|
||||||
|
|
||||||
//OpenedMediaSource.Path = TempFilePath;
|
// OpenedMediaSource.Path = TempFilePath;
|
||||||
//OpenedMediaSource.Protocol = MediaProtocol.File;
|
// OpenedMediaSource.Protocol = MediaProtocol.File;
|
||||||
|
|
||||||
//OpenedMediaSource.Path = _tempFilePath;
|
// OpenedMediaSource.Path = _tempFilePath;
|
||||||
//OpenedMediaSource.Protocol = MediaProtocol.File;
|
// OpenedMediaSource.Protocol = MediaProtocol.File;
|
||||||
//OpenedMediaSource.SupportsDirectPlay = false;
|
// OpenedMediaSource.SupportsDirectPlay = false;
|
||||||
//OpenedMediaSource.SupportsDirectStream = true;
|
// OpenedMediaSource.SupportsDirectStream = true;
|
||||||
//OpenedMediaSource.SupportsTranscoding = true;
|
// OpenedMediaSource.SupportsTranscoding = true;
|
||||||
await taskCompletionSource.Task.ConfigureAwait(false);
|
await taskCompletionSource.Task.ConfigureAwait(false);
|
||||||
if (taskCompletionSource.Task.Exception != null)
|
if (taskCompletionSource.Task.Exception != null)
|
||||||
{
|
{
|
||||||
|
@ -62,13 +62,13 @@
|
|||||||
"NotificationOptionPluginInstalled": "প্লাগিন ইন্সটল করা হয়েছে",
|
"NotificationOptionPluginInstalled": "প্লাগিন ইন্সটল করা হয়েছে",
|
||||||
"NotificationOptionPluginError": "প্লাগিন ব্যর্থ",
|
"NotificationOptionPluginError": "প্লাগিন ব্যর্থ",
|
||||||
"NotificationOptionNewLibraryContent": "নতুন কন্টেন্ট যোগ করা হয়েছে",
|
"NotificationOptionNewLibraryContent": "নতুন কন্টেন্ট যোগ করা হয়েছে",
|
||||||
"NotificationOptionInstallationFailed": "ইন্সটল ব্যর্থ",
|
"NotificationOptionInstallationFailed": "ইন্সটল ব্যর্থ হয়েছে",
|
||||||
"NotificationOptionCameraImageUploaded": "ক্যামেরার ছবি আপলোড হয়েছে",
|
"NotificationOptionCameraImageUploaded": "ক্যামেরার ছবি আপলোড হয়েছে",
|
||||||
"NotificationOptionAudioPlaybackStopped": "গান বাজা বন্ধ হয়েছে",
|
"NotificationOptionAudioPlaybackStopped": "গান বাজা বন্ধ হয়েছে",
|
||||||
"NotificationOptionAudioPlayback": "গান বাজা শুরু হয়েছে",
|
"NotificationOptionAudioPlayback": "গান বাজা শুরু হয়েছে",
|
||||||
"NotificationOptionApplicationUpdateInstalled": "এপ্লিকেশনের আপডেট ইনস্টল করা হয়েছে",
|
"NotificationOptionApplicationUpdateInstalled": "এপ্লিকেশনের আপডেট ইনস্টল করা হয়েছে",
|
||||||
"NotificationOptionApplicationUpdateAvailable": "এপ্লিকেশনের আপডেট রয়েছে",
|
"NotificationOptionApplicationUpdateAvailable": "এপ্লিকেশনের আপডেট রয়েছে",
|
||||||
"NewVersionIsAvailable": "জেলিফিন সার্ভারের একটি নতুন ভার্শন ডাউনলোডের জন্য তৈরী",
|
"NewVersionIsAvailable": "জেলিফিন সার্ভারের একটি নতুন ভার্শন ডাউনলোডের জন্য তৈরী।",
|
||||||
"NameSeasonUnknown": "সিজন অজানা",
|
"NameSeasonUnknown": "সিজন অজানা",
|
||||||
"NameSeasonNumber": "সিজন {0}",
|
"NameSeasonNumber": "সিজন {0}",
|
||||||
"NameInstallFailed": "{0} ইন্সটল ব্যর্থ",
|
"NameInstallFailed": "{0} ইন্সটল ব্যর্থ",
|
||||||
@ -100,5 +100,18 @@
|
|||||||
"TaskCleanCacheDescription": "সিস্টেমে আর প্রয়োজন নেই ক্যাশ, ফাইলগুলি মুছে ফেলুন।",
|
"TaskCleanCacheDescription": "সিস্টেমে আর প্রয়োজন নেই ক্যাশ, ফাইলগুলি মুছে ফেলুন।",
|
||||||
"TaskCleanCache": "ক্লিন ক্যাশ ডিরেক্টরি",
|
"TaskCleanCache": "ক্লিন ক্যাশ ডিরেক্টরি",
|
||||||
"TasksChannelsCategory": "ইন্টারনেট চ্যানেল",
|
"TasksChannelsCategory": "ইন্টারনেট চ্যানেল",
|
||||||
"TasksApplicationCategory": "আবেদন"
|
"TasksApplicationCategory": "আবেদন",
|
||||||
|
"TaskDownloadMissingSubtitlesDescription": "মেটাডেটা কনফিগারেশনের উপর ভিত্তি করে অনুপস্থিত সাবটাইটেলগুলির জন্য ইন্টারনেট অনুসন্ধান করে।",
|
||||||
|
"TaskDownloadMissingSubtitles": "অনুপস্থিত সাবটাইটেলগুলি ডাউনলোড করুন",
|
||||||
|
"TaskRefreshChannelsDescription": "ইন্টারনেট চ্যানেল তথ্য রিফ্রেশ করুন।",
|
||||||
|
"TaskRefreshChannels": "চ্যানেল রিফ্রেশ করুন",
|
||||||
|
"TaskCleanTranscodeDescription": "এক দিনেরও বেশি পুরানো ট্রান্সকোড ফাইলগুলি মুছে ফেলুন।",
|
||||||
|
"TaskCleanTranscode": "ট্রান্সকোড ডিরেক্টরি ক্লিন করুন",
|
||||||
|
"TaskUpdatePluginsDescription": "স্বয়ংক্রিয়ভাবে আপডেট কনফিগার করা প্লাগইনগুলির জন্য আপডেট ডাউনলোড এবং ইনস্টল করুন।",
|
||||||
|
"TaskUpdatePlugins": "প্লাগইন আপডেট করুন",
|
||||||
|
"TaskRefreshPeopleDescription": "আপনার মিডিয়া লাইব্রেরিতে অভিনেতা এবং পরিচালকদের জন্য মেটাডাটা আপডেট করুন।",
|
||||||
|
"TaskRefreshPeople": "পিপল রিফ্রেশ করুন",
|
||||||
|
"TaskCleanLogsDescription": "{0} দিনের বেশী পুরানো লগ ফাইলগুলি মুছে ফেলুন।",
|
||||||
|
"TaskCleanLogs": "লগ ডিরেক্টরি ক্লিন করুন",
|
||||||
|
"TaskRefreshLibraryDescription": "নতুন ফাইলের জন্য মিডিয়া লাইব্রেরি স্ক্যান এবং মেটাডাটা রিফ্রেশ করুন।"
|
||||||
}
|
}
|
||||||
|
@ -109,9 +109,10 @@
|
|||||||
"TaskCleanLogs": "Nettoyer le répertoire des journaux",
|
"TaskCleanLogs": "Nettoyer le répertoire des journaux",
|
||||||
"TaskRefreshLibraryDescription": "Analyse votre bibliothèque média pour trouver de nouveaux fichiers et rafraîchit les métadonnées.",
|
"TaskRefreshLibraryDescription": "Analyse votre bibliothèque média pour trouver de nouveaux fichiers et rafraîchit les métadonnées.",
|
||||||
"TaskRefreshChapterImages": "Extraire les images de chapitre",
|
"TaskRefreshChapterImages": "Extraire les images de chapitre",
|
||||||
"TaskRefreshChapterImagesDescription": "Créer des vignettes pour les vidéos qui ont des chapitres",
|
"TaskRefreshChapterImagesDescription": "Créer des vignettes pour les vidéos qui ont des chapitres.",
|
||||||
"TaskRefreshLibrary": "Analyser la bibliothèque de médias",
|
"TaskRefreshLibrary": "Analyser la bibliothèque de médias",
|
||||||
"TaskCleanCache": "Nettoyer le répertoire des fichiers temporaires",
|
"TaskCleanCache": "Nettoyer le répertoire des fichiers temporaires",
|
||||||
"TasksApplicationCategory": "Application",
|
"TasksApplicationCategory": "Application",
|
||||||
"TaskCleanCacheDescription": "Supprime les fichiers temporaires qui ne sont plus nécessaire pour le système."
|
"TaskCleanCacheDescription": "Supprime les fichiers temporaires qui ne sont plus nécessaire pour le système.",
|
||||||
|
"TasksChannelsCategory": "Canaux Internet"
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,6 @@ namespace Emby.Server.Implementations.Net
|
|||||||
}
|
}
|
||||||
catch (SocketException)
|
catch (SocketException)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -109,12 +108,11 @@ namespace Emby.Server.Implementations.Net
|
|||||||
}
|
}
|
||||||
catch (SocketException)
|
catch (SocketException)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
|
// retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
|
||||||
retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, multicastTimeToLive);
|
retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, multicastTimeToLive);
|
||||||
|
|
||||||
var localIp = IPAddress.Any;
|
var localIp = IPAddress.Any;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user