diff --git a/MediaBrowser.Api/ApiService.cs b/MediaBrowser.Api/ApiService.cs index 2687ce81a0..e495937790 100644 --- a/MediaBrowser.Api/ApiService.cs +++ b/MediaBrowser.Api/ApiService.cs @@ -1,10 +1,16 @@ using System; using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; using MediaBrowser.Controller; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Users; namespace MediaBrowser.Api { + /// + /// Contains some helpers for the api + /// public static class ApiService { public static BaseItem GetItemById(string id) @@ -14,86 +20,29 @@ namespace MediaBrowser.Api return Kernel.Instance.GetItemById(guid); } - public static IEnumerable GetAllStudios(Folder parent, Guid userId) + /// + /// Takes a BaseItem and returns the actual object that will be serialized by the api + /// + public static ApiBaseItemWrapper GetSerializationObject(BaseItem item, bool includeChildren, Guid userId) { - Dictionary data = new Dictionary(); - - IEnumerable allItems = Kernel.Instance.GetParentalAllowedRecursiveChildren(parent, userId); - - foreach (var item in allItems) + ApiBaseItemWrapper wrapper = new ApiBaseItemWrapper() { - if (item.Studios == null) - { - continue; - } + Item = item, + UserItemData = Kernel.Instance.GetUserItemData(userId, item.Id), + ItemType = item.GetType() + }; - foreach (string val in item.Studios) + if (includeChildren) + { + var folder = item as Folder; + + if (folder != null) { - if (!data.ContainsKey(val)) - { - data.Add(val, 1); - } - else - { - data[val]++; - } + wrapper.Children = Kernel.Instance.GetParentalAllowedChildren(folder, userId).Select(c => GetSerializationObject(c, false, userId)); } } - List list = new List(); - - foreach (string key in data.Keys) - { - list.Add(new CategoryInfo() - { - Name = key, - ItemCount = data[key] - - }); - } - - return list; - } - - public static IEnumerable GetAllGenres(Folder parent, Guid userId) - { - Dictionary data = new Dictionary(); - - IEnumerable allItems = Kernel.Instance.GetParentalAllowedRecursiveChildren(parent, userId); - - foreach (var item in allItems) - { - if (item.Genres == null) - { - continue; - } - - 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; + return wrapper; } } } diff --git a/MediaBrowser.Api/HttpHandlers/GenreHandler.cs b/MediaBrowser.Api/HttpHandlers/GenreHandler.cs index f43e3e1b02..477705e827 100644 --- a/MediaBrowser.Api/HttpHandlers/GenreHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/GenreHandler.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Model.Entities; @@ -10,11 +9,6 @@ namespace MediaBrowser.Api.HttpHandlers /// public class GenreHandler : ItemListHandler { - public GenreHandler(RequestContext ctx) - : base(ctx) - { - } - protected override IEnumerable ItemsToSerialize { get diff --git a/MediaBrowser.Api/HttpHandlers/GenresHandler.cs b/MediaBrowser.Api/HttpHandlers/GenresHandler.cs index 794b746cd4..e8e3fd80b7 100644 --- a/MediaBrowser.Api/HttpHandlers/GenresHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/GenresHandler.cs @@ -1,17 +1,11 @@ using System; -using MediaBrowser.Common.Net; -using MediaBrowser.Common.Net.Handlers; +using MediaBrowser.Controller; using MediaBrowser.Model.Entities; namespace MediaBrowser.Api.HttpHandlers { public class GenresHandler : JsonHandler { - public GenresHandler(RequestContext ctx) - : base(ctx) - { - } - protected sealed override object ObjectToSerialize { get @@ -19,7 +13,7 @@ namespace MediaBrowser.Api.HttpHandlers Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder; Guid userId = Guid.Parse(QueryString["userid"]); - return ApiService.GetAllGenres(parent, userId); + return Kernel.Instance.GetAllGenres(parent, userId); } } } diff --git a/MediaBrowser.Api/HttpHandlers/ImageHandler.cs b/MediaBrowser.Api/HttpHandlers/ImageHandler.cs index ed6dcc3a9d..ae6228ae87 100644 --- a/MediaBrowser.Api/HttpHandlers/ImageHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/ImageHandler.cs @@ -1,27 +1,14 @@ using System; using System.IO; -using System.IO.Compression; using System.Linq; -using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Model.Entities; +using MediaBrowser.Net.Handlers; namespace MediaBrowser.Api.HttpHandlers { - public class ImageHandler : Response + public class ImageHandler : BaseHandler { - public ImageHandler(RequestContext ctx) - : base(ctx) - { - Headers["Content-Encoding"] = "gzip"; - - WriteStream = s => - { - WriteReponse(s); - s.Close(); - }; - } - private string _ImagePath = string.Empty; private string ImagePath { @@ -149,12 +136,9 @@ namespace MediaBrowser.Api.HttpHandlers } } - private void WriteReponse(Stream stream) + protected override void WriteResponseToOutputStream(Stream stream) { - using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Compress, false)) - { - ImageProcessor.ProcessImage(ImagePath, gzipStream, Width, Height, MaxWidth, MaxHeight, Quality); - } + ImageProcessor.ProcessImage(ImagePath, stream, Width, Height, MaxWidth, MaxHeight, Quality); } private string GetImagePath() diff --git a/MediaBrowser.Api/HttpHandlers/InProgressItemsHandler.cs b/MediaBrowser.Api/HttpHandlers/InProgressItemsHandler.cs index e13cee866c..2bee275a45 100644 --- a/MediaBrowser.Api/HttpHandlers/InProgressItemsHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/InProgressItemsHandler.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Model.Entities; @@ -7,11 +6,6 @@ namespace MediaBrowser.Api.HttpHandlers { class InProgressItemsHandler : ItemListHandler { - public InProgressItemsHandler(RequestContext ctx) - : base(ctx) - { - } - protected override IEnumerable ItemsToSerialize { get diff --git a/MediaBrowser.Api/HttpHandlers/ItemHandler.cs b/MediaBrowser.Api/HttpHandlers/ItemHandler.cs index dd508d1037..2ff2354939 100644 --- a/MediaBrowser.Api/HttpHandlers/ItemHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/ItemHandler.cs @@ -1,50 +1,21 @@ using System; -using MediaBrowser.Api.Model; -using MediaBrowser.Common.Net; -using MediaBrowser.Common.Net.Handlers; -using MediaBrowser.Controller; +using MediaBrowser.Net.Handlers; using MediaBrowser.Model.Entities; namespace MediaBrowser.Api.HttpHandlers { public class ItemHandler : JsonHandler { - public ItemHandler(RequestContext ctx) - : base(ctx) - { - } - protected sealed override object ObjectToSerialize { get { Guid userId = Guid.Parse(QueryString["userid"]); - return GetSerializationObject(ItemToSerialize, true, userId); + return ApiService.GetSerializationObject(ItemToSerialize, true, userId); } } - public static object GetSerializationObject(BaseItem item, bool includeChildren, Guid userId) - { - BaseItemInfo wrapper = new BaseItemInfo() - { - Item = item, - UserItemData = Kernel.Instance.GetUserItemData(userId, item.Id) - }; - - if (includeChildren) - { - var folder = item as Folder; - - if (folder != null) - { - wrapper.Children = Kernel.Instance.GetParentalAllowedChildren(folder, userId); - } - } - - return wrapper; - } - protected virtual BaseItem ItemToSerialize { get diff --git a/MediaBrowser.Api/HttpHandlers/ItemListHandler.cs b/MediaBrowser.Api/HttpHandlers/ItemListHandler.cs index ed6e895f38..54af1b7e91 100644 --- a/MediaBrowser.Api/HttpHandlers/ItemListHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/ItemListHandler.cs @@ -1,26 +1,20 @@ using System; using System.Collections.Generic; using System.Linq; -using MediaBrowser.Common.Net; -using MediaBrowser.Common.Net.Handlers; +using MediaBrowser.Net.Handlers; using MediaBrowser.Model.Entities; namespace MediaBrowser.Api.HttpHandlers { public abstract class ItemListHandler : JsonHandler { - public ItemListHandler(RequestContext ctx) - : base(ctx) - { - } - protected sealed override object ObjectToSerialize { get { return ItemsToSerialize.Select(i => { - return ItemHandler.GetSerializationObject(i, false, UserId); + return ApiService.GetSerializationObject(i, false, UserId); }); } diff --git a/MediaBrowser.Api/HttpHandlers/JsonHandler.cs b/MediaBrowser.Api/HttpHandlers/JsonHandler.cs new file mode 100644 index 0000000000..e663085ec7 --- /dev/null +++ b/MediaBrowser.Api/HttpHandlers/JsonHandler.cs @@ -0,0 +1,16 @@ +using System.IO; +using MediaBrowser.Common.Json; +using MediaBrowser.Net.Handlers; + +namespace MediaBrowser.Api.HttpHandlers +{ + public abstract class JsonHandler : BaseJsonHandler + { + protected abstract object ObjectToSerialize { get; } + + protected override void WriteResponseToOutputStream(Stream stream) + { + JsonSerializer.SerializeToStream(ObjectToSerialize, stream); + } + } +} diff --git a/MediaBrowser.Api/HttpHandlers/MediaHandler.cs b/MediaBrowser.Api/HttpHandlers/MediaHandler.cs index d04ff21996..47aab3c410 100644 --- a/MediaBrowser.Api/HttpHandlers/MediaHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/MediaHandler.cs @@ -1,23 +1,12 @@ using System; using System.IO; -using System.IO.Compression; -using MediaBrowser.Common.Net; using MediaBrowser.Model.Entities; +using MediaBrowser.Net.Handlers; namespace MediaBrowser.Api.HttpHandlers { - class MediaHandler : Response + class MediaHandler : BaseHandler { - public MediaHandler(RequestContext ctx) - : base(ctx) - { - WriteStream = s => - { - WriteReponse(s); - s.Close(); - }; - } - private string _MediaPath = string.Empty; private string MediaPath { @@ -46,6 +35,14 @@ namespace MediaBrowser.Api.HttpHandlers return item.Path; } + public override bool GzipResponse + { + get + { + return false; + } + } + public override string ContentType { get @@ -87,7 +84,7 @@ namespace MediaBrowser.Api.HttpHandlers } } - private void WriteReponse(Stream stream) + protected override void WriteResponseToOutputStream(Stream stream) { try { @@ -100,6 +97,5 @@ namespace MediaBrowser.Api.HttpHandlers { } } - } } diff --git a/MediaBrowser.Api/HttpHandlers/PersonHandler.cs b/MediaBrowser.Api/HttpHandlers/PersonHandler.cs index 6a9d376791..3c1a0ecf3a 100644 --- a/MediaBrowser.Api/HttpHandlers/PersonHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/PersonHandler.cs @@ -1,16 +1,10 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Controller; +using MediaBrowser.Controller; using MediaBrowser.Model.Entities; namespace MediaBrowser.Api.HttpHandlers { public class PersonHandler : ItemHandler { - public PersonHandler(RequestContext ctx) - : base(ctx) - { - } - protected override BaseItem ItemToSerialize { get diff --git a/MediaBrowser.Api/HttpHandlers/RecentlyAddedItemsHandler.cs b/MediaBrowser.Api/HttpHandlers/RecentlyAddedItemsHandler.cs index 8d85eedf4e..f36c9c9975 100644 --- a/MediaBrowser.Api/HttpHandlers/RecentlyAddedItemsHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/RecentlyAddedItemsHandler.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Model.Entities; @@ -7,11 +6,6 @@ namespace MediaBrowser.Api.HttpHandlers { class RecentlyAddedItemsHandler : ItemListHandler { - public RecentlyAddedItemsHandler(RequestContext ctx) - : base(ctx) - { - } - protected override IEnumerable ItemsToSerialize { get diff --git a/MediaBrowser.Api/HttpHandlers/StudioHandler.cs b/MediaBrowser.Api/HttpHandlers/StudioHandler.cs index 9426d0b7c0..019ced0281 100644 --- a/MediaBrowser.Api/HttpHandlers/StudioHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/StudioHandler.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Model.Entities; @@ -10,11 +9,6 @@ namespace MediaBrowser.Api.HttpHandlers /// public class StudioHandler : ItemListHandler { - public StudioHandler(RequestContext ctx) - : base(ctx) - { - } - protected override IEnumerable ItemsToSerialize { get diff --git a/MediaBrowser.Api/HttpHandlers/StudiosHandler.cs b/MediaBrowser.Api/HttpHandlers/StudiosHandler.cs index 6b83b9e64f..66daca7774 100644 --- a/MediaBrowser.Api/HttpHandlers/StudiosHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/StudiosHandler.cs @@ -1,17 +1,12 @@ using System; -using MediaBrowser.Common.Net; -using MediaBrowser.Common.Net.Handlers; +using MediaBrowser.Net.Handlers; +using MediaBrowser.Controller; using MediaBrowser.Model.Entities; namespace MediaBrowser.Api.HttpHandlers { public class StudiosHandler : JsonHandler { - public StudiosHandler(RequestContext ctx) - : base(ctx) - { - } - protected sealed override object ObjectToSerialize { get @@ -19,7 +14,7 @@ namespace MediaBrowser.Api.HttpHandlers Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder; Guid userId = Guid.Parse(QueryString["userid"]); - return ApiService.GetAllStudios(parent, userId); + return Kernel.Instance.GetAllStudios(parent, userId); } } } diff --git a/MediaBrowser.Api/HttpHandlers/UsersHandler.cs b/MediaBrowser.Api/HttpHandlers/UsersHandler.cs index aa8dac11e4..816d4e83ac 100644 --- a/MediaBrowser.Api/HttpHandlers/UsersHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/UsersHandler.cs @@ -1,16 +1,10 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Common.Net.Handlers; +using MediaBrowser.Net.Handlers; using MediaBrowser.Controller; namespace MediaBrowser.Api.HttpHandlers { class UsersHandler : JsonHandler { - public UsersHandler(RequestContext ctx) - : base(ctx) - { - } - protected override object ObjectToSerialize { get diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index f493da552a..dd5c072324 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -37,6 +37,7 @@ False ..\packages\Rx-Main.1.0.11226\lib\Net4\System.Reactive.dll + @@ -51,6 +52,7 @@ + @@ -58,7 +60,6 @@ - @@ -75,6 +76,10 @@ {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} MediaBrowser.Model + + {5da08d1c-0d52-4b1b-aa66-e4a171d938f6} + MediaBrowser.Net + diff --git a/MediaBrowser.Api/Model/BaseItemInfo.cs b/MediaBrowser.Api/Model/BaseItemInfo.cs deleted file mode 100644 index 646c273905..0000000000 --- a/MediaBrowser.Api/Model/BaseItemInfo.cs +++ /dev/null @@ -1,15 +0,0 @@ -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 91bd906c8b..af885ef825 100644 --- a/MediaBrowser.Api/Plugin.cs +++ b/MediaBrowser.Api/Plugin.cs @@ -3,6 +3,8 @@ using System.Reactive.Linq; using MediaBrowser.Api.HttpHandlers; using MediaBrowser.Common.Plugins; using MediaBrowser.Controller; +using MediaBrowser.Net; +using MediaBrowser.Net.Handlers; namespace MediaBrowser.Api { @@ -12,25 +14,70 @@ 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.IndexOf("/api/", StringComparison.OrdinalIgnoreCase) != -1).Subscribe(ctx => + { + BaseHandler handler = GetHandler(ctx); - httpServer.Where(ctx => ctx.LocalPath.EndsWith("/api/media", StringComparison.OrdinalIgnoreCase)).Subscribe(ctx => ctx.Respond(new MediaHandler(ctx))); + if (handler != null) + { + ctx.Respond(handler); + } + }); + } - httpServer.Where(ctx => ctx.LocalPath.EndsWith("/api/item", StringComparison.OrdinalIgnoreCase)).Subscribe(ctx => ctx.Respond(new ItemHandler(ctx))); + private BaseHandler GetHandler(RequestContext ctx) + { + BaseHandler handler = null; - httpServer.Where(ctx => ctx.LocalPath.EndsWith("/api/image", StringComparison.OrdinalIgnoreCase)).Subscribe(ctx => ctx.Respond(new ImageHandler(ctx))); + string localPath = ctx.LocalPath; - httpServer.Where(ctx => ctx.LocalPath.EndsWith("/api/genre", StringComparison.OrdinalIgnoreCase)).Subscribe(ctx => ctx.Respond(new GenreHandler(ctx))); + if (localPath.EndsWith("/api/item", StringComparison.OrdinalIgnoreCase)) + { + handler = new ItemHandler(); + } + else if (localPath.EndsWith("/api/image", StringComparison.OrdinalIgnoreCase)) + { + handler = new ImageHandler(); + } + else if (localPath.EndsWith("/api/users", StringComparison.OrdinalIgnoreCase)) + { + handler = new UsersHandler(); + } + else if (localPath.EndsWith("/api/media", StringComparison.OrdinalIgnoreCase)) + { + handler = new MediaHandler(); + } + else if (localPath.EndsWith("/api/genre", StringComparison.OrdinalIgnoreCase)) + { + handler = new GenreHandler(); + } + else if (localPath.EndsWith("/api/genres", StringComparison.OrdinalIgnoreCase)) + { + handler = new GenresHandler(); + } + else if (localPath.EndsWith("/api/studio", StringComparison.OrdinalIgnoreCase)) + { + handler = new StudioHandler(); + } + else if (localPath.EndsWith("/api/studios", StringComparison.OrdinalIgnoreCase)) + { + handler = new StudiosHandler(); + } + else if (localPath.EndsWith("/api/recentlyaddeditems", StringComparison.OrdinalIgnoreCase)) + { + handler = new RecentlyAddedItemsHandler(); + } + else if (localPath.EndsWith("/api/inprogressitems", StringComparison.OrdinalIgnoreCase)) + { + handler = new InProgressItemsHandler(); + } - httpServer.Where(ctx => ctx.LocalPath.EndsWith("/api/genres", StringComparison.OrdinalIgnoreCase)).Subscribe(ctx => ctx.Respond(new GenresHandler(ctx))); + if (handler != null) + { + handler.RequestContext = 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))); + return handler; } } } diff --git a/MediaBrowser.Common/ApiInteraction/ApiController.cs b/MediaBrowser.Common/ApiInteraction/ApiController.cs index f237573550..b3a51c512e 100644 --- a/MediaBrowser.Common/ApiInteraction/ApiController.cs +++ b/MediaBrowser.Common/ApiInteraction/ApiController.cs @@ -2,11 +2,12 @@ using System.Collections.Generic; using System.IO; using System.IO.Compression; +using System.Linq; using System.Net; using System.Threading.Tasks; using MediaBrowser.Common.Json; -using MediaBrowser.Model.Users; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Users; namespace MediaBrowser.Common.ApiInteraction { @@ -21,19 +22,20 @@ namespace MediaBrowser.Common.ApiInteraction WebClient = new WebClient(); } - public async Task GetRootItem(Guid userId) + 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)) + using (Stream stream = await WebClient.OpenReadTaskAsync(url)) { - return DictionaryBaseItem.FromApiOutput(gzipStream); + using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + { + return DeserializeBaseItemWrapper(gzipStream); + } } } - public async Task GetItem(Guid id, Guid userId) + public async Task> GetItem(Guid id, Guid userId) { string url = ApiUrl + "/item?userId=" + userId.ToString(); @@ -42,11 +44,12 @@ namespace MediaBrowser.Common.ApiInteraction url += "&id=" + id.ToString(); } - Stream stream = await WebClient.OpenReadTaskAsync(url); - - using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + using (Stream stream = await WebClient.OpenReadTaskAsync(url)) { - return DictionaryBaseItem.FromApiOutput(gzipStream); + using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + { + return DeserializeBaseItemWrapper(gzipStream); + } } } @@ -54,11 +57,12 @@ namespace MediaBrowser.Common.ApiInteraction { string url = ApiUrl + "/users"; - Stream stream = await WebClient.OpenReadTaskAsync(url); - - using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + using (Stream stream = await WebClient.OpenReadTaskAsync(url)) { - return JsonSerializer.DeserializeFromStream>(gzipStream); + using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + { + return JsonSerializer.DeserializeFromStream>(gzipStream); + } } } @@ -66,11 +70,12 @@ namespace MediaBrowser.Common.ApiInteraction { string url = ApiUrl + "/genres?userId=" + userId.ToString(); - Stream stream = await WebClient.OpenReadTaskAsync(url); - - using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + using (Stream stream = await WebClient.OpenReadTaskAsync(url)) { - return JsonSerializer.DeserializeFromStream>(gzipStream); + using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + { + return JsonSerializer.DeserializeFromStream>(gzipStream); + } } } @@ -78,11 +83,12 @@ namespace MediaBrowser.Common.ApiInteraction { string url = ApiUrl + "/genre?userId=" + userId.ToString() + "&name=" + name; - Stream stream = await WebClient.OpenReadTaskAsync(url); - - using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + using (Stream stream = await WebClient.OpenReadTaskAsync(url)) { - return JsonSerializer.DeserializeFromStream(gzipStream); + using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + { + return JsonSerializer.DeserializeFromStream(gzipStream); + } } } @@ -90,11 +96,12 @@ namespace MediaBrowser.Common.ApiInteraction { string url = ApiUrl + "/studios?userId=" + userId.ToString(); - Stream stream = await WebClient.OpenReadTaskAsync(url); - - using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + using (Stream stream = await WebClient.OpenReadTaskAsync(url)) { - return JsonSerializer.DeserializeFromStream>(gzipStream); + using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + { + return JsonSerializer.DeserializeFromStream>(gzipStream); + } } } @@ -102,12 +109,20 @@ namespace MediaBrowser.Common.ApiInteraction { string url = ApiUrl + "/studio?userId=" + userId.ToString() + "&name=" + name; - Stream stream = await WebClient.OpenReadTaskAsync(url); - - using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + using (Stream stream = await WebClient.OpenReadTaskAsync(url)) { - return JsonSerializer.DeserializeFromStream(gzipStream); + using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, false)) + { + return JsonSerializer.DeserializeFromStream(gzipStream); + } } } + + private static ApiBaseItemWrapper DeserializeBaseItemWrapper(Stream stream) + { + ApiBaseItemWrapper data = JsonSerializer.DeserializeFromStream>(stream); + + return data; + } } } diff --git a/MediaBrowser.Common/ApiInteraction/DictionaryBaseItem.cs b/MediaBrowser.Common/ApiInteraction/DictionaryBaseItem.cs deleted file mode 100644 index 2bd6f1bcd5..0000000000 --- a/MediaBrowser.Common/ApiInteraction/DictionaryBaseItem.cs +++ /dev/null @@ -1,412 +0,0 @@ -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/Json/JsonSerializer.cs b/MediaBrowser.Common/Json/JsonSerializer.cs index 55663357ab..a882334897 100644 --- a/MediaBrowser.Common/Json/JsonSerializer.cs +++ b/MediaBrowser.Common/Json/JsonSerializer.cs @@ -1,23 +1,24 @@ using System.IO; +using System; namespace MediaBrowser.Common.Json { public class JsonSerializer { - public static void SerializeToStream(T o, Stream stream) + public static void SerializeToStream(T obj, Stream stream) { Configure(); - ServiceStack.Text.JsonSerializer.SerializeToStream(o, stream); + ServiceStack.Text.JsonSerializer.SerializeToStream(obj, stream); } - public static void SerializeToFile(T o, string file) + public static void SerializeToFile(T obj, string file) { Configure(); using (StreamWriter streamWriter = new StreamWriter(file)) { - ServiceStack.Text.JsonSerializer.SerializeToWriter(o, streamWriter); + ServiceStack.Text.JsonSerializer.SerializeToWriter(obj, streamWriter); } } @@ -44,12 +45,11 @@ namespace MediaBrowser.Common.Json return ServiceStack.Text.JsonSerializer.DeserializeFromString(data); } - + private static void Configure() { ServiceStack.Text.JsConfig.ExcludeTypeInfo = true; ServiceStack.Text.JsConfig.IncludeNullValues = false; - ServiceStack.Text.JsConfig.DateHandler = ServiceStack.Text.JsonDateHandler.ISO8601; } } } diff --git a/MediaBrowser.Common/Logging/Logger.cs b/MediaBrowser.Common/Logging/Logger.cs index 5f4c2ff795..d1ae9b8f35 100644 --- a/MediaBrowser.Common/Logging/Logger.cs +++ b/MediaBrowser.Common/Logging/Logger.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace MediaBrowser.Common.Logging { diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index f822b1a2bd..252c9c8cca 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -35,9 +35,6 @@ - - ..\packages\Rx-Main.1.0.11226\lib\Net4\System.Reactive.dll - @@ -48,15 +45,6 @@ - - - - - - - - - diff --git a/MediaBrowser.Common/Net/Handlers/JsonHandler.cs b/MediaBrowser.Common/Net/Handlers/JsonHandler.cs deleted file mode 100644 index ecfdd311a1..0000000000 --- a/MediaBrowser.Common/Net/Handlers/JsonHandler.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.IO; -using System.IO.Compression; -using MediaBrowser.Common.Json; - -namespace MediaBrowser.Common.Net.Handlers -{ - public abstract class JsonHandler : Response - { - public JsonHandler(RequestContext ctx) - : base(ctx) - { - Headers["Content-Encoding"] = "gzip"; - - WriteStream = s => - { - WriteReponse(s); - s.Close(); - }; - } - - public override string ContentType - { - get { return "application/json"; } - } - - protected abstract object ObjectToSerialize { get; } - - private void WriteReponse(Stream stream) - { - using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Compress, false)) - { - JsonSerializer.SerializeToStream(ObjectToSerialize, gzipStream); - } - } - } -} diff --git a/MediaBrowser.Common/Net/Response.cs b/MediaBrowser.Common/Net/Response.cs deleted file mode 100644 index 44b4e29622..0000000000 --- a/MediaBrowser.Common/Net/Response.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.IO; - -namespace MediaBrowser.Common.Net -{ - public abstract class Response - { - protected RequestContext RequestContext { get; private set; } - - protected NameValueCollection QueryString - { - get - { - return RequestContext.Request.QueryString; - } - } - - public Response(RequestContext ctx) - { - RequestContext = ctx; - - WriteStream = s => { }; - Headers = new Dictionary(); - } - - public abstract string ContentType { get; } - - public virtual int StatusCode - { - get - { - return 200; - } - } - - public virtual TimeSpan CacheDuration - { - get - { - return TimeSpan.FromTicks(0); - } - } - - public virtual DateTime? LastDateModified - { - get - { - return null; - } - } - - public IDictionary Headers { get; set; } - public Action WriteStream { get; set; } - } - - /*public class ByteResponse : Response - { - public ByteResponse(byte[] bytes) - { - WriteStream = async s => - { - await s.WriteAsync(bytes, 0, bytes.Length); - s.Close(); - }; - } - } - - public class StringResponse : ByteResponse - { - public StringResponse(string message) - : base(Encoding.UTF8.GetBytes(message)) - { - } - }*/ -} \ No newline at end of file diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs index 3438b09c20..be72dabca3 100644 --- a/MediaBrowser.Common/Plugins/BasePlugin.cs +++ b/MediaBrowser.Common/Plugins/BasePlugin.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; +using System.IO; using MediaBrowser.Common.Json; namespace MediaBrowser.Common.Plugins diff --git a/MediaBrowser.Common/Plugins/BasePluginConfiguration.cs b/MediaBrowser.Common/Plugins/BasePluginConfiguration.cs index ad7972d949..d3e47c84a4 100644 --- a/MediaBrowser.Common/Plugins/BasePluginConfiguration.cs +++ b/MediaBrowser.Common/Plugins/BasePluginConfiguration.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - + namespace MediaBrowser.Common.Plugins { public class BasePluginConfiguration diff --git a/MediaBrowser.Common/packages.config b/MediaBrowser.Common/packages.config index 15a978d36c..aad898882a 100644 --- a/MediaBrowser.Common/packages.config +++ b/MediaBrowser.Common/packages.config @@ -1,5 +1,4 @@  - \ No newline at end of file diff --git a/MediaBrowser.Controller/Events/ItemResolveEventArgs.cs b/MediaBrowser.Controller/Events/ItemResolveEventArgs.cs index c05c139fb0..7c4af71ebc 100644 --- a/MediaBrowser.Controller/Events/ItemResolveEventArgs.cs +++ b/MediaBrowser.Controller/Events/ItemResolveEventArgs.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; -using MediaBrowser.Model.Entities; using System.IO; -using System.Linq; +using MediaBrowser.Model.Entities; namespace MediaBrowser.Controller.Events { + /// + /// This is an EventArgs object used when resolving a Path into a BaseItem + /// public class ItemResolveEventArgs : PreBeginResolveEventArgs { public IEnumerable> FileSystemChildren { get; set; } @@ -57,6 +59,11 @@ namespace MediaBrowser.Controller.Events } } + /// + /// This is an EventArgs object used before we begin resolving a Path into a BaseItem + /// File system children have not been collected yet, but consuming events will + /// have a chance to cancel resolution based on the Path, Parent and FileAttributes + /// public class PreBeginResolveEventArgs : EventArgs { public string Path { get; set; } diff --git a/MediaBrowser.Controller/IO/DirectoryWatchers.cs b/MediaBrowser.Controller/IO/DirectoryWatchers.cs index dd27695834..8d102e80ce 100644 --- a/MediaBrowser.Controller/IO/DirectoryWatchers.cs +++ b/MediaBrowser.Controller/IO/DirectoryWatchers.cs @@ -24,9 +24,9 @@ namespace MediaBrowser.Controller.IO pathsToWatch.Add(rootFolder.Path); - foreach (Folder folder in rootFolder.FolderChildren) + foreach (Folder folder in rootFolder.Children.OfType()) { - foreach (Folder subFolder in folder.FolderChildren) + foreach (Folder subFolder in folder.Children.OfType()) { if (Path.IsPathRooted(subFolder.Path)) { diff --git a/MediaBrowser.Controller/IO/Shortcut.cs b/MediaBrowser.Controller/IO/Shortcut.cs index 376d16a795..83e2c0eda3 100644 --- a/MediaBrowser.Controller/IO/Shortcut.cs +++ b/MediaBrowser.Controller/IO/Shortcut.cs @@ -5,6 +5,9 @@ using System.Text; namespace MediaBrowser.Controller.IO { + /// + /// Contains helpers to interact with shortcut files (.lnk) + /// public static class Shortcut { #region Signitures were imported from http://pinvoke.net diff --git a/MediaBrowser.Controller/Kernel.cs b/MediaBrowser.Controller/Kernel.cs index 3f6e7bbb0e..9cbef68740 100644 --- a/MediaBrowser.Controller/Kernel.cs +++ b/MediaBrowser.Controller/Kernel.cs @@ -7,7 +7,6 @@ using System.Text; using System.Threading.Tasks; using MediaBrowser.Common.Json; using MediaBrowser.Common.Logging; -using MediaBrowser.Common.Net; using MediaBrowser.Common.Plugins; using MediaBrowser.Controller.Events; using MediaBrowser.Controller.IO; @@ -16,6 +15,7 @@ using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Users; +using MediaBrowser.Net; namespace MediaBrowser.Controller { @@ -79,7 +79,7 @@ namespace MediaBrowser.Controller ReloadHttpServer(); - ReloadPlugins(); + LoadPlugins(); // Get users from users folder // Load root media folder @@ -94,7 +94,7 @@ namespace MediaBrowser.Controller Logger.LoggerInstance.LogSeverity = Configuration.LogSeverity; } - private void ReloadPlugins() + private void LoadPlugins() { // Find plugins Plugins = PluginController.GetAllPlugins(); @@ -261,7 +261,7 @@ namespace MediaBrowser.Controller /// public IEnumerable GetParentalAllowedChildren(Folder folder, Guid userId) { - return folder.Children.ToList().Where(i => IsParentalAllowed(i, userId)); + return folder.Children.Where(i => IsParentalAllowed(i, userId)); } /// @@ -307,7 +307,7 @@ namespace MediaBrowser.Controller { DateTime now = DateTime.Now; - return GetParentalAllowedRecursiveChildren(parent, userId).Where(i => (now - i.DateCreated).TotalDays < Configuration.RecentItemDays); + return GetParentalAllowedRecursiveChildren(parent, userId).Where(i => !(i is Folder) && (now - i.DateCreated).TotalDays < Configuration.RecentItemDays); } /// @@ -330,6 +330,11 @@ namespace MediaBrowser.Controller { return GetParentalAllowedRecursiveChildren(parent, userId).Where(i => { + if (i is Folder) + { + return false; + } + var userdata = GetUserItemData(userId, i.Id); return userdata != null && userdata.PlaybackPosition.Ticks > 0; @@ -359,5 +364,116 @@ namespace MediaBrowser.Controller { return GetParentalAllowedRecursiveChildren(parent, userId).Where(f => f.People != null && f.People.Any(s => s.Name.Equals(personName, StringComparison.OrdinalIgnoreCase))); } + + /// + /// Gets all studios from all recursive children of a folder + /// The CategoryInfo class is used to keep track of the number of times each studio appears + /// + public IEnumerable GetAllStudios(Folder parent, Guid userId) + { + Dictionary data = new Dictionary(); + + // Get all the allowed recursive children + IEnumerable allItems = Kernel.Instance.GetParentalAllowedRecursiveChildren(parent, userId); + + foreach (var item in allItems) + { + // Add each studio from the item to the data dictionary + // If the studio already exists, increment the count + if (item.Studios == null) + { + continue; + } + + foreach (string val in item.Studios) + { + if (!data.ContainsKey(val)) + { + data.Add(val, 1); + } + else + { + data[val]++; + } + } + } + + // Now go through the dictionary and create a Category for each studio + List list = new List(); + + foreach (string key in data.Keys) + { + // Get the original entity so that we can also supply the PrimaryImagePath + Studio entity = Kernel.Instance.ItemController.GetStudio(key); + + if (entity != null) + { + list.Add(new CategoryInfo() + { + Name = entity.Name, + ItemCount = data[key], + PrimaryImagePath = entity.PrimaryImagePath + }); + } + } + + return list; + } + + /// + /// Gets all genres from all recursive children of a folder + /// The CategoryInfo class is used to keep track of the number of times each genres appears + /// + public IEnumerable GetAllGenres(Folder parent, Guid userId) + { + Dictionary data = new Dictionary(); + + // Get all the allowed recursive children + IEnumerable allItems = Kernel.Instance.GetParentalAllowedRecursiveChildren(parent, userId); + + foreach (var item in allItems) + { + // Add each genre from the item to the data dictionary + // If the genre already exists, increment the count + if (item.Genres == null) + { + continue; + } + + foreach (string val in item.Genres) + { + if (!data.ContainsKey(val)) + { + data.Add(val, 1); + } + else + { + data[val]++; + } + } + } + + // Now go through the dictionary and create a Category for each genre + List list = new List(); + + foreach (string key in data.Keys) + { + // Get the original entity so that we can also supply the PrimaryImagePath + Genre entity = Kernel.Instance.ItemController.GetGenre(key); + + if (entity != null) + { + list.Add(new CategoryInfo() + { + Name = entity.Name, + ItemCount = data[key], + PrimaryImagePath = entity.PrimaryImagePath + }); + } + } + + return list; + } + } } diff --git a/MediaBrowser.Controller/Library/ItemController.cs b/MediaBrowser.Controller/Library/ItemController.cs index b872e8dbae..fee53e3bb6 100644 --- a/MediaBrowser.Controller/Library/ItemController.cs +++ b/MediaBrowser.Controller/Library/ItemController.cs @@ -323,6 +323,12 @@ namespace MediaBrowser.Controller.Library return null; } + public Genre GetGenre(string name) + { + // not yet implemented + return null; + } + public Year GetYear(int value) { // not yet implemented diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 719d279eeb..1f57090a67 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -66,6 +66,10 @@ {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} MediaBrowser.Model + + {5da08d1c-0d52-4b1b-aa66-e4a171d938f6} + MediaBrowser.Net + diff --git a/MediaBrowser.Controller/Resolvers/AudioResolver.cs b/MediaBrowser.Controller/Resolvers/AudioResolver.cs index f9ce5ecd70..2ca54e71d4 100644 --- a/MediaBrowser.Controller/Resolvers/AudioResolver.cs +++ b/MediaBrowser.Controller/Resolvers/AudioResolver.cs @@ -8,6 +8,8 @@ namespace MediaBrowser.Controller.Resolvers { protected override Audio Resolve(ItemResolveEventArgs args) { + // Return audio if the path is a file and has a matching extension + if (!args.IsFolder) { if (IsAudioFile(args.Path)) diff --git a/MediaBrowser.Controller/Resolvers/BaseItemResolver.cs b/MediaBrowser.Controller/Resolvers/BaseItemResolver.cs index e2c49e90c1..dccdf57e1b 100644 --- a/MediaBrowser.Controller/Resolvers/BaseItemResolver.cs +++ b/MediaBrowser.Controller/Resolvers/BaseItemResolver.cs @@ -15,6 +15,9 @@ namespace MediaBrowser.Controller.Resolvers return null; } + /// + /// Sets initial values on the newly resolved item + /// protected virtual void SetItemValues(T item, ItemResolveEventArgs args) { // If the subclass didn't specify this @@ -23,6 +26,7 @@ namespace MediaBrowser.Controller.Resolvers item.Path = args.Path; } + // If the subclass didn't specify this if (args.Parent != null) { item.Parent = args.Parent; @@ -40,9 +44,14 @@ namespace MediaBrowser.Controller.Resolvers if (item != null) { + // Set initial values on the newly resolved item + SetItemValues(item, args); + // Make sure the item has a name EnsureName(item); + + // Make sure DateCreated and DateModified have values EnsureDates(item); } @@ -59,6 +68,9 @@ namespace MediaBrowser.Controller.Resolvers } + /// + /// Ensures DateCreated and DateModified have values + /// private void EnsureDates(T item) { // If the subclass didn't supply dates, add them here @@ -73,6 +85,9 @@ namespace MediaBrowser.Controller.Resolvers } } + /// + /// Fills in image paths based on files win the folder + /// protected virtual void PopulateImages(T item, ItemResolveEventArgs args) { List backdropFiles = new List(); @@ -88,6 +103,7 @@ namespace MediaBrowser.Controller.Resolvers string ext = Path.GetExtension(filePath); + // Only support png and jpg files if (!ext.EndsWith("png", StringComparison.OrdinalIgnoreCase) && !ext.EndsWith("jpg", StringComparison.OrdinalIgnoreCase)) { continue; @@ -137,6 +153,9 @@ namespace MediaBrowser.Controller.Resolvers } } + /// + /// Weed this to keep a list of resolvers, since Resolvers are built with generics + /// public interface IBaseItemResolver { BaseItem ResolvePath(ItemResolveEventArgs args); diff --git a/MediaBrowser.Controller/Resolvers/FolderResolver.cs b/MediaBrowser.Controller/Resolvers/FolderResolver.cs index 5c57c6bb3c..6101a45fd8 100644 --- a/MediaBrowser.Controller/Resolvers/FolderResolver.cs +++ b/MediaBrowser.Controller/Resolvers/FolderResolver.cs @@ -29,6 +29,7 @@ namespace MediaBrowser.Controller.Resolvers item.IsRoot = args.Parent == null; + // Read data from folder.xml, if it exists PopulateFolderMetadata(item, args); } diff --git a/MediaBrowser.Controller/Resolvers/VideoResolver.cs b/MediaBrowser.Controller/Resolvers/VideoResolver.cs index ba51dab875..df304c3290 100644 --- a/MediaBrowser.Controller/Resolvers/VideoResolver.cs +++ b/MediaBrowser.Controller/Resolvers/VideoResolver.cs @@ -1,20 +1,26 @@ -using System.IO; +using System.Collections.Generic; +using System.IO; using MediaBrowser.Controller.Events; using MediaBrowser.Model.Entities; -using System.Linq; -using System.Collections.Generic; namespace MediaBrowser.Controller.Resolvers { + /// + /// Resolves a Path into a Video + /// public class VideoResolver : BaseVideoResolver diff --git a/MediaBrowser.HtmlBrowser/Plugin.cs b/MediaBrowser.HtmlBrowser/Plugin.cs index 1599881d0b..db3f72f6f5 100644 --- a/MediaBrowser.HtmlBrowser/Plugin.cs +++ b/MediaBrowser.HtmlBrowser/Plugin.cs @@ -1,6 +1,6 @@ using System; using System.Reactive.Linq; -using MediaBrowser.Common.Net.Handlers; +using MediaBrowser.Net.Handlers; using MediaBrowser.Common.Plugins; using MediaBrowser.Controller; using MediaBrowser.HtmlBrowser.Handlers; @@ -13,7 +13,7 @@ namespace MediaBrowser.HtmlBrowser { var httpServer = Kernel.Instance.HttpServer; - httpServer.Where(ctx => ctx.LocalPath.IndexOf("/browser/", StringComparison.OrdinalIgnoreCase) != -1).Subscribe(ctx => + /*httpServer.Where(ctx => ctx.LocalPath.IndexOf("/browser/", StringComparison.OrdinalIgnoreCase) != -1).Subscribe(ctx => { string localPath = ctx.LocalPath; string srch = "/browser/"; @@ -24,7 +24,7 @@ namespace MediaBrowser.HtmlBrowser ctx.Respond(new EmbeddedResourceHandler(ctx, resource)); - }); + });*/ } } } diff --git a/MediaBrowser.Model/Entities/ApiBaseItem.cs b/MediaBrowser.Model/Entities/ApiBaseItem.cs new file mode 100644 index 0000000000..bdab9239a1 --- /dev/null +++ b/MediaBrowser.Model/Entities/ApiBaseItem.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using MediaBrowser.Model.Users; + +namespace MediaBrowser.Model.Entities +{ + /// + /// This is a concrete class that the UI can use to deserialize + /// It is flat in the sense that it will be used regardless of the type of BaseItem involved + /// + public class ApiBaseItem : BaseItem + { + } + + /// + /// This is the full return object when requesting an Item + /// + public class ApiBaseItemWrapper + where T : BaseItem + { + public T Item { get; set; } + + public UserItemData UserItemData { get; set; } + + public IEnumerable> Children { get; set; } + + [IgnoreDataMember] + public Type ItemType { get; set; } + + public string Type + { + get + { + return ItemType.Name; + } + } + } +} diff --git a/MediaBrowser.Model/Entities/BaseItem.cs b/MediaBrowser.Model/Entities/BaseItem.cs index 165328ac7b..46f859c9dc 100644 --- a/MediaBrowser.Model/Entities/BaseItem.cs +++ b/MediaBrowser.Model/Entities/BaseItem.cs @@ -6,70 +6,70 @@ namespace MediaBrowser.Model.Entities { public abstract class BaseItem { - public virtual string Name { get; set; } - public virtual string SortName { get; set; } + public string Name { get; set; } + public string SortName { get; set; } - public virtual Guid Id { get; set; } + public Guid Id { get; set; } - public virtual DateTime DateCreated { get; set; } + public DateTime DateCreated { get; set; } - public virtual DateTime DateModified { get; set; } + public DateTime DateModified { get; set; } - public virtual string Path { get; set; } + /// + /// When the item first debuted. For movies this could be premiere date, episodes would be first aired + /// + public DateTime? PremiereDate { get; set; } + + public string Path { get; set; } [IgnoreDataMember] public Folder Parent { get; set; } - public virtual string PrimaryImagePath { get; set; } - public virtual string LogoImagePath { get; set; } - public virtual string ArtImagePath { get; set; } - public virtual string ThumbnailImagePath { get; set; } - public virtual string BannerImagePath { get; set; } + public string PrimaryImagePath { get; set; } + public string LogoImagePath { get; set; } + public string ArtImagePath { get; set; } + public string ThumbnailImagePath { get; set; } + public string BannerImagePath { get; set; } - public virtual IEnumerable BackdropImagePaths { get; set; } + public IEnumerable BackdropImagePaths { get; set; } - public virtual string OfficialRating { get; set; } + public string OfficialRating { get; set; } - public virtual string CustomRating { get; set; } - public virtual string CustomPin { get; set; } + public string CustomRating { get; set; } + public string CustomPin { get; set; } - public virtual string Overview { get; set; } - public virtual string Tagline { get; set; } + public string Overview { get; set; } + public string Tagline { get; set; } [IgnoreDataMember] - public virtual IEnumerable People { get; set; } + public IEnumerable People { get; set; } - public virtual IEnumerable Studios { get; set; } + public IEnumerable Studios { get; set; } - public virtual IEnumerable Genres { get; set; } + public IEnumerable Genres { get; set; } - public virtual string DisplayMediaType { get; set; } + public string DisplayMediaType { get; set; } - public virtual float? UserRating { get; set; } - public virtual TimeSpan? RunTime { get; set; } + public float? UserRating { get; set; } + public TimeSpan? RunTime { get; set; } - public virtual string AspectRatio { get; set; } - public virtual int? ProductionYear { get; set; } + public string AspectRatio { get; set; } + public int? ProductionYear { get; set; } + + /// + /// If the item is part of a series, this is it's number in the series. + /// This could be episode number, album track number, etc. + /// + public int? IndexNumber { get; set; } [IgnoreDataMember] - public virtual IEnumerable + diff --git a/MediaBrowser.Model/Users/User.cs b/MediaBrowser.Model/Users/User.cs index 316e5b55c7..3761d981d4 100644 --- a/MediaBrowser.Model/Users/User.cs +++ b/MediaBrowser.Model/Users/User.cs @@ -6,7 +6,6 @@ namespace MediaBrowser.Model.Users { public class User : BaseItem { - public string Password { get; set; } public string MaxParentalRating { get; set; } private Dictionary _ItemData = new Dictionary(); diff --git a/MediaBrowser.Movies/Entities/Movie.cs b/MediaBrowser.Movies/Entities/Movie.cs index 2c44e7917e..585b5b7773 100644 --- a/MediaBrowser.Movies/Entities/Movie.cs +++ b/MediaBrowser.Movies/Entities/Movie.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -using MediaBrowser.Model.Entities; using System.Runtime.Serialization; +using MediaBrowser.Model.Entities; namespace MediaBrowser.Movies.Entities { diff --git a/MediaBrowser.Movies/Metadata/MovieXmlParser.cs b/MediaBrowser.Movies/Metadata/MovieXmlParser.cs index d8bbb49cbf..67650fa985 100644 --- a/MediaBrowser.Movies/Metadata/MovieXmlParser.cs +++ b/MediaBrowser.Movies/Metadata/MovieXmlParser.cs @@ -17,7 +17,7 @@ namespace MediaBrowser.Movies.Metadata case "IMDB": case "IMDbId": string IMDbId = reader.ReadElementContentAsString() ?? string.Empty; - if (!string.IsNullOrEmpty(IMDbId)) + if (!string.IsNullOrWhiteSpace(IMDbId)) { item.ImdbId = IMDbId; } diff --git a/MediaBrowser.Common/Net/CollectionExtensions.cs b/MediaBrowser.Net/CollectionExtensions.cs similarity index 89% rename from MediaBrowser.Common/Net/CollectionExtensions.cs rename to MediaBrowser.Net/CollectionExtensions.cs index 98d24dfc04..a6b59904f3 100644 --- a/MediaBrowser.Common/Net/CollectionExtensions.cs +++ b/MediaBrowser.Net/CollectionExtensions.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; -namespace MediaBrowser.Common.Net +namespace MediaBrowser.Net { public static class CollectionExtensions { diff --git a/MediaBrowser.Common/Net/Handlers/BaseEmbeddedResourceHandler.cs b/MediaBrowser.Net/Handlers/BaseEmbeddedResourceHandler.cs similarity index 66% rename from MediaBrowser.Common/Net/Handlers/BaseEmbeddedResourceHandler.cs rename to MediaBrowser.Net/Handlers/BaseEmbeddedResourceHandler.cs index e64773f33f..d7f579d05a 100644 --- a/MediaBrowser.Common/Net/Handlers/BaseEmbeddedResourceHandler.cs +++ b/MediaBrowser.Net/Handlers/BaseEmbeddedResourceHandler.cs @@ -1,23 +1,14 @@ -using System.IO; -using System.IO.Compression; -using System; +using System; +using System.IO; -namespace MediaBrowser.Common.Net.Handlers +namespace MediaBrowser.Net.Handlers { - public abstract class BaseEmbeddedResourceHandler : Response + public abstract class BaseEmbeddedResourceHandler : BaseHandler { - public BaseEmbeddedResourceHandler(RequestContext ctx, string resourcePath) - : base(ctx) + public BaseEmbeddedResourceHandler(string resourcePath) + : base() { ResourcePath = resourcePath; - - Headers["Content-Encoding"] = "gzip"; - - WriteStream = s => - { - WriteReponse(s); - s.Close(); - }; } protected string ResourcePath { get; set; } @@ -57,12 +48,9 @@ namespace MediaBrowser.Common.Net.Handlers } } - private void WriteReponse(Stream stream) + protected override void WriteResponseToOutputStream(Stream stream) { - using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Compress, false)) - { - GetEmbeddedResourceStream().CopyTo(gzipStream); - } + GetEmbeddedResourceStream().CopyTo(stream); } protected abstract Stream GetEmbeddedResourceStream(); diff --git a/MediaBrowser.Net/Handlers/BaseHandler.cs b/MediaBrowser.Net/Handlers/BaseHandler.cs new file mode 100644 index 0000000000..7a2bcffe97 --- /dev/null +++ b/MediaBrowser.Net/Handlers/BaseHandler.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.IO; +using System.IO.Compression; + +namespace MediaBrowser.Net.Handlers +{ + public abstract class BaseHandler + { + /// + /// Response headers + /// + public IDictionary Headers = new Dictionary(); + + /// + /// The action to write the response to the output stream + /// + public Action WriteStream { get; set; } + + /// + /// The original RequestContext + /// + public RequestContext RequestContext { get; set; } + + /// + /// The original QueryString + /// + protected NameValueCollection QueryString + { + get + { + return RequestContext.Request.QueryString; + } + } + + /// + /// Gets the MIME type to include in the response headers + /// + public abstract string ContentType { get; } + + /// + /// Gets the status code to include in the response headers + /// + public virtual int StatusCode + { + get + { + return 200; + } + } + + /// + /// Gets the cache duration to include in the response headers + /// + public virtual TimeSpan CacheDuration + { + get + { + return TimeSpan.FromTicks(0); + } + } + + /// + /// Gets the last date modified of the content being returned, if this can be determined. + /// This will be used to invalidate the cache, so it's not needed if CacheDuration is 0. + /// + public virtual DateTime? LastDateModified + { + get + { + return null; + } + } + + public virtual bool GzipResponse + { + get + { + return true; + } + } + + public BaseHandler() + { + WriteStream = s => + { + WriteReponse(s); + s.Close(); + }; + } + + private void WriteReponse(Stream stream) + { + if (GzipResponse) + { + using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Compress, false)) + { + WriteResponseToOutputStream(gzipStream); + } + } + else + { + WriteResponseToOutputStream(stream); + } + } + + protected abstract void WriteResponseToOutputStream(Stream stream); + + } +} \ No newline at end of file diff --git a/MediaBrowser.Net/Handlers/BaseJsonHandler.cs b/MediaBrowser.Net/Handlers/BaseJsonHandler.cs new file mode 100644 index 0000000000..725b89c32e --- /dev/null +++ b/MediaBrowser.Net/Handlers/BaseJsonHandler.cs @@ -0,0 +1,11 @@ + +namespace MediaBrowser.Net.Handlers +{ + public abstract class BaseJsonHandler : BaseHandler + { + public override string ContentType + { + get { return "application/json"; } + } + } +} diff --git a/MediaBrowser.Common/Net/HttpServer.cs b/MediaBrowser.Net/HttpServer.cs similarity index 94% rename from MediaBrowser.Common/Net/HttpServer.cs rename to MediaBrowser.Net/HttpServer.cs index fad8d13eb9..aa24538d05 100644 --- a/MediaBrowser.Common/Net/HttpServer.cs +++ b/MediaBrowser.Net/HttpServer.cs @@ -2,7 +2,7 @@ using System; using System.Net; using System.Reactive.Linq; -namespace MediaBrowser.Common.Net +namespace MediaBrowser.Net { public class HttpServer : IObservable, IDisposable { diff --git a/MediaBrowser.Net/MediaBrowser.Net.csproj b/MediaBrowser.Net/MediaBrowser.Net.csproj new file mode 100644 index 0000000000..6f1b7cccfe --- /dev/null +++ b/MediaBrowser.Net/MediaBrowser.Net.csproj @@ -0,0 +1,66 @@ + + + + + Debug + AnyCPU + {5DA08D1C-0D52-4B1B-AA66-E4A171D938F6} + Library + Properties + MediaBrowser.Net + MediaBrowser.Net + v4.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + ..\packages\Rx-Main.1.0.11226\lib\Net4\System.Reactive.dll + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MediaBrowser.Net/Properties/AssemblyInfo.cs b/MediaBrowser.Net/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..00964b6a26 --- /dev/null +++ b/MediaBrowser.Net/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("MediaBrowser.Net")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("MediaBrowser.Net")] +[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("eacc40b5-e24e-4467-8000-f40874048d45")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/MediaBrowser.Common/Net/Request.cs b/MediaBrowser.Net/Request.cs similarity index 89% rename from MediaBrowser.Common/Net/Request.cs rename to MediaBrowser.Net/Request.cs index 795c9c36ba..43f854233e 100644 --- a/MediaBrowser.Common/Net/Request.cs +++ b/MediaBrowser.Net/Request.cs @@ -2,7 +2,7 @@ using System.IO; using System.Linq; -namespace MediaBrowser.Common.Net +namespace MediaBrowser.Net { public class Request { diff --git a/MediaBrowser.Common/Net/RequestContext.cs b/MediaBrowser.Net/RequestContext.cs similarity index 90% rename from MediaBrowser.Common/Net/RequestContext.cs rename to MediaBrowser.Net/RequestContext.cs index d3635f34a5..4c1350701c 100644 --- a/MediaBrowser.Common/Net/RequestContext.cs +++ b/MediaBrowser.Net/RequestContext.cs @@ -1,8 +1,9 @@ using System; using System.Linq; using System.Net; +using MediaBrowser.Net.Handlers; -namespace MediaBrowser.Common.Net +namespace MediaBrowser.Net { public class RequestContext { @@ -23,7 +24,7 @@ namespace MediaBrowser.Common.Net Request = context.Request; } - public void Respond(Response handler) + public void Respond(BaseHandler handler) { Response.AddHeader("Access-Control-Allow-Origin", "*"); @@ -58,6 +59,11 @@ namespace MediaBrowser.Common.Net if (statusCode != 304) { + if (handler.GzipResponse) + { + Response.AddHeader("Content-Encoding", "gzip"); + } + if (cacheDuration.Ticks > 0) { CacheResponse(Response, cacheDuration, handler.LastDateModified); diff --git a/MediaBrowser.Common/Net/StreamExtensions.cs b/MediaBrowser.Net/StreamExtensions.cs similarity index 90% rename from MediaBrowser.Common/Net/StreamExtensions.cs rename to MediaBrowser.Net/StreamExtensions.cs index c10e458ada..b4925cc7fd 100644 --- a/MediaBrowser.Common/Net/StreamExtensions.cs +++ b/MediaBrowser.Net/StreamExtensions.cs @@ -2,7 +2,7 @@ using System; using System.IO; using System.Reactive.Linq; -namespace MediaBrowser.Common.Net +namespace MediaBrowser.Net { public static class StreamExtensions { diff --git a/MediaBrowser.Net/packages.config b/MediaBrowser.Net/packages.config new file mode 100644 index 0000000000..47102a263f --- /dev/null +++ b/MediaBrowser.Net/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/MediaBrowser.TV/Entities/Episode.cs b/MediaBrowser.TV/Entities/Episode.cs index 9838e939b1..aa3227a77d 100644 --- a/MediaBrowser.TV/Entities/Episode.cs +++ b/MediaBrowser.TV/Entities/Episode.cs @@ -1,13 +1,9 @@ -using System; -using System.Collections.Generic; -using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Entities; namespace MediaBrowser.TV.Entities { public class Episode : Video { public string SeasonNumber { get; set; } - public string EpisodeNumber { get; set; } - public DateTime? FirstAired { get; set; } } } diff --git a/MediaBrowser.TV/Entities/Series.cs b/MediaBrowser.TV/Entities/Series.cs index 0034c9fe5b..f63580314c 100644 --- a/MediaBrowser.TV/Entities/Series.cs +++ b/MediaBrowser.TV/Entities/Series.cs @@ -1,12 +1,10 @@ -using System; -using System.Collections.Generic; -using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Entities; namespace MediaBrowser.TV.Entities { public class Series : Folder { - public string TVDBSeriesId { get; set; } + public string TvdbId { get; set; } public string Status { get; set; } } } diff --git a/MediaBrowser.TV/Metadata/EpisodeXmlParser.cs b/MediaBrowser.TV/Metadata/EpisodeXmlParser.cs index 1c68580b15..7df64b405b 100644 --- a/MediaBrowser.TV/Metadata/EpisodeXmlParser.cs +++ b/MediaBrowser.TV/Metadata/EpisodeXmlParser.cs @@ -16,7 +16,7 @@ namespace MediaBrowser.TV.Metadata { string filename = reader.ReadElementContentAsString(); - if (!string.IsNullOrEmpty(filename)) + if (!string.IsNullOrWhiteSpace(filename)) { string metadataFolder = Path.GetDirectoryName(item.Path); item.PrimaryImagePath = Path.Combine(metadataFolder, filename); @@ -24,7 +24,12 @@ namespace MediaBrowser.TV.Metadata break; } case "EpisodeNumber": - item.EpisodeNumber = reader.ReadElementContentAsString() ?? string.Empty; + string number = reader.ReadElementContentAsString() ?? string.Empty; + + if (!string.IsNullOrWhiteSpace(number)) + { + item.IndexNumber = int.Parse(number); + } break; case "SeasonNumber": @@ -39,13 +44,13 @@ namespace MediaBrowser.TV.Metadata { string firstAired = reader.ReadElementContentAsString() ?? string.Empty; - if (!string.IsNullOrEmpty(firstAired)) + if (!string.IsNullOrWhiteSpace(firstAired)) { DateTime airDate; if (DateTime.TryParse(firstAired, out airDate) && airDate.Year > 1850) { - item.FirstAired = airDate; + item.PremiereDate = airDate; item.ProductionYear = airDate.Year; } } diff --git a/MediaBrowser.TV/Metadata/SeriesXmlParser.cs b/MediaBrowser.TV/Metadata/SeriesXmlParser.cs index f4c0719008..9fdf1e7ca4 100644 --- a/MediaBrowser.TV/Metadata/SeriesXmlParser.cs +++ b/MediaBrowser.TV/Metadata/SeriesXmlParser.cs @@ -12,7 +12,7 @@ namespace MediaBrowser.TV.Metadata switch (reader.Name) { case "id": - item.TVDBSeriesId = reader.ReadElementContentAsString() ?? string.Empty; + item.TvdbId = reader.ReadElementContentAsString() ?? string.Empty; break; case "SeriesName": @@ -26,7 +26,7 @@ namespace MediaBrowser.TV.Metadata case "Runtime": { string text = reader.ReadElementContentAsString() ?? string.Empty; - if (!string.IsNullOrEmpty(text)) + if (!string.IsNullOrWhiteSpace(text)) { int runtime; diff --git a/MediaBrowser.sln b/MediaBrowser.sln index 6f94baf31d..23e78b42f9 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -21,6 +21,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Common", "Medi EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Model", "MediaBrowser.Model\MediaBrowser.Model.csproj", "{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Net", "MediaBrowser.Net\MediaBrowser.Net.csproj", "{5DA08D1C-0D52-4B1B-AA66-E4A171D938F6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -43,6 +45,10 @@ Global {5758B2C7-949A-421D-B268-70A950CF8741}.Debug|Any CPU.Build.0 = Debug|Any CPU {5758B2C7-949A-421D-B268-70A950CF8741}.Release|Any CPU.ActiveCfg = Release|Any CPU {5758B2C7-949A-421D-B268-70A950CF8741}.Release|Any CPU.Build.0 = Release|Any CPU + {5DA08D1C-0D52-4B1B-AA66-E4A171D938F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5DA08D1C-0D52-4B1B-AA66-E4A171D938F6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5DA08D1C-0D52-4B1B-AA66-E4A171D938F6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5DA08D1C-0D52-4B1B-AA66-E4A171D938F6}.Release|Any CPU.Build.0 = Release|Any CPU {78AEA637-AF42-4F43-8E2B-0F2F0E2931F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {78AEA637-AF42-4F43-8E2B-0F2F0E2931F3}.Debug|Any CPU.Build.0 = Debug|Any CPU {78AEA637-AF42-4F43-8E2B-0F2F0E2931F3}.Release|Any CPU.ActiveCfg = Release|Any CPU