rework server sync
This commit is contained in:
parent
933fca78e6
commit
65fb01bbe2
|
@ -50,8 +50,8 @@ namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
var user = query.User;
|
var user = query.User;
|
||||||
|
|
||||||
if (query.IncludeItemTypes != null &&
|
if (query.IncludeItemTypes != null &&
|
||||||
query.IncludeItemTypes.Length == 1 &&
|
query.IncludeItemTypes.Length == 1 &&
|
||||||
string.Equals(query.IncludeItemTypes[0], "Playlist", StringComparison.OrdinalIgnoreCase))
|
string.Equals(query.IncludeItemTypes[0], "Playlist", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (!string.Equals(viewType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase))
|
if (!string.Equals(viewType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase))
|
||||||
|
@ -117,9 +117,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
|
|
||||||
case CollectionType.LiveTv:
|
case CollectionType.LiveTv:
|
||||||
{
|
{
|
||||||
var result = await GetLiveTvFolders(user).ConfigureAwait(false);
|
return await GetLiveTvView(queryParent, user, query).ConfigureAwait(false);
|
||||||
|
|
||||||
return GetResult(result, queryParent, query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case CollectionType.Books:
|
case CollectionType.Books:
|
||||||
|
@ -215,6 +213,9 @@ namespace MediaBrowser.Controller.Entities
|
||||||
case SpecialFolder.MusicLatest:
|
case SpecialFolder.MusicLatest:
|
||||||
return GetMusicLatest(queryParent, user, query);
|
return GetMusicLatest(queryParent, user, query);
|
||||||
|
|
||||||
|
case SpecialFolder.MusicPlaylists:
|
||||||
|
return await GetMusicPlaylists(queryParent, user, query).ConfigureAwait(false);
|
||||||
|
|
||||||
case SpecialFolder.MusicAlbums:
|
case SpecialFolder.MusicAlbums:
|
||||||
return GetMusicAlbums(queryParent, user, query);
|
return GetMusicAlbums(queryParent, user, query);
|
||||||
|
|
||||||
|
@ -277,12 +278,13 @@ namespace MediaBrowser.Controller.Entities
|
||||||
var list = new List<BaseItem>();
|
var list = new List<BaseItem>();
|
||||||
|
|
||||||
list.Add(await GetUserView(SpecialFolder.MusicLatest, user, "0", parent).ConfigureAwait(false));
|
list.Add(await GetUserView(SpecialFolder.MusicLatest, user, "0", parent).ConfigureAwait(false));
|
||||||
list.Add(await GetUserView(SpecialFolder.MusicAlbums, user, "1", parent).ConfigureAwait(false));
|
list.Add(await GetUserView(SpecialFolder.MusicPlaylists, user, "1", parent).ConfigureAwait(false));
|
||||||
list.Add(await GetUserView(SpecialFolder.MusicAlbumArtists, user, "2", parent).ConfigureAwait(false));
|
list.Add(await GetUserView(SpecialFolder.MusicAlbums, user, "2", parent).ConfigureAwait(false));
|
||||||
//list.Add(await GetUserView(SpecialFolder.MusicArtists, user, "3", parent).ConfigureAwait(false));
|
list.Add(await GetUserView(SpecialFolder.MusicAlbumArtists, user, "3", parent).ConfigureAwait(false));
|
||||||
list.Add(await GetUserView(SpecialFolder.MusicSongs, user, "4", parent).ConfigureAwait(false));
|
//list.Add(await GetUserView(SpecialFolder.MusicArtists, user, "4", parent).ConfigureAwait(false));
|
||||||
list.Add(await GetUserView(SpecialFolder.MusicGenres, user, "5", parent).ConfigureAwait(false));
|
list.Add(await GetUserView(SpecialFolder.MusicSongs, user, "5", parent).ConfigureAwait(false));
|
||||||
list.Add(await GetUserView(SpecialFolder.MusicFavorites, user, "6", parent).ConfigureAwait(false));
|
list.Add(await GetUserView(SpecialFolder.MusicGenres, user, "6", parent).ConfigureAwait(false));
|
||||||
|
list.Add(await GetUserView(SpecialFolder.MusicFavorites, user, "7", parent).ConfigureAwait(false));
|
||||||
|
|
||||||
return GetResult(list, parent, query);
|
return GetResult(list, parent, query);
|
||||||
}
|
}
|
||||||
|
@ -423,6 +425,14 @@ namespace MediaBrowser.Controller.Entities
|
||||||
return GetResult(artists, parent, query);
|
return GetResult(artists, parent, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Task<QueryResult<BaseItem>> GetMusicPlaylists(Folder parent, User user, InternalItemsQuery query)
|
||||||
|
{
|
||||||
|
query.IncludeItemTypes = new[] { "Playlist" };
|
||||||
|
query.Recursive = true;
|
||||||
|
|
||||||
|
return parent.GetItems(query);
|
||||||
|
}
|
||||||
|
|
||||||
private QueryResult<BaseItem> GetMusicAlbums(Folder parent, User user, InternalItemsQuery query)
|
private QueryResult<BaseItem> GetMusicAlbums(Folder parent, User user, InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }, i => (i is MusicAlbum) && FilterItem(i, query));
|
var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }, i => (i is MusicAlbum) && FilterItem(i, query));
|
||||||
|
@ -1769,17 +1779,26 @@ namespace MediaBrowser.Controller.Entities
|
||||||
return parent.GetRecursiveChildren(user, filter);
|
return parent.GetRecursiveChildren(user, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<IEnumerable<BaseItem>> GetLiveTvFolders(User user)
|
private async Task<QueryResult<BaseItem>> GetLiveTvView(Folder queryParent, User user, InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
|
if (query.Recursive)
|
||||||
|
{
|
||||||
|
return await _liveTvManager.GetInternalRecordings(new RecordingQuery
|
||||||
|
{
|
||||||
|
IsInProgress = false,
|
||||||
|
Status = RecordingStatus.Completed,
|
||||||
|
UserId = user.Id.ToString("N")
|
||||||
|
|
||||||
|
}, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
var list = new List<BaseItem>();
|
var list = new List<BaseItem>();
|
||||||
|
|
||||||
var parent = user.RootFolder;
|
|
||||||
|
|
||||||
//list.Add(await GetUserSubView(SpecialFolder.LiveTvNowPlaying, user, "0", parent).ConfigureAwait(false));
|
//list.Add(await GetUserSubView(SpecialFolder.LiveTvNowPlaying, user, "0", parent).ConfigureAwait(false));
|
||||||
list.Add(await GetUserView(SpecialFolder.LiveTvChannels, user, string.Empty, parent).ConfigureAwait(false));
|
list.Add(await GetUserView(SpecialFolder.LiveTvChannels, user, string.Empty, user.RootFolder).ConfigureAwait(false));
|
||||||
list.Add(await GetUserView(SpecialFolder.LiveTvRecordingGroups, user, string.Empty, parent).ConfigureAwait(false));
|
list.Add(await GetUserView(SpecialFolder.LiveTvRecordingGroups, user, string.Empty, user.RootFolder).ConfigureAwait(false));
|
||||||
|
|
||||||
return list;
|
return GetResult(list, queryParent, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<UserView> GetUserView(string name, string type, User user, string sortName, BaseItem parent)
|
private async Task<UserView> GetUserView(string name, string type, User user, string sortName, BaseItem parent)
|
||||||
|
|
|
@ -52,6 +52,10 @@
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\morelinq.1.1.0\lib\net35\MoreLinq.dll</HintPath>
|
<HintPath>..\packages\morelinq.1.1.0\lib\net35\MoreLinq.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Patterns.IO, Version=1.0.5580.36861, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\packages\Patterns.IO.1.0.0.3\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.IO.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
|
|
|
@ -9,10 +9,10 @@ namespace MediaBrowser.Controller.Sync
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the synced file information.
|
/// Gets the synced file information.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="remotePath">The remote path.</param>
|
/// <param name="id">The identifier.</param>
|
||||||
/// <param name="target">The target.</param>
|
/// <param name="target">The target.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>Task<SyncedFileInfo>.</returns>
|
/// <returns>Task<SyncedFileInfo>.</returns>
|
||||||
Task<SyncedFileInfo> GetSyncedFileInfo(string remotePath, SyncTarget target, CancellationToken cancellationToken);
|
Task<SyncedFileInfo> GetSyncedFileInfo(string id, SyncTarget target, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using MediaBrowser.Model.Sync;
|
using MediaBrowser.Model.Querying;
|
||||||
|
using MediaBrowser.Model.Sync;
|
||||||
|
using Patterns.IO;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -13,46 +14,39 @@ namespace MediaBrowser.Controller.Sync
|
||||||
/// Transfers the file.
|
/// Transfers the file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stream">The stream.</param>
|
/// <param name="stream">The stream.</param>
|
||||||
/// <param name="remotePath">The remote path.</param>
|
/// <param name="pathParts">The path parts.</param>
|
||||||
/// <param name="target">The target.</param>
|
/// <param name="target">The target.</param>
|
||||||
/// <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>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
Task<SyncedFileInfo> SendFile(Stream stream, string remotePath, SyncTarget target, IProgress<double> progress, CancellationToken cancellationToken);
|
Task<SyncedFileInfo> SendFile(Stream stream, string[] pathParts, SyncTarget target, IProgress<double> progress, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes the file.
|
/// Deletes the file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">The path.</param>
|
/// <param name="id">The identifier.</param>
|
||||||
/// <param name="target">The target.</param>
|
/// <param name="target">The target.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
Task DeleteFile(string path, SyncTarget target, CancellationToken cancellationToken);
|
Task DeleteFile(string id, SyncTarget target, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the file.
|
/// Gets the file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">The path.</param>
|
/// <param name="id">The identifier.</param>
|
||||||
/// <param name="target">The target.</param>
|
/// <param name="target">The target.</param>
|
||||||
/// <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>
|
||||||
/// <returns>Task<Stream>.</returns>
|
/// <returns>Task<Stream>.</returns>
|
||||||
Task<Stream> GetFile(string path, SyncTarget target, IProgress<double> progress, CancellationToken cancellationToken);
|
Task<Stream> GetFile(string id, SyncTarget target, IProgress<double> progress, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the full path.
|
/// Gets the files.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">The path.</param>
|
/// <param name="query">The query.</param>
|
||||||
/// <param name="target">The target.</param>
|
/// <param name="target">The target.</param>
|
||||||
/// <returns>System.String.</returns>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
string GetFullPath(IEnumerable<string> path, SyncTarget target);
|
/// <returns>Task<QueryResult<FileMetadata>>.</returns>
|
||||||
|
Task<QueryResult<FileMetadata>> GetFiles(FileQuery query, SyncTarget target, CancellationToken cancellationToken);
|
||||||
/// <summary>
|
|
||||||
/// Gets the parent directory path.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path">The path.</param>
|
|
||||||
/// <param name="target">The target.</param>
|
|
||||||
/// <returns>System.String.</returns>
|
|
||||||
string GetParentDirectoryPath(string path, SyncTarget target);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,20 +7,12 @@ namespace MediaBrowser.Controller.Sync
|
||||||
public interface ISyncDataProvider
|
public interface ISyncDataProvider
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the server item ids.
|
/// Gets the local items.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">The target.</param>
|
/// <param name="target">The target.</param>
|
||||||
/// <param name="serverId">The server identifier.</param>
|
/// <param name="serverId">The server identifier.</param>
|
||||||
/// <returns>Task<List<System.String>>.</returns>
|
/// <returns>Task<List<LocalItem>>.</returns>
|
||||||
Task<List<string>> GetServerItemIds(SyncTarget target, string serverId);
|
Task<List<LocalItem>> GetLocalItems(SyncTarget target, string serverId);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the synchronize job item ids.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="target">The target.</param>
|
|
||||||
/// <param name="serverId">The server identifier.</param>
|
|
||||||
/// <returns>Task<List<System.String>>.</returns>
|
|
||||||
Task<List<string>> GetSyncJobItemIds(SyncTarget target, string serverId);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the or update.
|
/// Adds the or update.
|
||||||
|
|
|
@ -20,6 +20,11 @@ namespace MediaBrowser.Controller.Sync
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The required HTTP headers.</value>
|
/// <value>The required HTTP headers.</value>
|
||||||
public Dictionary<string, string> RequiredHttpHeaders { get; set; }
|
public Dictionary<string, string> RequiredHttpHeaders { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the identifier.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The identifier.</value>
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
public SyncedFileInfo()
|
public SyncedFileInfo()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="morelinq" version="1.1.0" targetFramework="net45" />
|
<package id="morelinq" version="1.1.0" targetFramework="net45" />
|
||||||
|
<package id="Patterns.IO" version="1.0.0.3" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
|
@ -732,7 +732,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
|
|
||||||
if (enableForceKill)
|
if (enableForceKill)
|
||||||
{
|
{
|
||||||
process.Process .Kill();
|
process.Process.Kill();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -748,10 +748,14 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
{
|
{
|
||||||
proceses = _runningProcesses.ToList();
|
proceses = _runningProcesses.ToList();
|
||||||
}
|
}
|
||||||
|
_runningProcesses.Clear();
|
||||||
|
|
||||||
foreach (var process in proceses)
|
foreach (var process in proceses)
|
||||||
{
|
{
|
||||||
StopProcess(process, 500, true);
|
if (!process.HasExited)
|
||||||
|
{
|
||||||
|
StopProcess(process, 500, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,8 +805,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
lock (_mediaEncoder._runningProcesses)
|
lock (_mediaEncoder._runningProcesses)
|
||||||
{
|
{
|
||||||
_mediaEncoder._runningProcesses.Remove(this);
|
_mediaEncoder._runningProcesses.Remove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
process.Dispose();
|
process.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
public const string MusicGenres = "MusicGenres";
|
public const string MusicGenres = "MusicGenres";
|
||||||
public const string MusicGenre = "MusicGenre";
|
public const string MusicGenre = "MusicGenre";
|
||||||
public const string MusicLatest = "MusicLatest";
|
public const string MusicLatest = "MusicLatest";
|
||||||
|
public const string MusicPlaylists = "MusicPlaylists";
|
||||||
public const string MusicSongs = "MusicSongs";
|
public const string MusicSongs = "MusicSongs";
|
||||||
public const string MusicFavorites = "MusicFavorites";
|
public const string MusicFavorites = "MusicFavorites";
|
||||||
public const string MusicFavoriteArtists = "MusicFavoriteArtists";
|
public const string MusicFavoriteArtists = "MusicFavoriteArtists";
|
||||||
|
|
|
@ -21,6 +21,9 @@ namespace MediaBrowser.Model.Session
|
||||||
public DeviceProfile DeviceProfile { get; set; }
|
public DeviceProfile DeviceProfile { get; set; }
|
||||||
public List<string> SupportedLiveMediaTypes { get; set; }
|
public List<string> SupportedLiveMediaTypes { get; set; }
|
||||||
|
|
||||||
|
public string AppUrl { get; set; }
|
||||||
|
public string AppImageUrl { get; set; }
|
||||||
|
|
||||||
public ClientCapabilities()
|
public ClientCapabilities()
|
||||||
{
|
{
|
||||||
PlayableMediaTypes = new List<string>();
|
PlayableMediaTypes = new List<string>();
|
||||||
|
|
|
@ -26,6 +26,11 @@ namespace MediaBrowser.Model.Sync
|
||||||
/// <value>The unique identifier.</value>
|
/// <value>The unique identifier.</value>
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Gets or sets the file identifier.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The file identifier.</value>
|
||||||
|
public string FileId { get; set; }
|
||||||
|
/// <summary>
|
||||||
/// Gets or sets the item identifier.
|
/// Gets or sets the item identifier.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The item identifier.</value>
|
/// <value>The item identifier.</value>
|
||||||
|
|
|
@ -964,6 +964,7 @@
|
||||||
"ViewTypeMovieFavorites": "Favorites",
|
"ViewTypeMovieFavorites": "Favorites",
|
||||||
"ViewTypeMovieGenres": "Genres",
|
"ViewTypeMovieGenres": "Genres",
|
||||||
"ViewTypeMusicLatest": "Latest",
|
"ViewTypeMusicLatest": "Latest",
|
||||||
|
"ViewTypeMusicPlaylists": "Playlists",
|
||||||
"ViewTypeMusicAlbums": "Albums",
|
"ViewTypeMusicAlbums": "Albums",
|
||||||
"ViewTypeMusicAlbumArtists": "Album Artists",
|
"ViewTypeMusicAlbumArtists": "Album Artists",
|
||||||
"HeaderOtherDisplaySettings": "Display Settings",
|
"HeaderOtherDisplaySettings": "Display Settings",
|
||||||
|
|
|
@ -57,6 +57,10 @@
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\morelinq.1.1.0\lib\net35\MoreLinq.dll</HintPath>
|
<HintPath>..\packages\morelinq.1.1.0\lib\net35\MoreLinq.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Patterns.IO, Version=1.0.5580.36861, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\packages\Patterns.IO.1.0.0.3\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.IO.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Patterns.Logging">
|
<Reference Include="Patterns.Logging">
|
||||||
<HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>
|
<HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System.Globalization;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Configuration;
|
|
||||||
using MediaBrowser.Common.IO;
|
using MediaBrowser.Common.IO;
|
||||||
using MediaBrowser.Common.Progress;
|
using MediaBrowser.Common.Progress;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
|
@ -12,12 +11,14 @@ using MediaBrowser.Model.MediaInfo;
|
||||||
using MediaBrowser.Model.Sync;
|
using MediaBrowser.Model.Sync;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Patterns.IO;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.Sync
|
namespace MediaBrowser.Server.Implementations.Sync
|
||||||
{
|
{
|
||||||
|
@ -29,6 +30,9 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly IConfigurationManager _config;
|
private readonly IConfigurationManager _config;
|
||||||
|
|
||||||
|
public const string PathSeparatorString = "/";
|
||||||
|
public const char PathSeparatorChar = '/';
|
||||||
|
|
||||||
public MediaSync(ILogger logger, ISyncManager syncManager, IServerApplicationHost appHost, IFileSystem fileSystem, IConfigurationManager config)
|
public MediaSync(ILogger logger, ISyncManager syncManager, IServerApplicationHost appHost, IFileSystem fileSystem, IConfigurationManager config)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
@ -71,7 +75,24 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
SyncTarget target,
|
SyncTarget target,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var jobItemIds = await dataProvider.GetSyncJobItemIds(target, serverId).ConfigureAwait(false);
|
var localItems = await dataProvider.GetLocalItems(target, serverId).ConfigureAwait(false);
|
||||||
|
var remoteFiles = await provider.GetFiles(new FileQuery(), target, cancellationToken).ConfigureAwait(false);
|
||||||
|
var remoteIds = remoteFiles.Items.Select(i => i.Id).ToList();
|
||||||
|
|
||||||
|
var jobItemIds = new List<string>();
|
||||||
|
|
||||||
|
foreach (var localItem in localItems)
|
||||||
|
{
|
||||||
|
// TODO: Remove this after a while
|
||||||
|
if (string.IsNullOrWhiteSpace(localItem.FileId))
|
||||||
|
{
|
||||||
|
jobItemIds.Add(localItem.SyncJobItemId);
|
||||||
|
}
|
||||||
|
else if (remoteIds.Contains(localItem.FileId, StringComparer.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
jobItemIds.Add(localItem.SyncJobItemId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var result = await _syncManager.SyncData(new SyncDataRequest
|
var result = await _syncManager.SyncData(new SyncDataRequest
|
||||||
{
|
{
|
||||||
|
@ -163,7 +184,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
var fileTransferProgress = new ActionableProgress<double>();
|
var fileTransferProgress = new ActionableProgress<double>();
|
||||||
fileTransferProgress.RegisterAction(pct => progress.Report(pct * .92));
|
fileTransferProgress.RegisterAction(pct => progress.Report(pct * .92));
|
||||||
|
|
||||||
var sendFileResult = await SendFile(provider, internalSyncJobItem.OutputPath, localItem.LocalPath, target, options, fileTransferProgress, cancellationToken).ConfigureAwait(false);
|
var sendFileResult = await SendFile(provider, internalSyncJobItem.OutputPath, localItem.LocalPath.Split(PathSeparatorChar), target, options, fileTransferProgress, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
if (localItem.Item.MediaSources != null)
|
if (localItem.Item.MediaSources != null)
|
||||||
{
|
{
|
||||||
|
@ -177,6 +198,8 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
localItem.FileId = sendFileResult.Id;
|
||||||
|
|
||||||
// Create db record
|
// Create db record
|
||||||
await dataProvider.AddOrUpdate(target, localItem).ConfigureAwait(false);
|
await dataProvider.AddOrUpdate(target, localItem).ConfigureAwait(false);
|
||||||
|
|
||||||
|
@ -228,10 +251,10 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
var sendFileResult = await SendFile(provider, mediaStream.Path, remotePath, target, options, new Progress<double>(), cancellationToken).ConfigureAwait(false);
|
var sendFileResult = await SendFile(provider, mediaStream.Path, remotePath, target, options, new Progress<double>(), cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
// This is the path that will be used when talking to the provider
|
// This is the path that will be used when talking to the provider
|
||||||
mediaStream.ExternalId = remotePath;
|
mediaStream.ExternalId = sendFileResult.Id;
|
||||||
|
|
||||||
// Keep track of all additional files for cleanup later.
|
// Keep track of all additional files for cleanup later.
|
||||||
localItem.AdditionalFiles.Add(remotePath);
|
localItem.AdditionalFiles.Add(sendFileResult.Id);
|
||||||
|
|
||||||
// This is the public path clients will use
|
// This is the public path clients will use
|
||||||
mediaStream.Path = sendFileResult.Path;
|
mediaStream.Path = sendFileResult.Path;
|
||||||
|
@ -256,17 +279,15 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetRemoteSubtitlePath(LocalItem item, MediaStream stream, IServerSyncProvider provider, SyncTarget target)
|
private string[] GetRemoteSubtitlePath(LocalItem item, MediaStream stream, IServerSyncProvider provider, SyncTarget target)
|
||||||
{
|
{
|
||||||
var path = item.LocalPath;
|
|
||||||
|
|
||||||
var filename = GetSubtitleSaveFileName(item, stream.Language, stream.IsForced) + "." + stream.Codec.ToLower();
|
var filename = GetSubtitleSaveFileName(item, stream.Language, stream.IsForced) + "." + stream.Codec.ToLower();
|
||||||
|
|
||||||
var parentPath = provider.GetParentDirectoryPath(path, target);
|
var pathParts = item.LocalPath.Split(PathSeparatorChar);
|
||||||
|
var list = pathParts.Take(pathParts.Length - 1).ToList();
|
||||||
|
list.Add(filename);
|
||||||
|
|
||||||
path = Path.Combine(parentPath, filename);
|
return list.ToArray();
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetSubtitleSaveFileName(LocalItem item, string language, bool isForced)
|
private string GetSubtitleSaveFileName(LocalItem item, string language, bool isForced)
|
||||||
|
@ -300,12 +321,16 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
foreach (var localItem in localItems)
|
foreach (var localItem in localItems)
|
||||||
{
|
{
|
||||||
var files = localItem.AdditionalFiles.ToList();
|
var files = localItem.AdditionalFiles.ToList();
|
||||||
files.Insert(0, localItem.LocalPath);
|
|
||||||
|
// TODO: Remove this. Have to check it for now since this is a new property
|
||||||
|
if (!string.IsNullOrWhiteSpace(localItem.FileId))
|
||||||
|
{
|
||||||
|
files.Insert(0, localItem.FileId);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var file in files)
|
foreach (var file in files)
|
||||||
{
|
{
|
||||||
_logger.Debug("Removing {0} from {1}.", file, target.Name);
|
_logger.Debug("Removing {0} from {1}.", file, target.Name);
|
||||||
|
|
||||||
await provider.DeleteFile(file, target, cancellationToken).ConfigureAwait(false);
|
await provider.DeleteFile(file, target, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,9 +338,9 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<SyncedFileInfo> SendFile(IServerSyncProvider provider, string inputPath, string remotePath, SyncTarget target, SyncOptions options, IProgress<double> progress, CancellationToken cancellationToken)
|
private async Task<SyncedFileInfo> SendFile(IServerSyncProvider provider, string inputPath, string[] pathParts, SyncTarget target, SyncOptions options, IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_logger.Debug("Sending {0} to {1}. Remote path: {2}", inputPath, provider.Name, remotePath);
|
_logger.Debug("Sending {0} to {1}. Remote path: {2}", inputPath, provider.Name, string.Join("/", pathParts));
|
||||||
using (var fileStream = _fileSystem.GetFileStream(inputPath, FileMode.Open, FileAccess.Read, FileShare.Read, true))
|
using (var fileStream = _fileSystem.GetFileStream(inputPath, FileMode.Open, FileAccess.Read, FileShare.Read, true))
|
||||||
{
|
{
|
||||||
Stream stream = fileStream;
|
Stream stream = fileStream;
|
||||||
|
@ -325,7 +350,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
stream = new ThrottledStream(stream, options.UploadSpeedLimitBytes);
|
stream = new ThrottledStream(stream, options.UploadSpeedLimitBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return await provider.SendFile(stream, remotePath, target, progress, cancellationToken).ConfigureAwait(false);
|
return await provider.SendFile(stream, pathParts, target, progress, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,7 +374,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
var path = GetDirectoryPath(provider, job, syncedItem, libraryItem, serverName);
|
var path = GetDirectoryPath(provider, job, syncedItem, libraryItem, serverName);
|
||||||
path.Add(GetLocalFileName(provider, libraryItem, originalFileName));
|
path.Add(GetLocalFileName(provider, libraryItem, originalFileName));
|
||||||
|
|
||||||
var localPath = provider.GetFullPath(path, target);
|
var localPath = string.Join(PathSeparatorString, path.ToArray());
|
||||||
|
|
||||||
foreach (var mediaSource in libraryItem.MediaSources)
|
foreach (var mediaSource in libraryItem.MediaSources)
|
||||||
{
|
{
|
||||||
|
|
|
@ -793,8 +793,6 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Debug("Setting status to Queued for {0} because it is no longer on the device.", jobItem.ItemId);
|
|
||||||
|
|
||||||
// Content is no longer on the device
|
// Content is no longer on the device
|
||||||
if (jobItem.IsMarkedForRemoval)
|
if (jobItem.IsMarkedForRemoval)
|
||||||
{
|
{
|
||||||
|
@ -802,6 +800,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
_logger.Debug("Setting status to Queued for {0} because it is no longer on the device.", jobItem.ItemId);
|
||||||
jobItem.Status = SyncJobItemStatus.Queued;
|
jobItem.Status = SyncJobItemStatus.Queued;
|
||||||
}
|
}
|
||||||
requiresSaving = true;
|
requiresSaving = true;
|
||||||
|
@ -902,8 +901,6 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Debug("Setting status to Queued for {0} because it is no longer on the device.", jobItem.Id);
|
|
||||||
|
|
||||||
// Content is no longer on the device
|
// Content is no longer on the device
|
||||||
if (jobItem.IsMarkedForRemoval)
|
if (jobItem.IsMarkedForRemoval)
|
||||||
{
|
{
|
||||||
|
@ -911,6 +908,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
_logger.Debug("Setting status to Queued for {0} because it is no longer on the device.", jobItem.Id);
|
||||||
jobItem.Status = SyncJobItemStatus.Queued;
|
jobItem.Status = SyncJobItemStatus.Queued;
|
||||||
}
|
}
|
||||||
requiresSaving = true;
|
requiresSaving = true;
|
||||||
|
|
|
@ -109,8 +109,13 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
var dataProvider = _syncManager.GetDataProvider(provider, target);
|
var dataProvider = _syncManager.GetDataProvider(provider, target);
|
||||||
var localItem = await dataProvider.Get(target, openKeys[2]).ConfigureAwait(false);
|
var localItem = await dataProvider.Get(target, openKeys[2]).ConfigureAwait(false);
|
||||||
|
|
||||||
|
var fileId = localItem.FileId;
|
||||||
|
if (string.IsNullOrWhiteSpace(fileId))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
var requiresDynamicAccess = (IHasDynamicAccess)provider;
|
var requiresDynamicAccess = (IHasDynamicAccess)provider;
|
||||||
var dynamicInfo = await requiresDynamicAccess.GetSyncedFileInfo(localItem.LocalPath, target, cancellationToken).ConfigureAwait(false);
|
var dynamicInfo = await requiresDynamicAccess.GetSyncedFileInfo(fileId, target, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
var mediaSource = localItem.Item.MediaSources.First();
|
var mediaSource = localItem.Item.MediaSources.First();
|
||||||
mediaSource.LiveStreamId = Guid.NewGuid().ToString();
|
mediaSource.LiveStreamId = Guid.NewGuid().ToString();
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Extensions;
|
|
||||||
using MediaBrowser.Common.IO;
|
using MediaBrowser.Common.IO;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Sync;
|
using MediaBrowser.Controller.Sync;
|
||||||
|
@ -12,6 +11,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 Patterns.IO;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.Sync
|
namespace MediaBrowser.Server.Implementations.Sync
|
||||||
{
|
{
|
||||||
|
@ -29,8 +29,6 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
private readonly IApplicationPaths _appPaths;
|
private readonly IApplicationPaths _appPaths;
|
||||||
private readonly IServerApplicationHost _appHost;
|
private readonly IServerApplicationHost _appHost;
|
||||||
|
|
||||||
private readonly SemaphoreSlim _cacheFileLock = new SemaphoreSlim(1, 1);
|
|
||||||
|
|
||||||
public TargetDataProvider(IServerSyncProvider provider, SyncTarget target, IServerApplicationHost appHost, ILogger logger, IJsonSerializer json, IFileSystem fileSystem, IApplicationPaths appPaths)
|
public TargetDataProvider(IServerSyncProvider provider, SyncTarget target, IServerApplicationHost appHost, ILogger logger, IJsonSerializer json, IFileSystem fileSystem, IApplicationPaths appPaths)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
@ -42,7 +40,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
_appHost = appHost;
|
_appHost = appHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetRemotePath()
|
private string[] GetRemotePath()
|
||||||
{
|
{
|
||||||
var parts = new List<string>
|
var parts = new List<string>
|
||||||
{
|
{
|
||||||
|
@ -52,7 +50,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
|
|
||||||
parts = parts.Select(i => GetValidFilename(_provider, i)).ToList();
|
parts = parts.Select(i => GetValidFilename(_provider, i)).ToList();
|
||||||
|
|
||||||
return _provider.GetFullPath(parts, _target);
|
return parts.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetValidFilename(IServerSyncProvider provider, string filename)
|
private string GetValidFilename(IServerSyncProvider provider, string filename)
|
||||||
|
@ -65,22 +63,22 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
{
|
{
|
||||||
if (_items == null)
|
if (_items == null)
|
||||||
{
|
{
|
||||||
try
|
_logger.Debug("Getting {0} from {1}", string.Join(MediaSync.PathSeparatorString, GetRemotePath().ToArray()), _provider.Name);
|
||||||
|
|
||||||
|
var fileResult = await _provider.GetFiles(new FileQuery
|
||||||
{
|
{
|
||||||
var path = GetRemotePath();
|
FullPath = GetRemotePath().ToArray()
|
||||||
|
|
||||||
_logger.Debug("Getting {0} from {1}", path, _provider.Name);
|
}, _target, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
using (var stream = await _provider.GetFile(path, _target, new Progress<double>(), cancellationToken))
|
if (fileResult.Items.Length > 0)
|
||||||
|
{
|
||||||
|
using (var stream = await _provider.GetFile(fileResult.Items[0].Id, _target, new Progress<double>(), cancellationToken))
|
||||||
{
|
{
|
||||||
_items = _json.DeserializeFromStream<List<LocalItem>>(stream);
|
_items = _json.DeserializeFromStream<List<LocalItem>>(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException)
|
else
|
||||||
{
|
|
||||||
_items = new List<LocalItem>();
|
|
||||||
}
|
|
||||||
catch (DirectoryNotFoundException)
|
|
||||||
{
|
{
|
||||||
_items = new List<LocalItem>();
|
_items = new List<LocalItem>();
|
||||||
}
|
}
|
||||||
|
@ -133,14 +131,9 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<List<string>> GetServerItemIds(SyncTarget target, string serverId)
|
public Task<List<LocalItem>> GetLocalItems(SyncTarget target, string serverId)
|
||||||
{
|
{
|
||||||
return GetData(items => items.Where(i => string.Equals(i.ServerId, serverId, StringComparison.OrdinalIgnoreCase)).Select(i => i.ItemId).ToList());
|
return GetData(items => items.Where(i => string.Equals(i.ServerId, serverId, StringComparison.OrdinalIgnoreCase)).ToList());
|
||||||
}
|
|
||||||
|
|
||||||
public Task<List<string>> GetSyncJobItemIds(SyncTarget target, string serverId)
|
|
||||||
{
|
|
||||||
return GetData(items => items.Where(i => string.Equals(i.ServerId, serverId, StringComparison.OrdinalIgnoreCase)).Select(i => i.SyncJobItemId).Where(i => !string.IsNullOrWhiteSpace(i)).ToList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task AddOrUpdate(SyncTarget target, LocalItem item)
|
public Task AddOrUpdate(SyncTarget target, LocalItem item)
|
||||||
|
|
|
@ -203,6 +203,7 @@ namespace MediaBrowser.Server.Implementations.UserViews
|
||||||
SpecialFolder.MusicGenres,
|
SpecialFolder.MusicGenres,
|
||||||
SpecialFolder.MusicGenre,
|
SpecialFolder.MusicGenre,
|
||||||
SpecialFolder.MusicLatest,
|
SpecialFolder.MusicLatest,
|
||||||
|
SpecialFolder.MusicPlaylists,
|
||||||
SpecialFolder.MusicSongs,
|
SpecialFolder.MusicSongs,
|
||||||
SpecialFolder.MusicFavorites,
|
SpecialFolder.MusicFavorites,
|
||||||
SpecialFolder.MusicFavoriteArtists,
|
SpecialFolder.MusicFavoriteArtists,
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
<package id="MediaBrowser.Naming" version="1.0.0.32" targetFramework="net45" />
|
<package id="MediaBrowser.Naming" version="1.0.0.32" targetFramework="net45" />
|
||||||
<package id="Mono.Nat" version="1.2.23.0" targetFramework="net45" />
|
<package id="Mono.Nat" version="1.2.23.0" targetFramework="net45" />
|
||||||
<package id="morelinq" version="1.1.0" targetFramework="net45" />
|
<package id="morelinq" version="1.1.0" targetFramework="net45" />
|
||||||
|
<package id="Patterns.IO" version="1.0.0.3" targetFramework="net45" />
|
||||||
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
||||||
<package id="SocketHttpListener" version="1.0.0.3" targetFramework="net45" />
|
<package id="SocketHttpListener" version="1.0.0.3" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
|
@ -2,7 +2,7 @@
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MediaBrowser.Common.Internal</id>
|
<id>MediaBrowser.Common.Internal</id>
|
||||||
<version>3.0.616</version>
|
<version>3.0.619</version>
|
||||||
<title>MediaBrowser.Common.Internal</title>
|
<title>MediaBrowser.Common.Internal</title>
|
||||||
<authors>Luke</authors>
|
<authors>Luke</authors>
|
||||||
<owners>ebr,Luke,scottisafool</owners>
|
<owners>ebr,Luke,scottisafool</owners>
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
<description>Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption.</description>
|
<description>Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption.</description>
|
||||||
<copyright>Copyright © Emby 2013</copyright>
|
<copyright>Copyright © Emby 2013</copyright>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency id="MediaBrowser.Common" version="3.0.616" />
|
<dependency id="MediaBrowser.Common" version="3.0.619" />
|
||||||
<dependency id="NLog" version="3.2.0.0" />
|
<dependency id="NLog" version="3.2.0.0" />
|
||||||
<dependency id="SimpleInjector" version="2.7.0" />
|
<dependency id="SimpleInjector" version="2.7.0" />
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MediaBrowser.Common</id>
|
<id>MediaBrowser.Common</id>
|
||||||
<version>3.0.616</version>
|
<version>3.0.619</version>
|
||||||
<title>MediaBrowser.Common</title>
|
<title>MediaBrowser.Common</title>
|
||||||
<authors>Emby Team</authors>
|
<authors>Emby Team</authors>
|
||||||
<owners>ebr,Luke,scottisafool</owners>
|
<owners>ebr,Luke,scottisafool</owners>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MediaBrowser.Model.Signed</id>
|
<id>MediaBrowser.Model.Signed</id>
|
||||||
<version>3.0.616</version>
|
<version>3.0.619</version>
|
||||||
<title>MediaBrowser.Model - Signed Edition</title>
|
<title>MediaBrowser.Model - Signed Edition</title>
|
||||||
<authors>Emby Team</authors>
|
<authors>Emby Team</authors>
|
||||||
<owners>ebr,Luke,scottisafool</owners>
|
<owners>ebr,Luke,scottisafool</owners>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MediaBrowser.Server.Core</id>
|
<id>MediaBrowser.Server.Core</id>
|
||||||
<version>3.0.616</version>
|
<version>3.0.619</version>
|
||||||
<title>Media Browser.Server.Core</title>
|
<title>Media Browser.Server.Core</title>
|
||||||
<authors>Emby Team</authors>
|
<authors>Emby Team</authors>
|
||||||
<owners>ebr,Luke,scottisafool</owners>
|
<owners>ebr,Luke,scottisafool</owners>
|
||||||
|
@ -12,7 +12,8 @@
|
||||||
<description>Contains core components required to build plugins for Emby Server.</description>
|
<description>Contains core components required to build plugins for Emby Server.</description>
|
||||||
<copyright>Copyright © Emby 2013</copyright>
|
<copyright>Copyright © Emby 2013</copyright>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency id="MediaBrowser.Common" version="3.0.616" />
|
<dependency id="MediaBrowser.Common" version="3.0.619" />
|
||||||
|
<dependency id="Patterns.IO" version="1.0.0.3" />
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user