diff --git a/MediaBrowser.Api/ApiService.cs b/MediaBrowser.Api/ApiService.cs index b0cc54feea..2687ce81a0 100644 --- a/MediaBrowser.Api/ApiService.cs +++ b/MediaBrowser.Api/ApiService.cs @@ -9,52 +9,91 @@ namespace MediaBrowser.Api { public static BaseItem GetItemById(string id) { - if (string.IsNullOrEmpty(id)) - { - return Kernel.Instance.RootFolder; - } + Guid guid = string.IsNullOrEmpty(id) ? Guid.Empty : new Guid(id); - return GetItemById(new Guid(id)); + return Kernel.Instance.GetItemById(guid); } - public static BaseItem GetItemById(Guid id) + public static IEnumerable GetAllStudios(Folder parent, Guid userId) { - if (id == Guid.Empty) + Dictionary data = new Dictionary(); + + IEnumerable allItems = Kernel.Instance.GetParentalAllowedRecursiveChildren(parent, userId); + + foreach (var item in allItems) { - return Kernel.Instance.RootFolder; + if (item.Studios == null) + { + continue; + } + + foreach (string val in item.Studios) + { + if (!data.ContainsKey(val)) + { + data.Add(val, 1); + } + else + { + data[val]++; + } + } } - return Kernel.Instance.RootFolder.FindById(id); - } + List list = new List(); - public static Person GetPersonByName(string name) - { - return null; - } + foreach (string key in data.Keys) + { + list.Add(new CategoryInfo() + { + Name = key, + ItemCount = data[key] - public static IEnumerable GetItemsWithGenre(Folder parent, string genre) - { - return new BaseItem[] { }; + }); + } + + return list; } - public static IEnumerable GetAllGenres(Folder parent) + public static IEnumerable GetAllGenres(Folder parent, Guid userId) { - return new string[] { }; - } + Dictionary data = new Dictionary(); - public static IEnumerable GetRecentlyAddedItems(Folder parent) - { - return new BaseItem[] { }; - } + IEnumerable allItems = Kernel.Instance.GetParentalAllowedRecursiveChildren(parent, userId); - public static IEnumerable GetRecentlyAddedUnplayedItems(Folder parent) - { - return new BaseItem[] { }; - } + foreach (var item in allItems) + { + if (item.Genres == null) + { + continue; + } - public static IEnumerable GetInProgressItems(Folder parent) - { - return new BaseItem[] { }; + foreach (string val in item.Genres) + { + if (!data.ContainsKey(val)) + { + data.Add(val, 1); + } + else + { + data[val]++; + } + } + } + + List list = new List(); + + foreach (string key in data.Keys) + { + list.Add(new CategoryInfo() + { + Name = key, + ItemCount = data[key] + + }); + } + + return list; } } } diff --git a/MediaBrowser.Api/HttpHandlers/GenreHandler.cs b/MediaBrowser.Api/HttpHandlers/GenreHandler.cs index 27731e39f0..f43e3e1b02 100644 --- a/MediaBrowser.Api/HttpHandlers/GenreHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/GenreHandler.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using MediaBrowser.Common.Net; +using MediaBrowser.Controller; using MediaBrowser.Model.Entities; -using MediaBrowser.Api; namespace MediaBrowser.Api.HttpHandlers { @@ -21,7 +21,7 @@ namespace MediaBrowser.Api.HttpHandlers { Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder; - return ApiService.GetItemsWithGenre(parent, QueryString["name"]); + return Kernel.Instance.GetItemsWithGenre(parent, QueryString["name"], UserId); } } } diff --git a/MediaBrowser.Api/HttpHandlers/GenresHandler.cs b/MediaBrowser.Api/HttpHandlers/GenresHandler.cs index 23755a7a48..794b746cd4 100644 --- a/MediaBrowser.Api/HttpHandlers/GenresHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/GenresHandler.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Net; +using System; +using MediaBrowser.Common.Net; using MediaBrowser.Common.Net.Handlers; using MediaBrowser.Model.Entities; @@ -16,8 +17,9 @@ namespace MediaBrowser.Api.HttpHandlers get { Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder; + Guid userId = Guid.Parse(QueryString["userid"]); - return ApiService.GetAllGenres(parent); + return ApiService.GetAllGenres(parent, userId); } } } diff --git a/MediaBrowser.Api/HttpHandlers/ImageHandler.cs b/MediaBrowser.Api/HttpHandlers/ImageHandler.cs index 12b3d6e572..ed6dcc3a9d 100644 --- a/MediaBrowser.Api/HttpHandlers/ImageHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/ImageHandler.cs @@ -1,9 +1,10 @@ using System; using System.IO; +using System.IO.Compression; using System.Linq; using MediaBrowser.Common.Net; +using MediaBrowser.Controller; using MediaBrowser.Model.Entities; -using System.IO.Compression; namespace MediaBrowser.Api.HttpHandlers { @@ -174,7 +175,7 @@ namespace MediaBrowser.Api.HttpHandlers if (!string.IsNullOrEmpty(personName)) { - item = ApiService.GetPersonByName(personName); + item = Kernel.Instance.ItemController.GetPerson(personName); } else { diff --git a/MediaBrowser.Api/HttpHandlers/InProgressItemsHandler.cs b/MediaBrowser.Api/HttpHandlers/InProgressItemsHandler.cs index 148964f89a..e13cee866c 100644 --- a/MediaBrowser.Api/HttpHandlers/InProgressItemsHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/InProgressItemsHandler.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using MediaBrowser.Common.Net; +using MediaBrowser.Controller; using MediaBrowser.Model.Entities; namespace MediaBrowser.Api.HttpHandlers @@ -17,7 +18,7 @@ namespace MediaBrowser.Api.HttpHandlers { Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder; - return ApiService.GetInProgressItems(parent); + return Kernel.Instance.GetInProgressItems(parent, UserId); } } } diff --git a/MediaBrowser.Api/HttpHandlers/ItemHandler.cs b/MediaBrowser.Api/HttpHandlers/ItemHandler.cs index 7b4b02b630..dd508d1037 100644 --- a/MediaBrowser.Api/HttpHandlers/ItemHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/ItemHandler.cs @@ -1,7 +1,9 @@ -using MediaBrowser.Common.Net; +using System; +using MediaBrowser.Api.Model; +using MediaBrowser.Common.Net; using MediaBrowser.Common.Net.Handlers; +using MediaBrowser.Controller; using MediaBrowser.Model.Entities; -using MediaBrowser.Common.Json; namespace MediaBrowser.Api.HttpHandlers { @@ -16,26 +18,31 @@ namespace MediaBrowser.Api.HttpHandlers { get { - return GetSerializationObject(ItemToSerialize, true); + Guid userId = Guid.Parse(QueryString["userid"]); + + return GetSerializationObject(ItemToSerialize, true, userId); } } - public static object GetSerializationObject(BaseItem item, bool includeChildren) + public static object GetSerializationObject(BaseItem item, bool includeChildren, Guid userId) { - if (includeChildren && item.IsFolder) + BaseItemInfo wrapper = new BaseItemInfo() { - Folder folder = item as Folder; + Item = item, + UserItemData = Kernel.Instance.GetUserItemData(userId, item.Id) + }; - return new - { - BaseItem = item, - Children = folder.Children - }; - } - else + if (includeChildren) { - return item; + var folder = item as Folder; + + if (folder != null) + { + wrapper.Children = Kernel.Instance.GetParentalAllowedChildren(folder, userId); + } } + + return wrapper; } protected virtual BaseItem ItemToSerialize diff --git a/MediaBrowser.Api/HttpHandlers/ItemListHandler.cs b/MediaBrowser.Api/HttpHandlers/ItemListHandler.cs index 33b3f9e71e..ed6e895f38 100644 --- a/MediaBrowser.Api/HttpHandlers/ItemListHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/ItemListHandler.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using MediaBrowser.Common.Net; using MediaBrowser.Common.Net.Handlers; @@ -19,7 +20,7 @@ namespace MediaBrowser.Api.HttpHandlers { return ItemsToSerialize.Select(i => { - return ItemHandler.GetSerializationObject(i, false); + return ItemHandler.GetSerializationObject(i, false, UserId); }); } @@ -29,5 +30,13 @@ namespace MediaBrowser.Api.HttpHandlers { get; } + + protected Guid UserId + { + get + { + return Guid.Parse(QueryString["userid"]); + } + } } } diff --git a/MediaBrowser.Api/HttpHandlers/PersonHandler.cs b/MediaBrowser.Api/HttpHandlers/PersonHandler.cs index 066ab4816d..6a9d376791 100644 --- a/MediaBrowser.Api/HttpHandlers/PersonHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/PersonHandler.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.Net; +using MediaBrowser.Controller; using MediaBrowser.Model.Entities; namespace MediaBrowser.Api.HttpHandlers @@ -14,7 +15,7 @@ namespace MediaBrowser.Api.HttpHandlers { get { - return ApiService.GetPersonByName(QueryString["name"]); + return Kernel.Instance.ItemController.GetPerson(QueryString["name"]); } } } diff --git a/MediaBrowser.Api/HttpHandlers/RecentlyAddedItemsHandler.cs b/MediaBrowser.Api/HttpHandlers/RecentlyAddedItemsHandler.cs index 46084e7f29..8d85eedf4e 100644 --- a/MediaBrowser.Api/HttpHandlers/RecentlyAddedItemsHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/RecentlyAddedItemsHandler.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using MediaBrowser.Common.Net; +using MediaBrowser.Controller; using MediaBrowser.Model.Entities; namespace MediaBrowser.Api.HttpHandlers @@ -19,10 +20,10 @@ namespace MediaBrowser.Api.HttpHandlers if (QueryString["unplayed"] == "1") { - return ApiService.GetRecentlyAddedUnplayedItems(parent); + return Kernel.Instance.GetRecentlyAddedUnplayedItems(parent, UserId); } - return ApiService.GetRecentlyAddedItems(parent); + return Kernel.Instance.GetRecentlyAddedItems(parent, UserId); } } } diff --git a/MediaBrowser.Api/HttpHandlers/StudioHandler.cs b/MediaBrowser.Api/HttpHandlers/StudioHandler.cs new file mode 100644 index 0000000000..9426d0b7c0 --- /dev/null +++ b/MediaBrowser.Api/HttpHandlers/StudioHandler.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller; +using MediaBrowser.Model.Entities; + +namespace MediaBrowser.Api.HttpHandlers +{ + /// + /// Gets all items within containing a studio + /// + public class StudioHandler : ItemListHandler + { + public StudioHandler(RequestContext ctx) + : base(ctx) + { + } + + protected override IEnumerable ItemsToSerialize + { + get + { + Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder; + + return Kernel.Instance.GetItemsWithStudio(parent, QueryString["name"], UserId); + } + } + } +} diff --git a/MediaBrowser.Api/HttpHandlers/StudiosHandler.cs b/MediaBrowser.Api/HttpHandlers/StudiosHandler.cs new file mode 100644 index 0000000000..6b83b9e64f --- /dev/null +++ b/MediaBrowser.Api/HttpHandlers/StudiosHandler.cs @@ -0,0 +1,26 @@ +using System; +using MediaBrowser.Common.Net; +using MediaBrowser.Common.Net.Handlers; +using MediaBrowser.Model.Entities; + +namespace MediaBrowser.Api.HttpHandlers +{ + public class StudiosHandler : JsonHandler + { + public StudiosHandler(RequestContext ctx) + : base(ctx) + { + } + + protected sealed override object ObjectToSerialize + { + get + { + Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder; + Guid userId = Guid.Parse(QueryString["userid"]); + + return ApiService.GetAllStudios(parent, userId); + } + } + } +} diff --git a/MediaBrowser.Api/HttpHandlers/UsersHandler.cs b/MediaBrowser.Api/HttpHandlers/UsersHandler.cs new file mode 100644 index 0000000000..aa8dac11e4 --- /dev/null +++ b/MediaBrowser.Api/HttpHandlers/UsersHandler.cs @@ -0,0 +1,22 @@ +using MediaBrowser.Common.Net; +using MediaBrowser.Common.Net.Handlers; +using MediaBrowser.Controller; + +namespace MediaBrowser.Api.HttpHandlers +{ + class UsersHandler : JsonHandler + { + public UsersHandler(RequestContext ctx) + : base(ctx) + { + } + + protected override object ObjectToSerialize + { + get + { + return Kernel.Instance.Users; + } + } + } +} diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 18bc85ff21..f493da552a 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -53,8 +53,12 @@ + + + + @@ -68,13 +72,14 @@ MediaBrowser.Controller - {9b1ddd79-5134-4df3-ace3-d1957a7350d8} + {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} MediaBrowser.Model + xcopy "$(TargetPath)" "$(SolutionDir)\ProgramData\Plugins\$(ProjectName)\" /y diff --git a/MediaBrowser.Api/Model/BaseItemInfo.cs b/MediaBrowser.Api/Model/BaseItemInfo.cs new file mode 100644 index 0000000000..646c273905 --- /dev/null +++ b/MediaBrowser.Api/Model/BaseItemInfo.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Users; + +namespace MediaBrowser.Api.Model +{ + public class BaseItemInfo + { + public BaseItem Item { get; set; } + + public UserItemData UserItemData { get; set; } + + public IEnumerable Children { get; set; } + } +} diff --git a/MediaBrowser.Api/Plugin.cs b/MediaBrowser.Api/Plugin.cs index 28b45b996b..91bd906c8b 100644 --- a/MediaBrowser.Api/Plugin.cs +++ b/MediaBrowser.Api/Plugin.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Reactive.Linq; using MediaBrowser.Api.HttpHandlers; using MediaBrowser.Common.Plugins; @@ -13,6 +12,8 @@ namespace MediaBrowser.Api { var httpServer = Kernel.Instance.HttpServer; + httpServer.Where(ctx => ctx.LocalPath.EndsWith("/api/users", StringComparison.OrdinalIgnoreCase)).Subscribe(ctx => ctx.Respond(new UsersHandler(ctx))); + httpServer.Where(ctx => ctx.LocalPath.EndsWith("/api/media", StringComparison.OrdinalIgnoreCase)).Subscribe(ctx => ctx.Respond(new MediaHandler(ctx))); httpServer.Where(ctx => ctx.LocalPath.EndsWith("/api/item", StringComparison.OrdinalIgnoreCase)).Subscribe(ctx => ctx.Respond(new ItemHandler(ctx))); @@ -23,6 +24,10 @@ namespace MediaBrowser.Api httpServer.Where(ctx => ctx.LocalPath.EndsWith("/api/genres", StringComparison.OrdinalIgnoreCase)).Subscribe(ctx => ctx.Respond(new GenresHandler(ctx))); + httpServer.Where(ctx => ctx.LocalPath.EndsWith("/api/studio", StringComparison.OrdinalIgnoreCase)).Subscribe(ctx => ctx.Respond(new StudioHandler(ctx))); + + httpServer.Where(ctx => ctx.LocalPath.EndsWith("/api/studios", StringComparison.OrdinalIgnoreCase)).Subscribe(ctx => ctx.Respond(new StudiosHandler(ctx))); + httpServer.Where(ctx => ctx.LocalPath.EndsWith("/api/recentlyaddeditems", StringComparison.OrdinalIgnoreCase)).Subscribe(ctx => ctx.Respond(new RecentlyAddedItemsHandler(ctx))); httpServer.Where(ctx => ctx.LocalPath.EndsWith("/api/inprogressitems", StringComparison.OrdinalIgnoreCase)).Subscribe(ctx => ctx.Respond(new InProgressItemsHandler(ctx))); diff --git a/MediaBrowser.Common/ApiInteraction/ApiController.cs b/MediaBrowser.Common/ApiInteraction/ApiController.cs new file mode 100644 index 0000000000..f237573550 --- /dev/null +++ b/MediaBrowser.Common/ApiInteraction/ApiController.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Net; +using System.Threading.Tasks; +using MediaBrowser.Common.Json; +using MediaBrowser.Model.Users; +using MediaBrowser.Model.Entities; + +namespace MediaBrowser.Common.ApiInteraction +{ + public class ApiController + { + public string ApiUrl { get; set; } + + private WebClient WebClient { get; set; } + + public ApiController() + { + WebClient = new WebClient(); + } + + public async Task GetRootItem(Guid userId) + { + string url = ApiUrl + "/item?userId=" + userId.ToString(); + + Stream stream = await WebClient.OpenReadTaskAsync(url); + + using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + { + return DictionaryBaseItem.FromApiOutput(gzipStream); + } + } + + public async Task GetItem(Guid id, Guid userId) + { + string url = ApiUrl + "/item?userId=" + userId.ToString(); + + if (id != Guid.Empty) + { + url += "&id=" + id.ToString(); + } + + Stream stream = await WebClient.OpenReadTaskAsync(url); + + using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + { + return DictionaryBaseItem.FromApiOutput(gzipStream); + } + } + + public async Task> GetAllUsers() + { + string url = ApiUrl + "/users"; + + Stream stream = await WebClient.OpenReadTaskAsync(url); + + using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + { + return JsonSerializer.DeserializeFromStream>(gzipStream); + } + } + + public async Task> GetAllGenres(Guid userId) + { + string url = ApiUrl + "/genres?userId=" + userId.ToString(); + + Stream stream = await WebClient.OpenReadTaskAsync(url); + + using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + { + return JsonSerializer.DeserializeFromStream>(gzipStream); + } + } + + public async Task GetGenre(string name, Guid userId) + { + string url = ApiUrl + "/genre?userId=" + userId.ToString() + "&name=" + name; + + Stream stream = await WebClient.OpenReadTaskAsync(url); + + using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + { + return JsonSerializer.DeserializeFromStream(gzipStream); + } + } + + public async Task> GetAllStudios(Guid userId) + { + string url = ApiUrl + "/studios?userId=" + userId.ToString(); + + Stream stream = await WebClient.OpenReadTaskAsync(url); + + using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + { + return JsonSerializer.DeserializeFromStream>(gzipStream); + } + } + + public async Task GetStudio(string name, Guid userId) + { + string url = ApiUrl + "/studio?userId=" + userId.ToString() + "&name=" + name; + + Stream stream = await WebClient.OpenReadTaskAsync(url); + + using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + { + return JsonSerializer.DeserializeFromStream(gzipStream); + } + } + } +} diff --git a/MediaBrowser.Common/ApiInteraction/DictionaryBaseItem.cs b/MediaBrowser.Common/ApiInteraction/DictionaryBaseItem.cs new file mode 100644 index 0000000000..2bd6f1bcd5 --- /dev/null +++ b/MediaBrowser.Common/ApiInteraction/DictionaryBaseItem.cs @@ -0,0 +1,412 @@ +using System; +using System.Collections.Generic; +using System.IO; +using MediaBrowser.Common.Json; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Users; +using System.Linq; + +namespace MediaBrowser.Common.ApiInteraction +{ + public class DictionaryBaseItem : BaseItem + { + private Dictionary Dictionary { get; set; } + + public UserItemData UserItemData { get; set; } + public IEnumerable Children { get; set; } + + public DictionaryBaseItem(Dictionary dictionary) + { + Dictionary = dictionary; + } + + public override string Name + { + get + { + return GetString("Name"); + } + set + { + SetValue("Name", value); + } + } + + public override string ArtImagePath + { + get + { + return GetString("ArtImagePath"); + } + set + { + SetValue("ArtImagePath", value); + } + } + + public override string AspectRatio + { + get + { + return GetString("AspectRatio"); + } + set + { + SetValue("AspectRatio", value); + } + } + + public override string BannerImagePath + { + get + { + return GetString("BannerImagePath"); + } + set + { + SetValue("BannerImagePath", value); + } + } + + public override string CustomPin + { + get + { + return GetString("CustomPin"); + } + set + { + SetValue("CustomPin", value); + } + } + + public override string CustomRating + { + get + { + return GetString("CustomRating"); + } + set + { + SetValue("CustomRating", value); + } + } + + public override string DisplayMediaType + { + get + { + return GetString("DisplayMediaType"); + } + set + { + SetValue("DisplayMediaType", value); + } + } + + public override string LogoImagePath + { + get + { + return GetString("LogoImagePath"); + } + set + { + SetValue("LogoImagePath", value); + } + } + + public override string OfficialRating + { + get + { + return GetString("OfficialRating"); + } + set + { + SetValue("OfficialRating", value); + } + } + + public override string Overview + { + get + { + return GetString("Overview"); + } + set + { + SetValue("Overview", value); + } + } + + public override string Path + { + get + { + return GetString("Path"); + } + set + { + SetValue("Path", value); + } + } + + public override string PrimaryImagePath + { + get + { + return GetString("PrimaryImagePath"); + } + set + { + SetValue("PrimaryImagePath", value); + } + } + + public override string SortName + { + get + { + return GetString("SortName"); + } + set + { + SetValue("SortName", value); + } + } + + public override string Tagline + { + get + { + return GetString("Tagline"); + } + set + { + SetValue("Tagline", value); + } + } + + public override string TrailerUrl + { + get + { + return GetString("TrailerUrl"); + } + set + { + SetValue("TrailerUrl", value); + } + } + + public override DateTime DateCreated + { + get + { + return GetDateTime("DateCreated"); + } + set + { + SetValue("DateCreated", value); + } + } + + public override DateTime DateModified + { + get + { + return GetDateTime("DateModified"); + } + set + { + SetValue("DateModified", value); + } + } + + public override float? UserRating + { + get + { + return GetNullableFloat("UserRating"); + } + set + { + SetValue("UserRating", value); + } + } + + public override string ThumbnailImagePath + { + get + { + return GetString("ThumbnailImagePath"); + } + set + { + SetValue("ThumbnailImagePath", value); + } + } + + public override int? ProductionYear + { + get + { + return GetNullableInt("ProductionYear"); + } + set + { + SetValue("ProductionYear", value); + } + } + + public override TimeSpan? RunTime + { + get + { + return GetNullableTimeSpan("RunTime"); + } + set + { + SetValue("RunTime", value); + } + } + + public bool IsFolder + { + get + { + return GetBool("IsFolder"); + } + } + + public override Guid Id + { + get + { + return GetGuid("Id"); + } + set + { + SetValue("Id", value); + } + } + + public TimeSpan? GetNullableTimeSpan(string name) + { + string val = Dictionary[name] as string; + + if (string.IsNullOrEmpty(val)) + { + return null; + } + + return TimeSpan.Parse(val); + } + + public int? GetNullableInt(string name) + { + string val = Dictionary[name] as string; + + if (string.IsNullOrEmpty(val)) + { + return null; + } + + return int.Parse(val); + } + + public float? GetNullableFloat(string name) + { + string val = Dictionary[name] as string; + + if (string.IsNullOrEmpty(val)) + { + return null; + } + + return float.Parse(val); + } + + public DateTime? GetNullableDateTime(string name) + { + string val = Dictionary[name] as string; + + if (string.IsNullOrEmpty(val)) + { + return null; + } + + return DateTime.Parse(val); + } + + public DateTime GetDateTime(string name) + { + DateTime? val = GetNullableDateTime(name); + + return val ?? DateTime.MinValue; + } + + public bool? GetNullableBool(string name) + { + string val = Dictionary[name] as string; + + if (string.IsNullOrEmpty(val)) + { + return null; + } + + return val != "false"; + } + + public Guid GetGuid(string name) + { + string val = GetString(name); + + if (string.IsNullOrEmpty(val)) + { + return Guid.Empty; + } + + return Guid.Parse(val); + } + + public bool GetBool(string name) + { + bool? val = GetNullableBool(name); + + return val ?? false; + } + + public string GetString(string name) + { + return Dictionary[name] as string; + } + + private void SetValue(string name, T value) + { + Dictionary[name] = value; + } + + public static DictionaryBaseItem FromApiOutput(Stream stream) + { + Dictionary data = JsonSerializer.DeserializeFromStream>(stream); + + string baseItem = data["Item"] as string; + + DictionaryBaseItem item = new DictionaryBaseItem(JsonSerializer.DeserializeFromString>(baseItem)); + + if (data.ContainsKey("UserItemData")) + { + item.UserItemData = JsonSerializer.DeserializeFromString(data["UserItemData"].ToString()); + } + + if (data.ContainsKey("Children")) + { + item.Children = JsonSerializer.DeserializeFromString>>(data["Children"].ToString()).Select(c => new DictionaryBaseItem(c)); + } + + return item; + } + } +} diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index 8ee14d3a98..f822b1a2bd 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -45,9 +45,10 @@ + - + @@ -70,7 +71,7 @@ - {9b1ddd79-5134-4df3-ace3-d1957a7350d8} + {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} MediaBrowser.Model diff --git a/MediaBrowser.Common/Model/DictionaryBaseItem.cs b/MediaBrowser.Common/Model/DictionaryBaseItem.cs deleted file mode 100644 index 8bdcf1460b..0000000000 --- a/MediaBrowser.Common/Model/DictionaryBaseItem.cs +++ /dev/null @@ -1,227 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using MediaBrowser.Model.Entities; -using System.IO; -using MediaBrowser.Common.Json; - -namespace MediaBrowser.Common.Model -{ - public class DictionaryBaseItem : BaseItem - { - private Dictionary Dictionary { get; set; } - - public DictionaryBaseItem(Dictionary dictionary) - { - Dictionary = dictionary; - } - - public override string Name - { - get - { - return GetString("Name"); - } - set - { - SetValue("Name", value); - } - } - - public override string ArtImagePath - { - get - { - return GetString("ArtImagePath"); - } - set - { - SetValue("ArtImagePath", value); - } - } - - public override string AspectRatio - { - get - { - return GetString("AspectRatio"); - } - set - { - SetValue("AspectRatio", value); - } - } - - public override string BannerImagePath - { - get - { - return GetString("BannerImagePath"); - } - set - { - SetValue("BannerImagePath", value); - } - } - - public override string CustomPin - { - get - { - return GetString("CustomPin"); - } - set - { - SetValue("CustomPin", value); - } - } - - public override string CustomRating - { - get - { - return GetString("CustomRating"); - } - set - { - SetValue("CustomRating", value); - } - } - - public override string DisplayMediaType - { - get - { - return GetString("DisplayMediaType"); - } - set - { - SetValue("DisplayMediaType", value); - } - } - - public override string LogoImagePath - { - get - { - return GetString("LogoImagePath"); - } - set - { - SetValue("LogoImagePath", value); - } - } - - public override string OfficialRating - { - get - { - return GetString("OfficialRating"); - } - set - { - SetValue("OfficialRating", value); - } - } - - public override string Overview - { - get - { - return GetString("Overview"); - } - set - { - SetValue("Overview", value); - } - } - - public override string Path - { - get - { - return GetString("Path"); - } - set - { - SetValue("Path", value); - } - } - - public override string PrimaryImagePath - { - get - { - return GetString("PrimaryImagePath"); - } - set - { - SetValue("PrimaryImagePath", value); - } - } - - public override string SortName - { - get - { - return GetString("SortName"); - } - set - { - SetValue("SortName", value); - } - } - - public override string Tagline - { - get - { - return GetString("Tagline"); - } - set - { - SetValue("Tagline", value); - } - } - - public override string TrailerUrl - { - get - { - return GetString("TrailerUrl"); - } - set - { - SetValue("TrailerUrl", value); - } - } - - private string GetString(string name) - { - return Dictionary[name] as string; - } - - private void SetValue(string name, T value) - { - Dictionary[name] = value; - } - - public static DictionaryBaseItem FromApiOutput(Stream stream) - { - Dictionary data = JsonSerializer.DeserializeFromStream>(stream); - - if (data.ContainsKey("BaseItem")) - { - string baseItem = data["BaseItem"] as string; - - data = JsonSerializer.DeserializeFromString>(baseItem); - - return new DictionaryBaseItem(data); - } - - return new DictionaryBaseItem(data); - } - } -} diff --git a/MediaBrowser.Configuration/MediaBrowser.Configuration.csproj b/MediaBrowser.Configuration/MediaBrowser.Configuration.csproj index 356aa502f2..b94672537b 100644 --- a/MediaBrowser.Configuration/MediaBrowser.Configuration.csproj +++ b/MediaBrowser.Configuration/MediaBrowser.Configuration.csproj @@ -55,10 +55,6 @@ {17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2} MediaBrowser.Controller - - {9b1ddd79-5134-4df3-ace3-d1957a7350d8} - MediaBrowser.Model - diff --git a/MediaBrowser.Controller/Kernel.cs b/MediaBrowser.Controller/Kernel.cs index 3db0cca8f0..3f6e7bbb0e 100644 --- a/MediaBrowser.Controller/Kernel.cs +++ b/MediaBrowser.Controller/Kernel.cs @@ -84,7 +84,6 @@ namespace MediaBrowser.Controller // Get users from users folder // Load root media folder Parallel.Invoke(ReloadUsers, ReloadRoot); - var b = true; } private void ReloadConfiguration() @@ -234,5 +233,131 @@ namespace MediaBrowser.Controller item.Parent.Children = children.ToArray(); } } + + /// + /// Finds a library item by Id + /// + public BaseItem GetItemById(Guid id) + { + if (id == Guid.Empty) + { + return RootFolder; + } + + return RootFolder.FindById(id); + } + + /// + /// Determines if an item is allowed for a given user + /// + public bool IsParentalAllowed(BaseItem item, Guid userId) + { + // not yet implemented + return true; + } + + /// + /// Gets allowed children of an item + /// + public IEnumerable GetParentalAllowedChildren(Folder folder, Guid userId) + { + return folder.Children.ToList().Where(i => IsParentalAllowed(i, userId)); + } + + /// + /// Gets allowed recursive children of an item + /// + public IEnumerable GetParentalAllowedRecursiveChildren(Folder folder, Guid userId) + { + foreach (var item in GetParentalAllowedChildren(folder, userId)) + { + yield return item; + + var subFolder = item as Folder; + + if (subFolder != null) + { + foreach (var subitem in GetParentalAllowedRecursiveChildren(subFolder, userId)) + { + yield return subitem; + } + } + } + } + + /// + /// Gets user data for an item, if there is any + /// + public UserItemData GetUserItemData(Guid userId, Guid itemId) + { + User user = Users.First(u => u.Id == userId); + + if (user.ItemData.ContainsKey(itemId)) + { + return user.ItemData[itemId]; + } + + return null; + } + + /// + /// Gets all recently added items (recursive) within a folder, based on configuration and parental settings + /// + public IEnumerable GetRecentlyAddedItems(Folder parent, Guid userId) + { + DateTime now = DateTime.Now; + + return GetParentalAllowedRecursiveChildren(parent, userId).Where(i => (now - i.DateCreated).TotalDays < Configuration.RecentItemDays); + } + + /// + /// Gets all recently added unplayed items (recursive) within a folder, based on configuration and parental settings + /// + public IEnumerable GetRecentlyAddedUnplayedItems(Folder parent, Guid userId) + { + return GetRecentlyAddedItems(parent, userId).Where(i => + { + var userdata = GetUserItemData(userId, i.Id); + + return userdata == null || userdata.PlayCount == 0; + }); + } + + /// + /// Gets all in-progress items (recursive) within a folder + /// + public IEnumerable GetInProgressItems(Folder parent, Guid userId) + { + return GetParentalAllowedRecursiveChildren(parent, userId).Where(i => + { + var userdata = GetUserItemData(userId, i.Id); + + return userdata != null && userdata.PlaybackPosition.Ticks > 0; + }); + } + + /// + /// Finds all recursive items within a top-level parent that contain the given studio and are allowed for the current user + /// + public IEnumerable GetItemsWithStudio(Folder parent, string studio, Guid userId) + { + return GetParentalAllowedRecursiveChildren(parent, userId).Where(f => f.Studios != null && f.Studios.Any(s => s.Equals(studio, StringComparison.OrdinalIgnoreCase))); + } + + /// + /// Finds all recursive items within a top-level parent that contain the given genre and are allowed for the current user + /// + public IEnumerable GetItemsWithGenre(Folder parent, string genre, Guid userId) + { + return GetParentalAllowedRecursiveChildren(parent, userId).Where(f => f.Genres != null && f.Genres.Any(s => s.Equals(genre, StringComparison.OrdinalIgnoreCase))); + } + + /// + /// Finds all recursive items within a top-level parent that contain the given person and are allowed for the current user + /// + public IEnumerable GetItemsWithPerson(Folder parent, string personName, Guid userId) + { + return GetParentalAllowedRecursiveChildren(parent, userId).Where(f => f.People != null && f.People.Any(s => s.Name.Equals(personName, StringComparison.OrdinalIgnoreCase))); + } } } diff --git a/MediaBrowser.Controller/Library/ItemController.cs b/MediaBrowser.Controller/Library/ItemController.cs index f0be2baf9b..b872e8dbae 100644 --- a/MediaBrowser.Controller/Library/ItemController.cs +++ b/MediaBrowser.Controller/Library/ItemController.cs @@ -310,5 +310,23 @@ namespace MediaBrowser.Controller.Library return returnFiles; } + + public Person GetPerson(string name) + { + // not yet implemented + return null; + } + + public Studio GetStudio(string name) + { + // not yet implemented + return null; + } + + public Year GetYear(int value) + { + // not yet implemented + return null; + } } } diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index c89a32c268..719d279eeb 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -63,7 +63,7 @@ MediaBrowser.Common - {9b1ddd79-5134-4df3-ace3-d1957a7350d8} + {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} MediaBrowser.Model diff --git a/MediaBrowser.HtmlBrowser/MediaBrowser.HtmlBrowser.csproj b/MediaBrowser.HtmlBrowser/MediaBrowser.HtmlBrowser.csproj index d01ca1b1dc..219ec35c53 100644 --- a/MediaBrowser.HtmlBrowser/MediaBrowser.HtmlBrowser.csproj +++ b/MediaBrowser.HtmlBrowser/MediaBrowser.HtmlBrowser.csproj @@ -56,7 +56,7 @@ MediaBrowser.Controller - {9b1ddd79-5134-4df3-ace3-d1957a7350d8} + {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} MediaBrowser.Model diff --git a/MediaBrowser.InternetProviders/MediaBrowser.InternetProviders.csproj b/MediaBrowser.InternetProviders/MediaBrowser.InternetProviders.csproj index 7503443318..3b88a5b56b 100644 --- a/MediaBrowser.InternetProviders/MediaBrowser.InternetProviders.csproj +++ b/MediaBrowser.InternetProviders/MediaBrowser.InternetProviders.csproj @@ -52,10 +52,6 @@ {17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2} MediaBrowser.Controller - - {9b1ddd79-5134-4df3-ace3-d1957a7350d8} - MediaBrowser.Model - {92b9f802-4415-438f-90e1-44602135ea41} MediaBrowser.Movies diff --git a/MediaBrowser.Model/Configuration/Configuration.cs b/MediaBrowser.Model/Configuration/Configuration.cs index 63ed22fc5a..e7dc4b8438 100644 --- a/MediaBrowser.Model/Configuration/Configuration.cs +++ b/MediaBrowser.Model/Configuration/Configuration.cs @@ -6,11 +6,13 @@ namespace MediaBrowser.Model.Configuration { public string ImagesByNamePath { get; set; } public int HttpServerPortNumber { get; set; } + public int RecentItemDays { get; set; } public LogSeverity LogSeverity { get; set; } public Configuration() { HttpServerPortNumber = 8096; + RecentItemDays = 14; LogSeverity = LogSeverity.Info; } } diff --git a/MediaBrowser.Model/Entities/Audio.cs b/MediaBrowser.Model/Entities/Audio.cs index b243411adb..bfd739b5a7 100644 --- a/MediaBrowser.Model/Entities/Audio.cs +++ b/MediaBrowser.Model/Entities/Audio.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - + namespace MediaBrowser.Model.Entities { public class Audio : BaseItem diff --git a/MediaBrowser.Model/Entities/BaseItem.cs b/MediaBrowser.Model/Entities/BaseItem.cs index a9c564a284..165328ac7b 100644 --- a/MediaBrowser.Model/Entities/BaseItem.cs +++ b/MediaBrowser.Model/Entities/BaseItem.cs @@ -51,6 +51,7 @@ namespace MediaBrowser.Model.Entities public virtual string AspectRatio { get; set; } public virtual int? ProductionYear { get; set; } + [IgnoreDataMember] public virtual IEnumerable