mirror of https://github.com/jellyfin/jellyfin.git
Merge branch 'master' of github.com:MediaBrowser/MediaBrowser
This commit is contained in:
commit
67354bde5f
|
@ -269,7 +269,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
// If fixed dimensions were supplied
|
// If fixed dimensions were supplied
|
||||||
if (request.Width.HasValue && request.Height.HasValue)
|
if (request.Width.HasValue && request.Height.HasValue)
|
||||||
{
|
{
|
||||||
return string.Format(" -vf \"scale={0}:{1}{2}\"", request.Width.Value, request.Height.Value, assSubtitleParam);
|
return string.Format(" -vf \"scale=trunc({0}/2)*2:trunc({1}/2)*2{2}\"", request.Width.Value, request.Height.Value, assSubtitleParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
var isH264Output = outputVideoCodec.Equals("libx264", StringComparison.OrdinalIgnoreCase);
|
var isH264Output = outputVideoCodec.Equals("libx264", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
|
@ -1337,6 +1337,13 @@ namespace MediaBrowser.Controller.Entities
|
||||||
|
|
||||||
var data = userManager.GetUserData(user.Id, key);
|
var data = userManager.GetUserData(user.Id, key);
|
||||||
|
|
||||||
|
if (datePlayed.HasValue)
|
||||||
|
{
|
||||||
|
// Incremenet
|
||||||
|
data.PlayCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure it's at least one
|
||||||
data.PlayCount = Math.Max(data.PlayCount, 1);
|
data.PlayCount = Math.Max(data.PlayCount, 1);
|
||||||
|
|
||||||
data.LastPlayedDate = datePlayed ?? data.LastPlayedDate;
|
data.LastPlayedDate = datePlayed ?? data.LastPlayedDate;
|
||||||
|
|
|
@ -203,7 +203,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||||
|
|
||||||
public bool IsUnaired
|
public bool IsUnaired
|
||||||
{
|
{
|
||||||
get { return PremiereDate.HasValue && PremiereDate.Value >= DateTime.UtcNow; }
|
get { return PremiereDate.HasValue && PremiereDate.Value.ToLocalTime().Date >= DateTime.Now.Date; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsVirtualUnaired
|
public bool IsVirtualUnaired
|
||||||
|
|
|
@ -552,32 +552,6 @@ namespace MediaBrowser.Controller.Providers
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "GamesDbId":
|
|
||||||
var gamesdbId = reader.ReadElementContentAsString();
|
|
||||||
if (!string.IsNullOrWhiteSpace(gamesdbId))
|
|
||||||
{
|
|
||||||
item.SetProviderId(MetadataProviders.Gamesdb, gamesdbId);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "Players":
|
|
||||||
{
|
|
||||||
var val = reader.ReadElementContentAsString();
|
|
||||||
if (!string.IsNullOrWhiteSpace(val))
|
|
||||||
{
|
|
||||||
int num;
|
|
||||||
|
|
||||||
if (int.TryParse(val, NumberStyles.Integer, _usCulture, out num))
|
|
||||||
{
|
|
||||||
var game = item as Game;
|
|
||||||
if (game != null)
|
|
||||||
{
|
|
||||||
game.PlayersSupported = num;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "VoteCount":
|
case "VoteCount":
|
||||||
{
|
{
|
||||||
var val = reader.ReadElementContentAsString();
|
var val = reader.ReadElementContentAsString();
|
||||||
|
@ -592,19 +566,6 @@ namespace MediaBrowser.Controller.Providers
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "GameSystem":
|
|
||||||
{
|
|
||||||
var val = reader.ReadElementContentAsString();
|
|
||||||
if (!string.IsNullOrWhiteSpace(val))
|
|
||||||
{
|
|
||||||
var game = item as Game;
|
|
||||||
if (game != null)
|
|
||||||
{
|
|
||||||
game.GameSystem = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "MusicbrainzId":
|
case "MusicbrainzId":
|
||||||
{
|
{
|
||||||
var mbz = reader.ReadElementContentAsString();
|
var mbz = reader.ReadElementContentAsString();
|
||||||
|
|
|
@ -44,7 +44,8 @@ namespace MediaBrowser.Controller.Resolvers
|
||||||
".f4v",
|
".f4v",
|
||||||
".3gp",
|
".3gp",
|
||||||
".webm",
|
".webm",
|
||||||
".mts"
|
".mts",
|
||||||
|
".rec"
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly Dictionary<string, string> VideoFileExtensionsDictionary = VideoFileExtensions.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
private static readonly Dictionary<string, string> VideoFileExtensionsDictionary = VideoFileExtensions.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
|
@ -3,11 +3,11 @@ using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.IO;
|
using MediaBrowser.Controller.IO;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
|
using MediaBrowser.Providers.Savers;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Providers.Savers;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.Games
|
namespace MediaBrowser.Providers.Games
|
||||||
{
|
{
|
||||||
|
@ -78,7 +78,7 @@ namespace MediaBrowser.Providers.Games
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
new BaseItemXmlParser<Game>(Logger).Fetch(game, metaFile, cancellationToken);
|
new GameXmlParser(Logger).Fetch(game, metaFile, cancellationToken);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
using MediaBrowser.Controller.Entities;
|
||||||
|
using MediaBrowser.Controller.Providers;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
|
using MediaBrowser.Model.Logging;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Providers.Games
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class EpisodeXmlParser
|
||||||
|
/// </summary>
|
||||||
|
public class GameXmlParser : BaseItemXmlParser<Game>
|
||||||
|
{
|
||||||
|
private Task _chaptersTask = null;
|
||||||
|
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||||
|
|
||||||
|
public GameXmlParser(ILogger logger)
|
||||||
|
: base(logger)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task FetchAsync(Game item, string metadataFile, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
_chaptersTask = null;
|
||||||
|
|
||||||
|
Fetch(item, metadataFile, cancellationToken);
|
||||||
|
|
||||||
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
if (_chaptersTask != null)
|
||||||
|
{
|
||||||
|
await _chaptersTask.ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fetches the data from XML node.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reader">The reader.</param>
|
||||||
|
/// <param name="item">The item.</param>
|
||||||
|
protected override void FetchDataFromXmlNode(XmlReader reader, Game item)
|
||||||
|
{
|
||||||
|
switch (reader.Name)
|
||||||
|
{
|
||||||
|
case "GameSystem":
|
||||||
|
{
|
||||||
|
var val = reader.ReadElementContentAsString();
|
||||||
|
if (!string.IsNullOrWhiteSpace(val))
|
||||||
|
{
|
||||||
|
item.GameSystem = val;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "GamesDbId":
|
||||||
|
{
|
||||||
|
var val = reader.ReadElementContentAsString();
|
||||||
|
if (!string.IsNullOrWhiteSpace(val))
|
||||||
|
{
|
||||||
|
item.SetProviderId(MetadataProviders.Gamesdb, val);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "NesBox":
|
||||||
|
{
|
||||||
|
var val = reader.ReadElementContentAsString();
|
||||||
|
if (!string.IsNullOrWhiteSpace(val))
|
||||||
|
{
|
||||||
|
item.SetProviderId(MetadataProviders.NesBox, val);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "NesBoxRom":
|
||||||
|
{
|
||||||
|
var val = reader.ReadElementContentAsString();
|
||||||
|
if (!string.IsNullOrWhiteSpace(val))
|
||||||
|
{
|
||||||
|
item.SetProviderId(MetadataProviders.NesBoxRom, val);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "Players":
|
||||||
|
{
|
||||||
|
var val = reader.ReadElementContentAsString();
|
||||||
|
if (!string.IsNullOrWhiteSpace(val))
|
||||||
|
{
|
||||||
|
int num;
|
||||||
|
|
||||||
|
if (int.TryParse(val, NumberStyles.Integer, _usCulture, out num))
|
||||||
|
{
|
||||||
|
item.PlayersSupported = num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
base.FetchDataFromXmlNode(reader, item);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,6 +49,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="FanartBaseProvider.cs" />
|
<Compile Include="FanartBaseProvider.cs" />
|
||||||
<Compile Include="FolderProviderFromXml.cs" />
|
<Compile Include="FolderProviderFromXml.cs" />
|
||||||
|
<Compile Include="Games\GameXmlParser.cs" />
|
||||||
<Compile Include="Games\GameProviderFromXml.cs" />
|
<Compile Include="Games\GameProviderFromXml.cs" />
|
||||||
<Compile Include="Games\GameSystemProviderFromXml.cs" />
|
<Compile Include="Games\GameSystemProviderFromXml.cs" />
|
||||||
<Compile Include="ImageFromMediaLocationProvider.cs" />
|
<Compile Include="ImageFromMediaLocationProvider.cs" />
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Providers.Movies;
|
using MediaBrowser.Providers.Movies;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -70,6 +71,20 @@ namespace MediaBrowser.Providers.Savers
|
||||||
builder.Append("<GameSystem>" + SecurityElement.Escape(game.GameSystem) + "</GameSystem>");
|
builder.Append("<GameSystem>" + SecurityElement.Escape(game.GameSystem) + "</GameSystem>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var val = game.GetProviderId(MetadataProviders.NesBox);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(val))
|
||||||
|
{
|
||||||
|
builder.Append("<NesBox>" + SecurityElement.Escape(val) + "</NesBox>");
|
||||||
|
}
|
||||||
|
|
||||||
|
val = game.GetProviderId(MetadataProviders.NesBoxRom);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(val))
|
||||||
|
{
|
||||||
|
builder.Append("<NesBoxRom>" + SecurityElement.Escape(val) + "</NesBoxRom>");
|
||||||
|
}
|
||||||
|
|
||||||
XmlSaverHelpers.AddCommonNodes(item, builder);
|
XmlSaverHelpers.AddCommonNodes(item, builder);
|
||||||
|
|
||||||
builder.Append("</Item>");
|
builder.Append("</Item>");
|
||||||
|
@ -79,7 +94,9 @@ namespace MediaBrowser.Providers.Savers
|
||||||
XmlSaverHelpers.Save(builder, xmlFilePath, new List<string>
|
XmlSaverHelpers.Save(builder, xmlFilePath, new List<string>
|
||||||
{
|
{
|
||||||
"Players",
|
"Players",
|
||||||
"GameSystem"
|
"GameSystem",
|
||||||
|
"NesBox",
|
||||||
|
"NesBoxRom"
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set last refreshed so that the provider doesn't trigger after the file save
|
// Set last refreshed so that the provider doesn't trigger after the file save
|
||||||
|
|
|
@ -275,6 +275,7 @@ namespace MediaBrowser.Providers.TV
|
||||||
string url = null;
|
string url = null;
|
||||||
int? bannerSeason = null;
|
int? bannerSeason = null;
|
||||||
string resolution = null;
|
string resolution = null;
|
||||||
|
string language = null;
|
||||||
|
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
|
@ -282,6 +283,12 @@ namespace MediaBrowser.Providers.TV
|
||||||
{
|
{
|
||||||
switch (reader.Name)
|
switch (reader.Name)
|
||||||
{
|
{
|
||||||
|
case "Language":
|
||||||
|
{
|
||||||
|
language = reader.ReadElementContentAsString() ?? string.Empty;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case "BannerType":
|
case "BannerType":
|
||||||
{
|
{
|
||||||
bannerType = reader.ReadElementContentAsString() ?? string.Empty;
|
bannerType = reader.ReadElementContentAsString() ?? string.Empty;
|
||||||
|
@ -333,10 +340,21 @@ namespace MediaBrowser.Providers.TV
|
||||||
}
|
}
|
||||||
else if (string.Equals(bannerType2, "seasonwide", StringComparison.OrdinalIgnoreCase))
|
else if (string.Equals(bannerType2, "seasonwide", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
// Just grab the first
|
if (string.IsNullOrWhiteSpace(language) || string.Equals(language, "en", StringComparison.OrdinalIgnoreCase))
|
||||||
if (string.IsNullOrWhiteSpace(data.Banner))
|
|
||||||
{
|
{
|
||||||
data.Banner = url;
|
// Just grab the first
|
||||||
|
if (string.IsNullOrWhiteSpace(data.Banner))
|
||||||
|
{
|
||||||
|
data.Banner = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (string.Equals(language, ConfigurationManager.Configuration.PreferredMetadataLanguage, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// Just grab the first
|
||||||
|
if (string.IsNullOrWhiteSpace(data.LanguageBanner))
|
||||||
|
{
|
||||||
|
data.LanguageBanner = url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -373,6 +373,11 @@ namespace MediaBrowser.Server.Implementations.Dto
|
||||||
dto.GameSystem = item.GameSystem;
|
dto.GameSystem = item.GameSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SetGameSystemProperties(BaseItemDto dto, GameSystem item)
|
||||||
|
{
|
||||||
|
dto.GameSystem = item.GameSystemName;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the backdrop image tags.
|
/// Gets the backdrop image tags.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1064,6 +1069,13 @@ namespace MediaBrowser.Server.Implementations.Dto
|
||||||
SetGameProperties(dto, game);
|
SetGameProperties(dto, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var gameSystem = item as GameSystem;
|
||||||
|
|
||||||
|
if (gameSystem != null)
|
||||||
|
{
|
||||||
|
SetGameSystemProperties(dto, gameSystem);
|
||||||
|
}
|
||||||
|
|
||||||
var musicVideo = item as MusicVideo;
|
var musicVideo = item as MusicVideo;
|
||||||
|
|
||||||
if (musicVideo != null)
|
if (musicVideo != null)
|
||||||
|
|
|
@ -214,8 +214,6 @@ namespace MediaBrowser.ServerApplication
|
||||||
SystemEvents.SessionEnding += SystemEvents_SessionEnding;
|
SystemEvents.SessionEnding += SystemEvents_SessionEnding;
|
||||||
SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
|
SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
|
||||||
|
|
||||||
MigrateShortcuts(appPaths.RootFolderPath);
|
|
||||||
|
|
||||||
_appHost = new ApplicationHost(appPaths, logManager);
|
_appHost = new ApplicationHost(appPaths, logManager);
|
||||||
|
|
||||||
_app = new App(_appHost, _appHost.LogManager.GetLogger("App"), runService);
|
_app = new App(_appHost, _appHost.LogManager.GetLogger("App"), runService);
|
||||||
|
@ -537,34 +535,5 @@ namespace MediaBrowser.ServerApplication
|
||||||
/// </summary>
|
/// </summary>
|
||||||
SEM_NOOPENFILEERRORBOX = 0x8000
|
SEM_NOOPENFILEERRORBOX = 0x8000
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void MigrateShortcuts(string directory)
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(directory);
|
|
||||||
|
|
||||||
foreach (var file in Directory.EnumerateFiles(directory, "*.lnk", SearchOption.AllDirectories).ToList())
|
|
||||||
{
|
|
||||||
MigrateShortcut(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void MigrateShortcut(string file)
|
|
||||||
{
|
|
||||||
var newFile = Path.ChangeExtension(file, ".mblink");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var resolvedPath = FileSystem.ResolveShortcut(file);
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(resolvedPath))
|
|
||||||
{
|
|
||||||
FileSystem.CreateShortcut(newFile, resolvedPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
File.Delete(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2731,16 +2731,42 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
self.getDateParamValue = function (date) {
|
||||||
* Marks an item as played or unplayed
|
function formatDigit(i) {
|
||||||
* This should not be used to update playstate following playback.
|
return i < 10 ? "0" + i : i;
|
||||||
* There are separate playstate check-in methods for that. This should be used for a
|
}
|
||||||
* separate option to reset playstate.
|
|
||||||
* @param {String} userId
|
var d = date;
|
||||||
* @param {String} itemId
|
|
||||||
* @param {Boolean} wasPlayed
|
return "" + d.getFullYear() + formatDigit(d.getMonth() + 1) + formatDigit(d.getDate()) + formatDigit(d.getHours()) + formatDigit(d.getMinutes()) + formatDigit(d.getSeconds());
|
||||||
*/
|
};
|
||||||
self.updatePlayedStatus = function (userId, itemId, wasPlayed) {
|
|
||||||
|
self.markPlayed = function (userId, itemId, date) {
|
||||||
|
|
||||||
|
if (!userId) {
|
||||||
|
throw new Error("null userId");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!itemId) {
|
||||||
|
throw new Error("null itemId");
|
||||||
|
}
|
||||||
|
|
||||||
|
var options = {};
|
||||||
|
|
||||||
|
if (date) {
|
||||||
|
options.DatePlayed = self.getDateParamValue(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
var url = self.getUrl("Users/" + userId + "/PlayedItems/" + itemId, options);
|
||||||
|
|
||||||
|
return self.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: url,
|
||||||
|
dataType: "json"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
self.markUnplayed = function (userId, itemId) {
|
||||||
|
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
throw new Error("null userId");
|
throw new Error("null userId");
|
||||||
|
@ -2752,10 +2778,8 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
|
||||||
|
|
||||||
var url = self.getUrl("Users/" + userId + "/PlayedItems/" + itemId);
|
var url = self.getUrl("Users/" + userId + "/PlayedItems/" + itemId);
|
||||||
|
|
||||||
var method = wasPlayed ? "POST" : "DELETE";
|
|
||||||
|
|
||||||
return self.ajax({
|
return self.ajax({
|
||||||
type: method,
|
type: "DELETE",
|
||||||
url: url,
|
url: url,
|
||||||
dataType: "json"
|
dataType: "json"
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.181" targetFramework="net45" />
|
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.182" targetFramework="net45" />
|
||||||
<package id="ServiceStack.Common" version="3.9.62" targetFramework="net45" />
|
<package id="ServiceStack.Common" version="3.9.62" targetFramework="net45" />
|
||||||
<package id="ServiceStack.Text" version="3.9.62" targetFramework="net45" />
|
<package id="ServiceStack.Text" version="3.9.62" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
Loading…
Reference in New Issue