mirror of https://github.com/jellyfin/jellyfin.git
separate display preferences per client
This commit is contained in:
parent
90077dd216
commit
2b07e6aaf8
|
@ -21,6 +21,12 @@ namespace MediaBrowser.Api
|
|||
/// <value>The id.</value>
|
||||
[ApiMember(Name = "DisplayPreferencesId", Description = "DisplayPreferences Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
|
||||
public Guid DisplayPreferencesId { get; set; }
|
||||
|
||||
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||
public Guid UserId { get; set; }
|
||||
|
||||
[ApiMember(Name = "Client", Description = "Client", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||
public string Client { get; set; }
|
||||
}
|
||||
|
||||
[Route("/DisplayPreferences/{Id}", "GET")]
|
||||
|
@ -33,6 +39,12 @@ namespace MediaBrowser.Api
|
|||
/// <value>The id.</value>
|
||||
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public Guid UserId { get; set; }
|
||||
|
||||
[ApiMember(Name = "Client", Description = "Client", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string Client { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -66,7 +78,7 @@ namespace MediaBrowser.Api
|
|||
/// <param name="request">The request.</param>
|
||||
public object Get(GetDisplayPreferences request)
|
||||
{
|
||||
var result = _displayPreferencesManager.GetDisplayPreferences(request.Id);
|
||||
var result = _displayPreferencesManager.GetDisplayPreferences(request.Id, request.UserId, request.Client);
|
||||
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
@ -80,7 +92,7 @@ namespace MediaBrowser.Api
|
|||
// Serialize to json and then back so that the core doesn't see the request dto type
|
||||
var displayPreferences = _jsonSerializer.DeserializeFromString<DisplayPreferences>(_jsonSerializer.SerializeToString(request));
|
||||
|
||||
var task = _displayPreferencesManager.SaveDisplayPreferences(displayPreferences, CancellationToken.None);
|
||||
var task = _displayPreferencesManager.SaveDisplayPreferences(displayPreferences, request.UserId, request.Client, CancellationToken.None);
|
||||
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// Allow different display preferences for each collection folder
|
||||
/// </summary>
|
||||
/// <value>The display prefs id.</value>
|
||||
protected override Guid DisplayPreferencesId
|
||||
public override Guid DisplayPreferencesId
|
||||
{
|
||||
get
|
||||
{
|
||||
|
|
|
@ -72,7 +72,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// </summary>
|
||||
/// <value>The display prefs id.</value>
|
||||
[IgnoreDataMember]
|
||||
protected virtual Guid DisplayPreferencesId
|
||||
public virtual Guid DisplayPreferencesId
|
||||
{
|
||||
get
|
||||
{
|
||||
|
|
|
@ -20,16 +20,20 @@ namespace MediaBrowser.Controller.Persistence
|
|||
/// Saves display preferences for an item
|
||||
/// </summary>
|
||||
/// <param name="displayPreferences">The display preferences.</param>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="client">The client.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task SaveDisplayPreferences(DisplayPreferences displayPreferences,
|
||||
Task SaveDisplayPreferences(DisplayPreferences displayPreferences, Guid userId, string client,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display preferences.
|
||||
/// </summary>
|
||||
/// <param name="displayPreferencesId">The display preferences id.</param>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="client">The client.</param>
|
||||
/// <returns>Task{DisplayPreferences}.</returns>
|
||||
DisplayPreferences GetDisplayPreferences(Guid displayPreferencesId);
|
||||
DisplayPreferences GetDisplayPreferences(Guid displayPreferencesId, Guid userId, string client);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -477,8 +477,10 @@ namespace MediaBrowser.Model.ApiClient
|
|||
/// Gets the display preferences.
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="client">The client.</param>
|
||||
/// <returns>Task{BaseItemDto}.</returns>
|
||||
Task<DisplayPreferences> GetDisplayPreferencesAsync(string id);
|
||||
Task<DisplayPreferences> GetDisplayPreferencesAsync(string id, string userId, string client);
|
||||
|
||||
/// <summary>
|
||||
/// Updates display preferences for a user
|
||||
|
@ -487,7 +489,7 @@ namespace MediaBrowser.Model.ApiClient
|
|||
/// <param name="displayPreferences">The display preferences.</param>
|
||||
/// <returns>Task{DisplayPreferences}.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">userId</exception>
|
||||
Task UpdateDisplayPreferencesAsync(DisplayPreferences displayPreferences);
|
||||
Task UpdateDisplayPreferencesAsync(DisplayPreferences displayPreferences, string userId, string client);
|
||||
|
||||
/// <summary>
|
||||
/// Posts a set of data to a url, and deserializes the return stream into T
|
||||
|
|
|
@ -82,11 +82,13 @@
|
|||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data.SQLite">
|
||||
<HintPath>..\packages\System.Data.SQLite.x86.1.0.86.0\lib\net45\System.Data.SQLite.dll</HintPath>
|
||||
<Reference Include="System.Data.SQLite, Version=1.0.87.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\System.Data.SQLite.x86.1.0.87.0\lib\net45\System.Data.SQLite.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.SQLite.Linq">
|
||||
<HintPath>..\packages\System.Data.SQLite.x86.1.0.86.0\lib\net45\System.Data.SQLite.Linq.dll</HintPath>
|
||||
<Reference Include="System.Data.SQLite.Linq, Version=1.0.87.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\System.Data.SQLite.x86.1.0.87.0\lib\net45\System.Data.SQLite.Linq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reactive.Core">
|
||||
<HintPath>..\packages\Rx-Core.2.1.30214.0\lib\Net45\System.Reactive.Core.dll</HintPath>
|
||||
|
|
|
@ -85,9 +85,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
|
||||
string[] queries = {
|
||||
|
||||
"create table if not exists displaypreferences (id GUID, data BLOB)",
|
||||
"create unique index if not exists displaypreferencesindex on displaypreferences (id)",
|
||||
"create table if not exists schema_version (table_name primary key, version)",
|
||||
"create table if not exists userdisplaypreferences (id GUID, userId GUID, client text, data BLOB)",
|
||||
"create unique index if not exists userdisplaypreferencesindex on userdisplaypreferences (id, userId, client)",
|
||||
//pragmas
|
||||
"pragma temp_store = memory"
|
||||
};
|
||||
|
@ -99,10 +98,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
/// Save the display preferences associated with an item in the repo
|
||||
/// </summary>
|
||||
/// <param name="displayPreferences">The display preferences.</param>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="client">The client.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">item</exception>
|
||||
public async Task SaveDisplayPreferences(DisplayPreferences displayPreferences, CancellationToken cancellationToken)
|
||||
public async Task SaveDisplayPreferences(DisplayPreferences displayPreferences, Guid userId, string client, CancellationToken cancellationToken)
|
||||
{
|
||||
if (displayPreferences == null)
|
||||
{
|
||||
|
@ -131,9 +132,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
|
||||
using (var cmd = _connection.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "replace into displaypreferences (id, data) values (@1, @2)";
|
||||
cmd.CommandText = "replace into userdisplaypreferences (id, userid, client, data) values (@1, @2, @3, @4)";
|
||||
cmd.AddParam("@1", displayPreferences.Id);
|
||||
cmd.AddParam("@2", serialized);
|
||||
cmd.AddParam("@2", userId);
|
||||
cmd.AddParam("@3", client);
|
||||
cmd.AddParam("@4", serialized);
|
||||
|
||||
cmd.Transaction = transaction;
|
||||
|
||||
|
@ -177,9 +180,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
/// Gets the display preferences.
|
||||
/// </summary>
|
||||
/// <param name="displayPreferencesId">The display preferences id.</param>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="client">The client.</param>
|
||||
/// <returns>Task{DisplayPreferences}.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">item</exception>
|
||||
public DisplayPreferences GetDisplayPreferences(Guid displayPreferencesId)
|
||||
public DisplayPreferences GetDisplayPreferences(Guid displayPreferencesId, Guid userId, string client)
|
||||
{
|
||||
if (displayPreferencesId == Guid.Empty)
|
||||
{
|
||||
|
@ -187,11 +192,17 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
}
|
||||
|
||||
var cmd = _connection.CreateCommand();
|
||||
cmd.CommandText = "select data from displaypreferences where id = @id";
|
||||
cmd.CommandText = "select data from userdisplaypreferences where id = @id and userId=@userId and client=@client";
|
||||
|
||||
var idParam = cmd.Parameters.Add("@id", DbType.Guid);
|
||||
idParam.Value = displayPreferencesId;
|
||||
|
||||
var userIdParam = cmd.Parameters.Add("@userId", DbType.Guid);
|
||||
userIdParam.Value = userId;
|
||||
|
||||
var clientParam = cmd.Parameters.Add("@client", DbType.String);
|
||||
clientParam.Value = client;
|
||||
|
||||
using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow))
|
||||
{
|
||||
if (reader.Read())
|
||||
|
|
|
@ -14,5 +14,5 @@
|
|||
<package id="ServiceStack.Redis" version="3.9.43" targetFramework="net45" />
|
||||
<package id="ServiceStack.Text" version="3.9.55" targetFramework="net45" />
|
||||
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
|
||||
<package id="System.Data.SQLite.x86" version="1.0.86.0" targetFramework="net45" />
|
||||
<package id="System.Data.SQLite.x86" version="1.0.87.0" targetFramework="net45" />
|
||||
</packages>
|
|
@ -61,7 +61,7 @@ namespace MediaBrowser.ServerApplication
|
|||
lblVersion.Content = "Version: " + appHost.ApplicationVersion;
|
||||
foreach (var user in userManager.Users)
|
||||
ddlProfile.Items.Add(user);
|
||||
ddlProfile.Items.Insert(0,new User {Name = "Physical"});
|
||||
ddlProfile.Items.Insert(0, new User { Name = "Physical" });
|
||||
ddlProfile.SelectedIndex = 0;
|
||||
ddlIndexBy.Visibility = ddlSortBy.Visibility = lblIndexBy.Visibility = lblSortBy.Visibility = Visibility.Hidden;
|
||||
|
||||
|
@ -94,22 +94,22 @@ namespace MediaBrowser.ServerApplication
|
|||
children = OrderByName(children, CurrentUser);
|
||||
|
||||
foreach (Folder folder in children)
|
||||
{
|
||||
{
|
||||
|
||||
var currentFolder = folder;
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
var prefs = ddlProfile.SelectedItem != null ? _displayPreferencesManager.GetDisplayPreferences(currentFolder.GetDisplayPreferencesId((ddlProfile.SelectedItem as User).Id)) ?? new DisplayPreferences { SortBy = ItemSortBy.SortName } : new DisplayPreferences { SortBy = ItemSortBy.SortName };
|
||||
var node = new TreeViewItem { Tag = currentFolder };
|
||||
var currentFolder = folder;
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
var prefs = ddlProfile.SelectedItem != null ? _displayPreferencesManager.GetDisplayPreferences(currentFolder.GetDisplayPreferencesId((ddlProfile.SelectedItem as User).Id), (ddlProfile.SelectedItem as User).Id, "LibraryExplorer") ?? new DisplayPreferences { SortBy = ItemSortBy.SortName } : new DisplayPreferences { SortBy = ItemSortBy.SortName };
|
||||
var node = new TreeViewItem { Tag = currentFolder };
|
||||
|
||||
var subChildren = currentFolder.GetChildren(CurrentUser, true, prefs.IndexBy);
|
||||
subChildren = OrderByName(subChildren, CurrentUser);
|
||||
AddChildren(node, subChildren, CurrentUser);
|
||||
node.Header = currentFolder.Name + " (" +
|
||||
node.Items.Count + ")";
|
||||
tvwLibrary.Items.Add(node);
|
||||
}, CancellationToken.None, TaskCreationOptions.None, ui);
|
||||
}
|
||||
var subChildren = currentFolder.GetChildren(CurrentUser, true, prefs.IndexBy);
|
||||
subChildren = OrderByName(subChildren, CurrentUser);
|
||||
AddChildren(node, subChildren, CurrentUser);
|
||||
node.Header = currentFolder.Name + " (" +
|
||||
node.Items.Count + ")";
|
||||
tvwLibrary.Items.Add(node);
|
||||
}, CancellationToken.None, TaskCreationOptions.None, ui);
|
||||
}
|
||||
});
|
||||
lblLoading.Visibility = Visibility.Hidden;
|
||||
Cursor = Cursors.Arrow;
|
||||
|
@ -148,11 +148,11 @@ namespace MediaBrowser.ServerApplication
|
|||
{
|
||||
foreach (var item in children)
|
||||
{
|
||||
var node = new TreeViewItem { Tag = item };
|
||||
var node = new TreeViewItem { Tag = item };
|
||||
var subFolder = item as Folder;
|
||||
if (subFolder != null)
|
||||
{
|
||||
var prefs = _displayPreferencesManager.GetDisplayPreferences(subFolder.GetDisplayPreferencesId(user.Id));
|
||||
var prefs = _displayPreferencesManager.GetDisplayPreferences(subFolder.GetDisplayPreferencesId(user.Id), user.Id, "LibraryExplorer");
|
||||
|
||||
AddChildren(node, OrderBy(subFolder.GetChildren(user, true), user, prefs.SortBy), user);
|
||||
node.Header = item.Name + " (" + node.Items.Count + ")";
|
||||
|
@ -185,7 +185,7 @@ namespace MediaBrowser.ServerApplication
|
|||
lblIndexBy.Visibility = ddlIndexBy.Visibility = ddlSortBy.Visibility = lblSortBy.Visibility = Visibility.Visible;
|
||||
ddlIndexBy.ItemsSource = folder.IndexByOptionStrings;
|
||||
|
||||
ddlSortBy.ItemsSource = new []
|
||||
ddlSortBy.ItemsSource = new[]
|
||||
{
|
||||
ItemSortBy.SortName,
|
||||
ItemSortBy.Album,
|
||||
|
@ -200,7 +200,7 @@ namespace MediaBrowser.ServerApplication
|
|||
ItemSortBy.Runtime
|
||||
};
|
||||
|
||||
var prefs = _displayPreferencesManager.GetDisplayPreferences(folder.GetDisplayPreferencesId((ddlProfile.SelectedItem as User).Id));
|
||||
var prefs = _displayPreferencesManager.GetDisplayPreferences(folder.GetDisplayPreferencesId((ddlProfile.SelectedItem as User).Id), (ddlProfile.SelectedItem as User).Id, "LibraryExplorer");
|
||||
|
||||
ddlIndexBy.SelectedItem = prefs != null
|
||||
? prefs.IndexBy ?? LocalizedStrings.Instance.GetString("NoneDispPref")
|
||||
|
@ -359,7 +359,7 @@ namespace MediaBrowser.ServerApplication
|
|||
var folder = treeItem != null
|
||||
? treeItem.Tag as Folder
|
||||
: null;
|
||||
var prefs = folder != null ? _displayPreferencesManager.GetDisplayPreferences(folder.GetDisplayPreferencesId(CurrentUser.Id)) : new DisplayPreferences { SortBy = ItemSortBy.SortName };
|
||||
var prefs = folder != null ? _displayPreferencesManager.GetDisplayPreferences(folder.GetDisplayPreferencesId(CurrentUser.Id), CurrentUser.Id, "LibraryExplorer") : new DisplayPreferences { SortBy = ItemSortBy.SortName };
|
||||
if (folder != null && prefs.IndexBy != ddlIndexBy.SelectedItem as string)
|
||||
{
|
||||
//grab UI context so we can update within the below task
|
||||
|
@ -400,7 +400,7 @@ namespace MediaBrowser.ServerApplication
|
|||
var folder = treeItem != null
|
||||
? treeItem.Tag as Folder
|
||||
: null;
|
||||
var prefs = folder != null ? _displayPreferencesManager.GetDisplayPreferences(folder.GetDisplayPreferencesId(CurrentUser.Id)) : new DisplayPreferences();
|
||||
var prefs = folder != null ? _displayPreferencesManager.GetDisplayPreferences(folder.GetDisplayPreferencesId(CurrentUser.Id), CurrentUser.Id, "LibraryExplorer") : new DisplayPreferences();
|
||||
if (folder != null && prefs.SortBy != ddlSortBy.SelectedItem as string)
|
||||
{
|
||||
//grab UI context so we can update within the below task
|
||||
|
@ -605,7 +605,7 @@ namespace MediaBrowser.ServerApplication
|
|||
uri = new Uri("pack://application:,,,/Resources/Images/series.png");
|
||||
else if (item is BoxSet)
|
||||
uri = new Uri("pack://application:,,,/Resources/Images/boxset.png");
|
||||
else
|
||||
else
|
||||
uri = new Uri("pack://application:,,,/Resources/Images/folder.png");
|
||||
|
||||
return new BitmapImage(uri);
|
||||
|
|
|
@ -172,12 +172,13 @@
|
|||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Data.SQLite, Version=1.0.86.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86">
|
||||
<Reference Include="System.Data.SQLite, Version=1.0.87.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\System.Data.SQLite.x86.1.0.86.0\lib\net45\System.Data.SQLite.dll</HintPath>
|
||||
<HintPath>..\packages\System.Data.SQLite.x86.1.0.87.0\lib\net45\System.Data.SQLite.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.SQLite.Linq">
|
||||
<HintPath>..\packages\System.Data.SQLite.x86.1.0.86.0\lib\net45\System.Data.SQLite.Linq.dll</HintPath>
|
||||
<Reference Include="System.Data.SQLite.Linq, Version=1.0.87.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\System.Data.SQLite.x86.1.0.87.0\lib\net45\System.Data.SQLite.Linq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net" />
|
||||
|
|
|
@ -12,5 +12,5 @@
|
|||
<package id="ServiceStack.Redis" version="3.9.44" targetFramework="net45" />
|
||||
<package id="ServiceStack.Text" version="3.9.55" targetFramework="net45" />
|
||||
<package id="SimpleInjector" version="2.2.3" targetFramework="net45" />
|
||||
<package id="System.Data.SQLite.x86" version="1.0.86.0" targetFramework="net45" />
|
||||
<package id="System.Data.SQLite.x86" version="1.0.87.0" targetFramework="net45" />
|
||||
</packages>
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>MediaBrowser.Common.Internal</id>
|
||||
<version>3.0.156</version>
|
||||
<version>3.0.157</version>
|
||||
<title>MediaBrowser.Common.Internal</title>
|
||||
<authors>Luke</authors>
|
||||
<owners>ebr,Luke,scottisafool</owners>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
|
||||
<copyright>Copyright © Media Browser 2013</copyright>
|
||||
<dependencies>
|
||||
<dependency id="MediaBrowser.Common" version="3.0.156" />
|
||||
<dependency id="MediaBrowser.Common" version="3.0.157" />
|
||||
<dependency id="NLog" version="2.0.1.2" />
|
||||
<dependency id="ServiceStack.Text" version="3.9.45" />
|
||||
<dependency id="SimpleInjector" version="2.2.3" />
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>MediaBrowser.Common</id>
|
||||
<version>3.0.156</version>
|
||||
<version>3.0.157</version>
|
||||
<title>MediaBrowser.Common</title>
|
||||
<authors>Media Browser Team</authors>
|
||||
<owners>ebr,Luke,scottisafool</owners>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>MediaBrowser.Server.Core</id>
|
||||
<version>3.0.156</version>
|
||||
<version>3.0.157</version>
|
||||
<title>Media Browser.Server.Core</title>
|
||||
<authors>Media Browser Team</authors>
|
||||
<owners>ebr,Luke,scottisafool</owners>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<description>Contains core components required to build plugins for Media Browser Server.</description>
|
||||
<copyright>Copyright © Media Browser 2013</copyright>
|
||||
<dependencies>
|
||||
<dependency id="MediaBrowser.Common" version="3.0.156" />
|
||||
<dependency id="MediaBrowser.Common" version="3.0.157" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
|
|
Loading…
Reference in New Issue