diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 67221a9ac9..8174dded26 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1337,6 +1337,13 @@ namespace MediaBrowser.Controller.Entities 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.LastPlayedDate = datePlayed ?? data.LastPlayedDate; diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs index e1b38bc714..e9bb7f66d9 100644 --- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs +++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs @@ -552,32 +552,6 @@ namespace MediaBrowser.Controller.Providers } 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": { var val = reader.ReadElementContentAsString(); @@ -592,19 +566,6 @@ namespace MediaBrowser.Controller.Providers } 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": { var mbz = reader.ReadElementContentAsString(); diff --git a/MediaBrowser.Providers/Games/GameProviderFromXml.cs b/MediaBrowser.Providers/Games/GameProviderFromXml.cs index 6292cec465..44680b8328 100644 --- a/MediaBrowser.Providers/Games/GameProviderFromXml.cs +++ b/MediaBrowser.Providers/Games/GameProviderFromXml.cs @@ -3,11 +3,11 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Logging; +using MediaBrowser.Providers.Savers; using System; using System.IO; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Providers.Savers; namespace MediaBrowser.Providers.Games { @@ -78,7 +78,7 @@ namespace MediaBrowser.Providers.Games try { - new BaseItemXmlParser(Logger).Fetch(game, metaFile, cancellationToken); + new GameXmlParser(Logger).Fetch(game, metaFile, cancellationToken); } finally { diff --git a/MediaBrowser.Providers/Games/GameXmlParser.cs b/MediaBrowser.Providers/Games/GameXmlParser.cs new file mode 100644 index 0000000000..53cc123884 --- /dev/null +++ b/MediaBrowser.Providers/Games/GameXmlParser.cs @@ -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 +{ + /// + /// Class EpisodeXmlParser + /// + public class GameXmlParser : BaseItemXmlParser + { + 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); + } + } + + /// + /// Fetches the data from XML node. + /// + /// The reader. + /// The item. + 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; + } + } + } +} diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index e687e14d9d..63bd8c9534 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -49,6 +49,7 @@ + diff --git a/MediaBrowser.Providers/Savers/GameXmlSaver.cs b/MediaBrowser.Providers/Savers/GameXmlSaver.cs index 5564b71cef..f35e4d1319 100644 --- a/MediaBrowser.Providers/Savers/GameXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/GameXmlSaver.cs @@ -1,6 +1,7 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Entities; using MediaBrowser.Providers.Movies; using System; using System.Collections.Generic; @@ -70,6 +71,20 @@ namespace MediaBrowser.Providers.Savers builder.Append("" + SecurityElement.Escape(game.GameSystem) + ""); } + var val = game.GetProviderId(MetadataProviders.NesBox); + + if (!string.IsNullOrEmpty(val)) + { + builder.Append("" + SecurityElement.Escape(val) + ""); + } + + val = game.GetProviderId(MetadataProviders.NesBoxRom); + + if (!string.IsNullOrEmpty(val)) + { + builder.Append("" + SecurityElement.Escape(val) + ""); + } + XmlSaverHelpers.AddCommonNodes(item, builder); builder.Append(""); @@ -79,7 +94,9 @@ namespace MediaBrowser.Providers.Savers XmlSaverHelpers.Save(builder, xmlFilePath, new List { "Players", - "GameSystem" + "GameSystem", + "NesBox", + "NesBoxRom" }); // Set last refreshed so that the provider doesn't trigger after the file save diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js index 97a443e844..8e64e4300d 100644 --- a/MediaBrowser.WebDashboard/ApiClient.js +++ b/MediaBrowser.WebDashboard/ApiClient.js @@ -2731,16 +2731,17 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi }); }; - /** - * Marks an item as played or unplayed - * This should not be used to update playstate following playback. - * There are separate playstate check-in methods for that. This should be used for a - * separate option to reset playstate. - * @param {String} userId - * @param {String} itemId - * @param {Boolean} wasPlayed - */ - self.updatePlayedStatus = function (userId, itemId, wasPlayed) { + self.getDateParamValue = function (date) { + function formatDigit(i) { + return i < 10 ? "0" + i : i; + } + + var d = date; + + return "" + d.getFullYear() + formatDigit(d.getMonth() + 1) + formatDigit(d.getDate()) + formatDigit(d.getHours()) + formatDigit(d.getMinutes()) + formatDigit(d.getSeconds()); + }; + + self.markPlayed = function (userId, itemId, date) { if (!userId) { throw new Error("null userId"); @@ -2750,12 +2751,35 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi throw new Error("null itemId"); } - var url = self.getUrl("Users/" + userId + "/PlayedItems/" + itemId); + var options = {}; + + if (date) { + options.DatePlayed = self.getDateParamValue(date); + } - var method = wasPlayed ? "POST" : "DELETE"; + var url = self.getUrl("Users/" + userId + "/PlayedItems/" + itemId, options); return self.ajax({ - type: method, + type: "POST", + url: url, + dataType: "json" + }); + }; + + self.markUnplayed = function (userId, itemId) { + + if (!userId) { + throw new Error("null userId"); + } + + if (!itemId) { + throw new Error("null itemId"); + } + + var url = self.getUrl("Users/" + userId + "/PlayedItems/" + itemId); + + return self.ajax({ + type: "DELETE", url: url, dataType: "json" }); diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config index 9c48b38095..02daa2cae4 100644 --- a/MediaBrowser.WebDashboard/packages.config +++ b/MediaBrowser.WebDashboard/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file