mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-07-05 21:33:02 +02:00
a few more async optimizations
This commit is contained in:
parent
1c5f728ec2
commit
fbf8cc833c
|
@ -81,16 +81,16 @@ namespace MediaBrowser.Api
|
||||||
|
|
||||||
dto.UserData = item.GetUserData(user);
|
dto.UserData = item.GetUserData(user);
|
||||||
|
|
||||||
await AttachStudios(dto, item);
|
await AttachStudios(dto, item).ConfigureAwait(false);
|
||||||
|
|
||||||
if (includeChildren)
|
if (includeChildren)
|
||||||
{
|
{
|
||||||
await AttachChildren(dto, item, user);
|
await AttachChildren(dto, item, user).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (includePeople)
|
if (includePeople)
|
||||||
{
|
{
|
||||||
await AttachPeople(dto, item);
|
await AttachPeople(dto, item).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Folder folder = item as Folder;
|
Folder folder = item as Folder;
|
||||||
|
@ -125,7 +125,7 @@ namespace MediaBrowser.Api
|
||||||
// Attach Studios by transforming them into BaseItemStudio (DTO)
|
// Attach Studios by transforming them into BaseItemStudio (DTO)
|
||||||
if (item.Studios != null)
|
if (item.Studios != null)
|
||||||
{
|
{
|
||||||
IEnumerable<Studio> entities = await Task.WhenAll<Studio>(item.Studios.Select(c => Kernel.Instance.ItemController.GetStudio(c)));
|
IEnumerable<Studio> entities = await Task.WhenAll<Studio>(item.Studios.Select(c => Kernel.Instance.ItemController.GetStudio(c))).ConfigureAwait(false);
|
||||||
|
|
||||||
dto.Studios = item.Studios.Select(s =>
|
dto.Studios = item.Studios.Select(s =>
|
||||||
{
|
{
|
||||||
|
@ -153,12 +153,12 @@ namespace MediaBrowser.Api
|
||||||
{
|
{
|
||||||
IEnumerable<BaseItem> children = folder.GetParentalAllowedChildren(user);
|
IEnumerable<BaseItem> children = folder.GetParentalAllowedChildren(user);
|
||||||
|
|
||||||
dto.Children = await Task.WhenAll<DTOBaseItem>(children.Select(c => GetDTOBaseItem(c, user, false, false)));
|
dto.Children = await Task.WhenAll<DTOBaseItem>(children.Select(c => GetDTOBaseItem(c, user, false, false))).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.LocalTrailers != null && item.LocalTrailers.Any())
|
if (item.LocalTrailers != null && item.LocalTrailers.Any())
|
||||||
{
|
{
|
||||||
dto.LocalTrailers = await Task.WhenAll<DTOBaseItem>(item.LocalTrailers.Select(c => GetDTOBaseItem(c, user, false, false)));
|
dto.LocalTrailers = await Task.WhenAll<DTOBaseItem>(item.LocalTrailers.Select(c => GetDTOBaseItem(c, user, false, false))).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ namespace MediaBrowser.Api
|
||||||
// Attach People by transforming them into BaseItemPerson (DTO)
|
// Attach People by transforming them into BaseItemPerson (DTO)
|
||||||
if (item.People != null)
|
if (item.People != null)
|
||||||
{
|
{
|
||||||
IEnumerable<Person> entities = await Task.WhenAll<Person>(item.People.Select(c => Kernel.Instance.ItemController.GetPerson(c.Name)));
|
IEnumerable<Person> entities = await Task.WhenAll<Person>(item.People.Select(c => Kernel.Instance.ItemController.GetPerson(c.Name))).ConfigureAwait(false);
|
||||||
|
|
||||||
dto.People = item.People.Select(p =>
|
dto.People = item.People.Select(p =>
|
||||||
{
|
{
|
||||||
|
|
|
@ -92,10 +92,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
|
|
||||||
public override Task<string> GetContentType()
|
public override Task<string> GetContentType()
|
||||||
{
|
{
|
||||||
return Task.Run(() =>
|
return Task.FromResult<string>(MimeTypes.GetMimeType("." + GetConversionOutputFormat()));
|
||||||
{
|
|
||||||
return MimeTypes.GetMimeType("." + GetConversionOutputFormat());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool ShouldCompressResponse(string contentType)
|
public override bool ShouldCompressResponse(string contentType)
|
||||||
|
@ -103,17 +100,17 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task ProcessRequest(HttpListenerContext ctx)
|
public override Task ProcessRequest(HttpListenerContext ctx)
|
||||||
{
|
{
|
||||||
HttpListenerContext = ctx;
|
HttpListenerContext = ctx;
|
||||||
|
|
||||||
if (!RequiresConversion())
|
if (!RequiresConversion())
|
||||||
{
|
{
|
||||||
await new StaticFileHandler() { Path = LibraryItem.Path }.ProcessRequest(ctx);
|
return new StaticFileHandler() { Path = LibraryItem.Path }.ProcessRequest(ctx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await base.ProcessRequest(ctx);
|
return base.ProcessRequest(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,15 +177,15 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
// If we ever decide to disable the ffmpeg log then you must uncomment the below line.
|
// If we ever decide to disable the ffmpeg log then you must uncomment the below line.
|
||||||
//process.BeginErrorReadLine();
|
//process.BeginErrorReadLine();
|
||||||
|
|
||||||
Task debugLogTask = Task.Run(async () => { await process.StandardError.BaseStream.CopyToAsync(logStream); });
|
Task debugLogTask = process.StandardError.BaseStream.CopyToAsync(logStream);
|
||||||
|
|
||||||
await process.StandardOutput.BaseStream.CopyToAsync(stream);
|
await process.StandardOutput.BaseStream.CopyToAsync(stream).ConfigureAwait(false);
|
||||||
|
|
||||||
process.WaitForExit();
|
process.WaitForExit();
|
||||||
|
|
||||||
Logger.LogInfo("FFMpeg exited with code " + process.ExitCode);
|
Logger.LogInfo("FFMpeg exited with code " + process.ExitCode);
|
||||||
|
|
||||||
await debugLogTask;
|
await debugLogTask.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GenreHandler : BaseJsonHandler<IBNItem<Genre>>
|
public class GenreHandler : BaseJsonHandler<IBNItem<Genre>>
|
||||||
{
|
{
|
||||||
protected override async Task<IBNItem<Genre>> GetObjectToSerialize()
|
protected override Task<IBNItem<Genre>> GetObjectToSerialize()
|
||||||
{
|
{
|
||||||
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
||||||
Guid userId = Guid.Parse(QueryString["userid"]);
|
Guid userId = Guid.Parse(QueryString["userid"]);
|
||||||
|
@ -22,7 +22,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
|
|
||||||
string name = QueryString["name"];
|
string name = QueryString["name"];
|
||||||
|
|
||||||
return await GetGenre(parent, user, name);
|
return GetGenre(parent, user, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -46,7 +46,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
// Get the original entity so that we can also supply the PrimaryImagePath
|
// Get the original entity so that we can also supply the PrimaryImagePath
|
||||||
return new IBNItem<Genre>()
|
return new IBNItem<Genre>()
|
||||||
{
|
{
|
||||||
Item = await Kernel.Instance.ItemController.GetGenre(name),
|
Item = await Kernel.Instance.ItemController.GetGenre(name).ConfigureAwait(false),
|
||||||
BaseItemCount = count
|
BaseItemCount = count
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,13 +11,13 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
public class GenresHandler : BaseJsonHandler<IEnumerable<IBNItem<Genre>>>
|
public class GenresHandler : BaseJsonHandler<IEnumerable<IBNItem<Genre>>>
|
||||||
{
|
{
|
||||||
protected override async Task<IEnumerable<IBNItem<Genre>>> GetObjectToSerialize()
|
protected override Task<IEnumerable<IBNItem<Genre>>> GetObjectToSerialize()
|
||||||
{
|
{
|
||||||
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
||||||
Guid userId = Guid.Parse(QueryString["userid"]);
|
Guid userId = Guid.Parse(QueryString["userid"]);
|
||||||
User user = Kernel.Instance.Users.First(u => u.Id == userId);
|
User user = Kernel.Instance.Users.First(u => u.Id == userId);
|
||||||
|
|
||||||
return await GetAllGenres(parent, user);
|
return GetAllGenres(parent, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -53,7 +53,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<Genre> entities = await Task.WhenAll<Genre>(data.Keys.Select(key => { return Kernel.Instance.ItemController.GetGenre(key); }));
|
IEnumerable<Genre> entities = await Task.WhenAll<Genre>(data.Keys.Select(key => { return Kernel.Instance.ItemController.GetGenre(key); })).ConfigureAwait(false);
|
||||||
|
|
||||||
return entities.Select(e => new IBNItem<Genre>() { Item = e, BaseItemCount = data[e.Name] });
|
return entities.Select(e => new IBNItem<Genre>() { Item = e, BaseItemCount = data[e.Name] });
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,28 +29,28 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(personName))
|
if (!string.IsNullOrEmpty(personName))
|
||||||
{
|
{
|
||||||
return (await Kernel.Instance.ItemController.GetPerson(personName)).PrimaryImagePath;
|
return (await Kernel.Instance.ItemController.GetPerson(personName).ConfigureAwait(false)).PrimaryImagePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
string genreName = QueryString["genre"];
|
string genreName = QueryString["genre"];
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(genreName))
|
if (!string.IsNullOrEmpty(genreName))
|
||||||
{
|
{
|
||||||
return (await Kernel.Instance.ItemController.GetGenre(genreName)).PrimaryImagePath;
|
return (await Kernel.Instance.ItemController.GetGenre(genreName).ConfigureAwait(false)).PrimaryImagePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
string year = QueryString["year"];
|
string year = QueryString["year"];
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(year))
|
if (!string.IsNullOrEmpty(year))
|
||||||
{
|
{
|
||||||
return (await Kernel.Instance.ItemController.GetYear(int.Parse(year))).PrimaryImagePath;
|
return (await Kernel.Instance.ItemController.GetYear(int.Parse(year)).ConfigureAwait(false)).PrimaryImagePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
string studio = QueryString["studio"];
|
string studio = QueryString["studio"];
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(studio))
|
if (!string.IsNullOrEmpty(studio))
|
||||||
{
|
{
|
||||||
return (await Kernel.Instance.ItemController.GetStudio(studio)).PrimaryImagePath;
|
return (await Kernel.Instance.ItemController.GetStudio(studio).ConfigureAwait(false)).PrimaryImagePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseItem item = ApiService.GetItemById(QueryString["id"]);
|
BaseItem item = ApiService.GetItemById(QueryString["id"]);
|
||||||
|
@ -64,7 +64,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
private Stream _SourceStream = null;
|
private Stream _SourceStream = null;
|
||||||
private async Task<Stream> GetSourceStream()
|
private async Task<Stream> GetSourceStream()
|
||||||
{
|
{
|
||||||
await EnsureSourceStream();
|
await EnsureSourceStream().ConfigureAwait(false);
|
||||||
return _SourceStream;
|
return _SourceStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_SourceStream = File.OpenRead(await GetImagePath());
|
_SourceStream = File.OpenRead(await GetImagePath().ConfigureAwait(false));
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException ex)
|
catch (FileNotFoundException ex)
|
||||||
{
|
{
|
||||||
|
@ -101,14 +101,14 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
|
|
||||||
public async override Task<string> GetContentType()
|
public async override Task<string> GetContentType()
|
||||||
{
|
{
|
||||||
await EnsureSourceStream();
|
await EnsureSourceStream().ConfigureAwait(false);
|
||||||
|
|
||||||
if (await GetSourceStream() == null)
|
if (await GetSourceStream().ConfigureAwait(false) == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MimeTypes.GetMimeType(await GetImagePath());
|
return MimeTypes.GetMimeType(await GetImagePath().ConfigureAwait(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override TimeSpan CacheDuration
|
public override TimeSpan CacheDuration
|
||||||
|
@ -121,14 +121,14 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
|
|
||||||
protected async override Task<DateTime?> GetLastDateModified()
|
protected async override Task<DateTime?> GetLastDateModified()
|
||||||
{
|
{
|
||||||
await EnsureSourceStream();
|
await EnsureSourceStream().ConfigureAwait(false);
|
||||||
|
|
||||||
if (await GetSourceStream() == null)
|
if (await GetSourceStream().ConfigureAwait(false) == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return File.GetLastWriteTime(await GetImagePath());
|
return File.GetLastWriteTime(await GetImagePath().ConfigureAwait(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
private int? Height
|
private int? Height
|
||||||
|
@ -223,7 +223,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
|
|
||||||
protected override async Task WriteResponseToOutputStream(Stream stream)
|
protected override async Task WriteResponseToOutputStream(Stream stream)
|
||||||
{
|
{
|
||||||
ImageProcessor.ProcessImage(await GetSourceStream(), stream, Width, Height, MaxWidth, MaxHeight, Quality);
|
ImageProcessor.ProcessImage(await GetSourceStream().ConfigureAwait(false), stream, Width, Height, MaxWidth, MaxHeight, Quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetImagePathFromTypes(BaseItem item, ImageType imageType, int imageIndex)
|
private string GetImagePathFromTypes(BaseItem item, ImageType imageType, int imageIndex)
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
public class ItemHandler : BaseJsonHandler<DTOBaseItem>
|
public class ItemHandler : BaseJsonHandler<DTOBaseItem>
|
||||||
{
|
{
|
||||||
protected async override Task<DTOBaseItem> GetObjectToSerialize()
|
protected override Task<DTOBaseItem> GetObjectToSerialize()
|
||||||
{
|
{
|
||||||
Guid userId = Guid.Parse(QueryString["userid"]);
|
Guid userId = Guid.Parse(QueryString["userid"]);
|
||||||
User user = Kernel.Instance.Users.First(u => u.Id == userId);
|
User user = Kernel.Instance.Users.First(u => u.Id == userId);
|
||||||
|
@ -22,7 +22,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await ApiService.GetDTOBaseItem(item, user);
|
return ApiService.GetDTOBaseItem(item, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual BaseItem ItemToSerialize
|
protected virtual BaseItem ItemToSerialize
|
||||||
|
|
|
@ -9,13 +9,13 @@ using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
namespace MediaBrowser.Api.HttpHandlers
|
namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
public class ItemListHandler : BaseJsonHandler<IEnumerable<DTOBaseItem>>
|
public class ItemListHandler : BaseJsonHandler<DTOBaseItem[]>
|
||||||
{
|
{
|
||||||
protected override async Task<IEnumerable<DTOBaseItem>> GetObjectToSerialize()
|
protected override Task<DTOBaseItem[]> GetObjectToSerialize()
|
||||||
{
|
{
|
||||||
User user = Kernel.Instance.Users.First(u => u.Id == UserId);
|
User user = Kernel.Instance.Users.First(u => u.Id == UserId);
|
||||||
|
|
||||||
return await Task.WhenAll<DTOBaseItem>(ItemsToSerialize.Select(i =>
|
return Task.WhenAll<DTOBaseItem>(ItemsToSerialize.Select(i =>
|
||||||
{
|
{
|
||||||
return ApiService.GetDTOBaseItem(i, user, includeChildren: false, includePeople: false);
|
return ApiService.GetDTOBaseItem(i, user, includeChildren: false, includePeople: false);
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PersonHandler : BaseJsonHandler<IBNItem<Person>>
|
public class PersonHandler : BaseJsonHandler<IBNItem<Person>>
|
||||||
{
|
{
|
||||||
protected async override Task<IBNItem<Person>> GetObjectToSerialize()
|
protected override Task<IBNItem<Person>> GetObjectToSerialize()
|
||||||
{
|
{
|
||||||
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
||||||
Guid userId = Guid.Parse(QueryString["userid"]);
|
Guid userId = Guid.Parse(QueryString["userid"]);
|
||||||
|
@ -22,7 +22,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
|
|
||||||
string name = QueryString["name"];
|
string name = QueryString["name"];
|
||||||
|
|
||||||
return await GetPerson(parent, user, name);
|
return GetPerson(parent, user, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -46,7 +46,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
// Get the original entity so that we can also supply the PrimaryImagePath
|
// Get the original entity so that we can also supply the PrimaryImagePath
|
||||||
return new IBNItem<Person>()
|
return new IBNItem<Person>()
|
||||||
{
|
{
|
||||||
Item = await Kernel.Instance.ItemController.GetPerson(name),
|
Item = await Kernel.Instance.ItemController.GetPerson(name).ConfigureAwait(false),
|
||||||
BaseItemCount = count
|
BaseItemCount = count
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,12 +11,11 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
protected override Task<BasePluginConfiguration> GetObjectToSerialize()
|
protected override Task<BasePluginConfiguration> GetObjectToSerialize()
|
||||||
{
|
{
|
||||||
return Task.Run(() =>
|
string pluginName = QueryString["name"];
|
||||||
{
|
|
||||||
string pluginName = QueryString["name"];
|
|
||||||
|
|
||||||
return Kernel.Instance.Plugins.First(p => p.Name.Equals(pluginName, StringComparison.OrdinalIgnoreCase)).Configuration;
|
BasePluginConfiguration config = Kernel.Instance.Plugins.First(p => p.Name.Equals(pluginName, StringComparison.OrdinalIgnoreCase)).Configuration;
|
||||||
});
|
|
||||||
|
return Task.FromResult<BasePluginConfiguration>(config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,27 +14,24 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
protected override Task<IEnumerable<PluginInfo>> GetObjectToSerialize()
|
protected override Task<IEnumerable<PluginInfo>> GetObjectToSerialize()
|
||||||
{
|
{
|
||||||
return Task.Run(() =>
|
var plugins = Kernel.Instance.Plugins.Select(p =>
|
||||||
{
|
{
|
||||||
var plugins = Kernel.Instance.Plugins.Select(p =>
|
return new PluginInfo()
|
||||||
{
|
{
|
||||||
return new PluginInfo()
|
Path = p.Path,
|
||||||
{
|
Name = p.Name,
|
||||||
Path = p.Path,
|
Enabled = p.Enabled,
|
||||||
Name = p.Name,
|
DownloadToUI = p.DownloadToUI,
|
||||||
Enabled = p.Enabled,
|
Version = p.Version
|
||||||
DownloadToUI = p.DownloadToUI,
|
};
|
||||||
Version = p.Version
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
if (QueryString["uionly"] == "1")
|
|
||||||
{
|
|
||||||
plugins = plugins.Where(p => p.DownloadToUI);
|
|
||||||
}
|
|
||||||
|
|
||||||
return plugins;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (QueryString["uionly"] == "1")
|
||||||
|
{
|
||||||
|
plugins = plugins.Where(p => p.DownloadToUI);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.FromResult<IEnumerable<PluginInfo>>(plugins);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class StudioHandler : BaseJsonHandler<IBNItem<Studio>>
|
public class StudioHandler : BaseJsonHandler<IBNItem<Studio>>
|
||||||
{
|
{
|
||||||
protected async override Task<IBNItem<Studio>> GetObjectToSerialize()
|
protected override Task<IBNItem<Studio>> GetObjectToSerialize()
|
||||||
{
|
{
|
||||||
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
||||||
Guid userId = Guid.Parse(QueryString["userid"]);
|
Guid userId = Guid.Parse(QueryString["userid"]);
|
||||||
|
@ -22,7 +22,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
|
|
||||||
string name = QueryString["name"];
|
string name = QueryString["name"];
|
||||||
|
|
||||||
return await GetStudio(parent, user, name);
|
return GetStudio(parent, user, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -46,7 +46,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
// Get the original entity so that we can also supply the PrimaryImagePath
|
// Get the original entity so that we can also supply the PrimaryImagePath
|
||||||
return new IBNItem<Studio>()
|
return new IBNItem<Studio>()
|
||||||
{
|
{
|
||||||
Item = await Kernel.Instance.ItemController.GetStudio(name),
|
Item = await Kernel.Instance.ItemController.GetStudio(name).ConfigureAwait(false),
|
||||||
BaseItemCount = count
|
BaseItemCount = count
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,13 +11,13 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
public class StudiosHandler : BaseJsonHandler<IEnumerable<IBNItem<Studio>>>
|
public class StudiosHandler : BaseJsonHandler<IEnumerable<IBNItem<Studio>>>
|
||||||
{
|
{
|
||||||
protected override async Task<IEnumerable<IBNItem<Studio>>> GetObjectToSerialize()
|
protected override Task<IEnumerable<IBNItem<Studio>>> GetObjectToSerialize()
|
||||||
{
|
{
|
||||||
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
||||||
Guid userId = Guid.Parse(QueryString["userid"]);
|
Guid userId = Guid.Parse(QueryString["userid"]);
|
||||||
User user = Kernel.Instance.Users.First(u => u.Id == userId);
|
User user = Kernel.Instance.Users.First(u => u.Id == userId);
|
||||||
|
|
||||||
return await GetAllStudios(parent, user);
|
return GetAllStudios(parent, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -53,7 +53,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<Studio> entities = await Task.WhenAll<Studio>(data.Keys.Select(key => { return Kernel.Instance.ItemController.GetStudio(key); }));
|
IEnumerable<Studio> entities = await Task.WhenAll<Studio>(data.Keys.Select(key => { return Kernel.Instance.ItemController.GetStudio(key); })).ConfigureAwait(false);
|
||||||
|
|
||||||
return entities.Select(e => new IBNItem<Studio>() { Item = e, BaseItemCount = data[e.Name] });
|
return entities.Select(e => new IBNItem<Studio>() { Item = e, BaseItemCount = data[e.Name] });
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
protected override Task<IEnumerable<User>> GetObjectToSerialize()
|
protected override Task<IEnumerable<User>> GetObjectToSerialize()
|
||||||
{
|
{
|
||||||
return Task.Run(() =>
|
return Task.FromResult<IEnumerable<User>>(Kernel.Instance.Users);
|
||||||
{
|
|
||||||
return Kernel.Instance.Users;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class YearHandler : BaseJsonHandler<IBNItem<Year>>
|
public class YearHandler : BaseJsonHandler<IBNItem<Year>>
|
||||||
{
|
{
|
||||||
protected override async Task<IBNItem<Year>> GetObjectToSerialize()
|
protected override Task<IBNItem<Year>> GetObjectToSerialize()
|
||||||
{
|
{
|
||||||
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
||||||
Guid userId = Guid.Parse(QueryString["userid"]);
|
Guid userId = Guid.Parse(QueryString["userid"]);
|
||||||
|
@ -22,7 +22,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
|
|
||||||
string year = QueryString["year"];
|
string year = QueryString["year"];
|
||||||
|
|
||||||
return await GetYear(parent, user, int.Parse(year));
|
return GetYear(parent, user, int.Parse(year));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -46,7 +46,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
// Get the original entity so that we can also supply the PrimaryImagePath
|
// Get the original entity so that we can also supply the PrimaryImagePath
|
||||||
return new IBNItem<Year>()
|
return new IBNItem<Year>()
|
||||||
{
|
{
|
||||||
Item = await Kernel.Instance.ItemController.GetYear(year),
|
Item = await Kernel.Instance.ItemController.GetYear(year).ConfigureAwait(false),
|
||||||
BaseItemCount = count
|
BaseItemCount = count
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,13 +11,13 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
public class YearsHandler : BaseJsonHandler<IEnumerable<IBNItem<Year>>>
|
public class YearsHandler : BaseJsonHandler<IEnumerable<IBNItem<Year>>>
|
||||||
{
|
{
|
||||||
protected override async Task<IEnumerable<IBNItem<Year>>> GetObjectToSerialize()
|
protected override Task<IEnumerable<IBNItem<Year>>> GetObjectToSerialize()
|
||||||
{
|
{
|
||||||
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
||||||
Guid userId = Guid.Parse(QueryString["userid"]);
|
Guid userId = Guid.Parse(QueryString["userid"]);
|
||||||
User user = Kernel.Instance.Users.First(u => u.Id == userId);
|
User user = Kernel.Instance.Users.First(u => u.Id == userId);
|
||||||
|
|
||||||
return await GetAllYears(parent, user);
|
return GetAllYears(parent, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -50,7 +50,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<Year> entities = await Task.WhenAll<Year>(data.Keys.Select(key => { return Kernel.Instance.ItemController.GetYear(key); }));
|
IEnumerable<Year> entities = await Task.WhenAll<Year>(data.Keys.Select(key => { return Kernel.Instance.ItemController.GetYear(key); })).ConfigureAwait(false);
|
||||||
|
|
||||||
return entities.Select(e => new IBNItem<Year>() { Item = e, BaseItemCount = data[int.Parse(e.Name)] });
|
return entities.Select(e => new IBNItem<Year>() { Item = e, BaseItemCount = data[int.Parse(e.Name)] });
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,13 +22,13 @@ namespace MediaBrowser.Api
|
||||||
{
|
{
|
||||||
var httpServer = Kernel.Instance.HttpServer;
|
var httpServer = Kernel.Instance.HttpServer;
|
||||||
|
|
||||||
httpServer.Where(ctx => ctx.Request.Url.LocalPath.IndexOf("/api/", StringComparison.OrdinalIgnoreCase) != -1).Subscribe(async (ctx) =>
|
httpServer.Where(ctx => ctx.Request.Url.LocalPath.IndexOf("/api/", StringComparison.OrdinalIgnoreCase) != -1).Subscribe((ctx) =>
|
||||||
{
|
{
|
||||||
BaseHandler handler = GetHandler(ctx);
|
BaseHandler handler = GetHandler(ctx);
|
||||||
|
|
||||||
if (handler != null)
|
if (handler != null)
|
||||||
{
|
{
|
||||||
await handler.ProcessRequest(ctx);
|
handler.ProcessRequest(ctx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,9 +152,9 @@ namespace MediaBrowser.ApiInteraction
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets an image stream based on a url
|
/// Gets an image stream based on a url
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<Stream> GetImageStreamAsync(string url)
|
public Task<Stream> GetImageStreamAsync(string url)
|
||||||
{
|
{
|
||||||
return await HttpClient.GetStreamAsync(url);
|
return HttpClient.GetStreamAsync(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -169,7 +169,7 @@ namespace MediaBrowser.ApiInteraction
|
||||||
url += "&id=" + id.ToString();
|
url += "&id=" + id.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromStream<DTOBaseItem>(stream);
|
return JsonSerializer.DeserializeFromStream<DTOBaseItem>(stream);
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ namespace MediaBrowser.ApiInteraction
|
||||||
{
|
{
|
||||||
string url = ApiUrl + "/users";
|
string url = ApiUrl + "/users";
|
||||||
|
|
||||||
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromStream<IEnumerable<User>>(stream);
|
return JsonSerializer.DeserializeFromStream<IEnumerable<User>>(stream);
|
||||||
}
|
}
|
||||||
|
@ -195,7 +195,7 @@ namespace MediaBrowser.ApiInteraction
|
||||||
{
|
{
|
||||||
string url = ApiUrl + "/genres?userId=" + userId.ToString();
|
string url = ApiUrl + "/genres?userId=" + userId.ToString();
|
||||||
|
|
||||||
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromStream<IEnumerable<IBNItem<Genre>>>(stream);
|
return JsonSerializer.DeserializeFromStream<IEnumerable<IBNItem<Genre>>>(stream);
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,7 @@ namespace MediaBrowser.ApiInteraction
|
||||||
{
|
{
|
||||||
string url = ApiUrl + "/years?userId=" + userId.ToString();
|
string url = ApiUrl + "/years?userId=" + userId.ToString();
|
||||||
|
|
||||||
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromStream<IEnumerable<IBNItem<Year>>>(stream);
|
return JsonSerializer.DeserializeFromStream<IEnumerable<IBNItem<Year>>>(stream);
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ namespace MediaBrowser.ApiInteraction
|
||||||
{
|
{
|
||||||
string url = ApiUrl + "/itemlist?listtype=itemswithyear&userId=" + userId.ToString() + "&name=" + name;
|
string url = ApiUrl + "/itemlist?listtype=itemswithyear&userId=" + userId.ToString() + "&name=" + name;
|
||||||
|
|
||||||
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
|
return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ namespace MediaBrowser.ApiInteraction
|
||||||
{
|
{
|
||||||
string url = ApiUrl + "/itemlist?listtype=itemswithgenre&userId=" + userId.ToString() + "&name=" + name;
|
string url = ApiUrl + "/itemlist?listtype=itemswithgenre&userId=" + userId.ToString() + "&name=" + name;
|
||||||
|
|
||||||
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
|
return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,7 @@ namespace MediaBrowser.ApiInteraction
|
||||||
{
|
{
|
||||||
string url = ApiUrl + "/itemlist?listtype=itemswithperson&userId=" + userId.ToString() + "&name=" + name;
|
string url = ApiUrl + "/itemlist?listtype=itemswithperson&userId=" + userId.ToString() + "&name=" + name;
|
||||||
|
|
||||||
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
|
return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
|
||||||
}
|
}
|
||||||
|
@ -262,7 +262,7 @@ namespace MediaBrowser.ApiInteraction
|
||||||
|
|
||||||
url += "&persontype=" + personType;
|
url += "&persontype=" + personType;
|
||||||
|
|
||||||
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
|
return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,7 @@ namespace MediaBrowser.ApiInteraction
|
||||||
{
|
{
|
||||||
string url = ApiUrl + "/studios?userId=" + userId.ToString();
|
string url = ApiUrl + "/studios?userId=" + userId.ToString();
|
||||||
|
|
||||||
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromStream<IEnumerable<IBNItem<Studio>>>(stream);
|
return JsonSerializer.DeserializeFromStream<IEnumerable<IBNItem<Studio>>>(stream);
|
||||||
}
|
}
|
||||||
|
@ -288,7 +288,7 @@ namespace MediaBrowser.ApiInteraction
|
||||||
{
|
{
|
||||||
string url = ApiUrl + "/itemlist?listtype=itemswithstudio&userId=" + userId.ToString() + "&name=" + name;
|
string url = ApiUrl + "/itemlist?listtype=itemswithstudio&userId=" + userId.ToString() + "&name=" + name;
|
||||||
|
|
||||||
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
|
return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
|
||||||
}
|
}
|
||||||
|
@ -301,7 +301,7 @@ namespace MediaBrowser.ApiInteraction
|
||||||
{
|
{
|
||||||
string url = ApiUrl + "/studio?userId=" + userId.ToString() + "&name=" + name;
|
string url = ApiUrl + "/studio?userId=" + userId.ToString() + "&name=" + name;
|
||||||
|
|
||||||
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromStream<IBNItem<Studio>>(stream);
|
return JsonSerializer.DeserializeFromStream<IBNItem<Studio>>(stream);
|
||||||
}
|
}
|
||||||
|
@ -314,7 +314,7 @@ namespace MediaBrowser.ApiInteraction
|
||||||
{
|
{
|
||||||
string url = ApiUrl + "/genre?userId=" + userId.ToString() + "&name=" + name;
|
string url = ApiUrl + "/genre?userId=" + userId.ToString() + "&name=" + name;
|
||||||
|
|
||||||
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromStream<IBNItem<Genre>>(stream);
|
return JsonSerializer.DeserializeFromStream<IBNItem<Genre>>(stream);
|
||||||
}
|
}
|
||||||
|
@ -327,7 +327,7 @@ namespace MediaBrowser.ApiInteraction
|
||||||
{
|
{
|
||||||
string url = ApiUrl + "/person?userId=" + userId.ToString() + "&name=" + name;
|
string url = ApiUrl + "/person?userId=" + userId.ToString() + "&name=" + name;
|
||||||
|
|
||||||
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromStream<IBNItem<Person>>(stream);
|
return JsonSerializer.DeserializeFromStream<IBNItem<Person>>(stream);
|
||||||
}
|
}
|
||||||
|
@ -340,7 +340,7 @@ namespace MediaBrowser.ApiInteraction
|
||||||
{
|
{
|
||||||
string url = ApiUrl + "/year?userId=" + userId.ToString() + "&year=" + year;
|
string url = ApiUrl + "/year?userId=" + userId.ToString() + "&year=" + year;
|
||||||
|
|
||||||
using (Stream stream = await HttpClient.GetStreamAsync(url))
|
using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromStream<IBNItem<Year>>(stream);
|
return JsonSerializer.DeserializeFromStream<IBNItem<Year>>(stream);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System.IO;
|
||||||
using System.IO;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace MediaBrowser.Common.Net.Handlers
|
namespace MediaBrowser.Common.Net.Handlers
|
||||||
|
@ -16,37 +15,7 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
|
|
||||||
public override Task<string> GetContentType()
|
public override Task<string> GetContentType()
|
||||||
{
|
{
|
||||||
return Task.Run(() =>
|
return Task.FromResult<string>(MimeTypes.GetMimeType(ResourcePath));
|
||||||
{
|
|
||||||
string extension = Path.GetExtension(ResourcePath);
|
|
||||||
|
|
||||||
if (extension.EndsWith("jpeg", StringComparison.OrdinalIgnoreCase) || extension.EndsWith("jpg", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return "image/jpeg";
|
|
||||||
}
|
|
||||||
else if (extension.EndsWith("png", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return "image/png";
|
|
||||||
}
|
|
||||||
else if (extension.EndsWith("ico", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return "image/ico";
|
|
||||||
}
|
|
||||||
else if (extension.EndsWith("js", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return "application/x-javascript";
|
|
||||||
}
|
|
||||||
else if (extension.EndsWith("css", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return "text/css";
|
|
||||||
}
|
|
||||||
else if (extension.EndsWith("html", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return "text/html; charset=utf-8";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "text/plain; charset=utf-8";
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Task WriteResponseToOutputStream(Stream stream)
|
protected override Task WriteResponseToOutputStream(Stream stream)
|
||||||
|
|
|
@ -185,11 +185,11 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
// When serving a range request, we need to return status code 206 to indicate a partial response body
|
// When serving a range request, we need to return status code 206 to indicate a partial response body
|
||||||
StatusCode = SupportsByteRangeRequests && IsRangeRequest ? 206 : 200;
|
StatusCode = SupportsByteRangeRequests && IsRangeRequest ? 206 : 200;
|
||||||
|
|
||||||
ctx.Response.ContentType = await GetContentType();
|
ctx.Response.ContentType = await GetContentType().ConfigureAwait(false);
|
||||||
|
|
||||||
TimeSpan cacheDuration = CacheDuration;
|
TimeSpan cacheDuration = CacheDuration;
|
||||||
|
|
||||||
DateTime? lastDateModified = await GetLastDateModified();
|
DateTime? lastDateModified = await GetLastDateModified().ConfigureAwait(false);
|
||||||
|
|
||||||
if (ctx.Request.Headers.AllKeys.Contains("If-Modified-Since"))
|
if (ctx.Request.Headers.AllKeys.Contains("If-Modified-Since"))
|
||||||
{
|
{
|
||||||
|
@ -205,13 +205,13 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await PrepareResponse();
|
await PrepareResponse().ConfigureAwait(false);
|
||||||
|
|
||||||
if (IsResponseValid)
|
if (IsResponseValid)
|
||||||
{
|
{
|
||||||
bool compressResponse = ShouldCompressResponse(ctx.Response.ContentType) && ClientSupportsCompression;
|
bool compressResponse = ShouldCompressResponse(ctx.Response.ContentType) && ClientSupportsCompression;
|
||||||
|
|
||||||
await ProcessUncachedRequest(ctx, compressResponse, cacheDuration, lastDateModified);
|
await ProcessUncachedRequest(ctx, compressResponse, cacheDuration, lastDateModified).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -285,7 +285,7 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
outputStream = CompressedStream;
|
outputStream = CompressedStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
await WriteResponseToOutputStream(outputStream);
|
await WriteResponseToOutputStream(outputStream).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -307,7 +307,7 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual Task PrepareResponse()
|
protected virtual Task PrepareResponse()
|
||||||
{
|
{
|
||||||
return Task.Run(() => { });
|
return Task.FromResult<object>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract Task WriteResponseToOutputStream(Stream stream);
|
protected abstract Task WriteResponseToOutputStream(Stream stream);
|
||||||
|
@ -359,7 +359,7 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
{
|
{
|
||||||
DateTime? value = null;
|
DateTime? value = null;
|
||||||
|
|
||||||
return Task.Run<DateTime?>(() => { return value; });
|
return Task.FromResult<DateTime?>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsResponseValid
|
private bool IsResponseValid
|
||||||
|
|
|
@ -8,10 +8,7 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
{
|
{
|
||||||
public override Task<string> GetContentType()
|
public override Task<string> GetContentType()
|
||||||
{
|
{
|
||||||
return Task.Run(() =>
|
return Task.FromResult<string>(MimeTypes.JsonMimeType);
|
||||||
{
|
|
||||||
return MimeTypes.JsonMimeType;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _ObjectToSerializeEnsured = false;
|
private bool _ObjectToSerializeEnsured = false;
|
||||||
|
@ -21,7 +18,7 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
{
|
{
|
||||||
if (!_ObjectToSerializeEnsured)
|
if (!_ObjectToSerializeEnsured)
|
||||||
{
|
{
|
||||||
_ObjectToSerialize = await GetObjectToSerialize();
|
_ObjectToSerialize = await GetObjectToSerialize().ConfigureAwait(false);
|
||||||
|
|
||||||
if (_ObjectToSerialize == null)
|
if (_ObjectToSerialize == null)
|
||||||
{
|
{
|
||||||
|
@ -34,9 +31,9 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
|
|
||||||
protected abstract Task<T> GetObjectToSerialize();
|
protected abstract Task<T> GetObjectToSerialize();
|
||||||
|
|
||||||
protected override async Task PrepareResponse()
|
protected override Task PrepareResponse()
|
||||||
{
|
{
|
||||||
await EnsureObjectToSerialize();
|
return EnsureObjectToSerialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async override Task WriteResponseToOutputStream(Stream stream)
|
protected async override Task WriteResponseToOutputStream(Stream stream)
|
||||||
|
|
|
@ -102,33 +102,30 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
|
|
||||||
protected override Task<DateTime?> GetLastDateModified()
|
protected override Task<DateTime?> GetLastDateModified()
|
||||||
{
|
{
|
||||||
return Task.Run<DateTime?>(() =>
|
DateTime? value = null;
|
||||||
|
|
||||||
|
EnsureSourceStream();
|
||||||
|
|
||||||
|
if (SourceStream != null)
|
||||||
{
|
{
|
||||||
EnsureSourceStream();
|
value = File.GetLastWriteTime(Path);
|
||||||
|
}
|
||||||
|
|
||||||
if (SourceStream == null)
|
return Task.FromResult<DateTime?>(value);
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return File.GetLastWriteTime(Path);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task<string> GetContentType()
|
public override Task<string> GetContentType()
|
||||||
{
|
{
|
||||||
return Task.Run(() =>
|
return Task.FromResult<string>(MimeTypes.GetMimeType(Path));
|
||||||
{
|
|
||||||
return MimeTypes.GetMimeType(Path);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Task PrepareResponse()
|
protected override Task PrepareResponse()
|
||||||
{
|
{
|
||||||
return Task.Run(() => { EnsureSourceStream(); });
|
EnsureSourceStream();
|
||||||
|
return Task.FromResult<object>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async override Task WriteResponseToOutputStream(Stream stream)
|
protected override Task WriteResponseToOutputStream(Stream stream)
|
||||||
{
|
{
|
||||||
if (IsRangeRequest)
|
if (IsRangeRequest)
|
||||||
{
|
{
|
||||||
|
@ -137,22 +134,22 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
// If the requested range is "0-" and we know the total length, we can optimize by avoiding having to buffer the content into memory
|
// If the requested range is "0-" and we know the total length, we can optimize by avoiding having to buffer the content into memory
|
||||||
if (requestedRange.Value == null && TotalContentLength != null)
|
if (requestedRange.Value == null && TotalContentLength != null)
|
||||||
{
|
{
|
||||||
await ServeCompleteRangeRequest(requestedRange, stream);
|
return ServeCompleteRangeRequest(requestedRange, stream);
|
||||||
}
|
}
|
||||||
else if (TotalContentLength.HasValue)
|
else if (TotalContentLength.HasValue)
|
||||||
{
|
{
|
||||||
// This will have to buffer a portion of the content into memory
|
// This will have to buffer a portion of the content into memory
|
||||||
await ServePartialRangeRequestWithKnownTotalContentLength(requestedRange, stream);
|
return ServePartialRangeRequestWithKnownTotalContentLength(requestedRange, stream);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// This will have to buffer the entire content into memory
|
// This will have to buffer the entire content into memory
|
||||||
await ServePartialRangeRequestWithUnknownTotalContentLength(requestedRange, stream);
|
return ServePartialRangeRequestWithUnknownTotalContentLength(requestedRange, stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await SourceStream.CopyToAsync(stream);
|
return SourceStream.CopyToAsync(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +167,7 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
/// Handles a range request of "bytes=0-"
|
/// Handles a range request of "bytes=0-"
|
||||||
/// This will serve the complete content and add the content-range header
|
/// This will serve the complete content and add the content-range header
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task ServeCompleteRangeRequest(KeyValuePair<long, long?> requestedRange, Stream responseStream)
|
private Task ServeCompleteRangeRequest(KeyValuePair<long, long?> requestedRange, Stream responseStream)
|
||||||
{
|
{
|
||||||
long totalContentLength = TotalContentLength.Value;
|
long totalContentLength = TotalContentLength.Value;
|
||||||
|
|
||||||
|
@ -187,7 +184,7 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
SourceStream.Position = rangeStart;
|
SourceStream.Position = rangeStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
await SourceStream.CopyToAsync(responseStream);
|
return SourceStream.CopyToAsync(responseStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -196,7 +193,7 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
private async Task ServePartialRangeRequestWithUnknownTotalContentLength(KeyValuePair<long, long?> requestedRange, Stream responseStream)
|
private async Task ServePartialRangeRequestWithUnknownTotalContentLength(KeyValuePair<long, long?> requestedRange, Stream responseStream)
|
||||||
{
|
{
|
||||||
// Read the entire stream so that we can determine the length
|
// Read the entire stream so that we can determine the length
|
||||||
byte[] bytes = await ReadBytes(SourceStream, 0, null);
|
byte[] bytes = await ReadBytes(SourceStream, 0, null).ConfigureAwait(false);
|
||||||
|
|
||||||
long totalContentLength = bytes.LongLength;
|
long totalContentLength = bytes.LongLength;
|
||||||
|
|
||||||
|
@ -208,7 +205,7 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
HttpListenerContext.Response.ContentLength64 = rangeLength;
|
HttpListenerContext.Response.ContentLength64 = rangeLength;
|
||||||
HttpListenerContext.Response.Headers["Content-Range"] = string.Format("bytes {0}-{1}/{2}", rangeStart, rangeEnd, totalContentLength);
|
HttpListenerContext.Response.Headers["Content-Range"] = string.Format("bytes {0}-{1}/{2}", rangeStart, rangeEnd, totalContentLength);
|
||||||
|
|
||||||
await responseStream.WriteAsync(bytes, Convert.ToInt32(rangeStart), Convert.ToInt32(rangeLength));
|
await responseStream.WriteAsync(bytes, Convert.ToInt32(rangeStart), Convert.ToInt32(rangeLength)).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -222,14 +219,14 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
long rangeLength = 1 + rangeEnd - rangeStart;
|
long rangeLength = 1 + rangeEnd - rangeStart;
|
||||||
|
|
||||||
// Only read the bytes we need
|
// Only read the bytes we need
|
||||||
byte[] bytes = await ReadBytes(SourceStream, Convert.ToInt32(rangeStart), Convert.ToInt32(rangeLength));
|
byte[] bytes = await ReadBytes(SourceStream, Convert.ToInt32(rangeStart), Convert.ToInt32(rangeLength)).ConfigureAwait(false);
|
||||||
|
|
||||||
// Content-Length is the length of what we're serving, not the original content
|
// Content-Length is the length of what we're serving, not the original content
|
||||||
HttpListenerContext.Response.ContentLength64 = rangeLength;
|
HttpListenerContext.Response.ContentLength64 = rangeLength;
|
||||||
|
|
||||||
HttpListenerContext.Response.Headers["Content-Range"] = string.Format("bytes {0}-{1}/{2}", rangeStart, rangeEnd, totalContentLength);
|
HttpListenerContext.Response.Headers["Content-Range"] = string.Format("bytes {0}-{1}/{2}", rangeStart, rangeEnd, totalContentLength);
|
||||||
|
|
||||||
await responseStream.WriteAsync(bytes, 0, Convert.ToInt32(rangeLength));
|
await responseStream.WriteAsync(bytes, 0, Convert.ToInt32(rangeLength)).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -252,9 +249,9 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
using (MemoryStream ms = new MemoryStream())
|
using (MemoryStream ms = new MemoryStream())
|
||||||
{
|
{
|
||||||
int read;
|
int read;
|
||||||
while ((read = await input.ReadAsync(buffer, 0, buffer.Length)) > 0)
|
while ((read = await input.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false)) > 0)
|
||||||
{
|
{
|
||||||
await ms.WriteAsync(buffer, 0, read);
|
await ms.WriteAsync(buffer, 0, read).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
return ms.ToArray();
|
return ms.ToArray();
|
||||||
}
|
}
|
||||||
|
@ -265,9 +262,9 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
|
|
||||||
using (MemoryStream ms = new MemoryStream())
|
using (MemoryStream ms = new MemoryStream())
|
||||||
{
|
{
|
||||||
int read = await input.ReadAsync(buffer, 0, buffer.Length);
|
int read = await input.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);
|
||||||
|
|
||||||
await ms.WriteAsync(buffer, 0, read);
|
await ms.WriteAsync(buffer, 0, read).ConfigureAwait(false);
|
||||||
|
|
||||||
return ms.ToArray();
|
return ms.ToArray();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,15 +17,15 @@ namespace MediaBrowser.Common.UI
|
||||||
protected abstract IKernel InstantiateKernel();
|
protected abstract IKernel InstantiateKernel();
|
||||||
protected abstract Window InstantiateMainWindow();
|
protected abstract Window InstantiateMainWindow();
|
||||||
|
|
||||||
protected async override void OnStartup(StartupEventArgs e)
|
protected override void OnStartup(StartupEventArgs e)
|
||||||
{
|
{
|
||||||
// Without this the app will shutdown after the splash screen closes
|
// Without this the app will shutdown after the splash screen closes
|
||||||
this.ShutdownMode = ShutdownMode.OnExplicitShutdown;
|
this.ShutdownMode = ShutdownMode.OnExplicitShutdown;
|
||||||
|
|
||||||
await LoadKernel().ConfigureAwait(false);
|
LoadKernel();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task LoadKernel()
|
private async void LoadKernel()
|
||||||
{
|
{
|
||||||
Kernel = InstantiateKernel();
|
Kernel = InstantiateKernel();
|
||||||
|
|
||||||
|
@ -40,9 +40,7 @@ namespace MediaBrowser.Common.UI
|
||||||
|
|
||||||
await Kernel.Init(progress);
|
await Kernel.Init(progress);
|
||||||
|
|
||||||
double seconds = (DateTime.Now - now).TotalSeconds;
|
Logger.LogInfo("Kernel.Init completed in {0} seconds.", (DateTime.Now - now).TotalSeconds);
|
||||||
|
|
||||||
Logger.LogInfo("Kernel.Init completed in {0} seconds.", seconds);
|
|
||||||
splash.Close();
|
splash.Close();
|
||||||
|
|
||||||
this.ShutdownMode = System.Windows.ShutdownMode.OnLastWindowClose;
|
this.ShutdownMode = System.Windows.ShutdownMode.OnLastWindowClose;
|
||||||
|
|
|
@ -18,10 +18,7 @@ namespace MediaBrowser.Controller.FFMpeg
|
||||||
// Use try catch to avoid having to use File.Exists
|
// Use try catch to avoid having to use File.Exists
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (FileStream stream = File.OpenRead(outputCachePath))
|
return GetCachedResult(outputCachePath);
|
||||||
{
|
|
||||||
return JsonSerializer.DeserializeFromStream<FFProbeResult>(stream);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException)
|
catch (FileNotFoundException)
|
||||||
{
|
{
|
||||||
|
@ -29,7 +26,12 @@ namespace MediaBrowser.Controller.FFMpeg
|
||||||
|
|
||||||
await Run(item.Path, outputCachePath).ConfigureAwait(false);
|
await Run(item.Path, outputCachePath).ConfigureAwait(false);
|
||||||
|
|
||||||
using (FileStream stream = File.OpenRead(outputCachePath))
|
return GetCachedResult(item.Path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FFProbeResult GetCachedResult(string path)
|
||||||
|
{
|
||||||
|
using (FileStream stream = File.OpenRead(path))
|
||||||
{
|
{
|
||||||
return JsonSerializer.DeserializeFromStream<FFProbeResult>(stream);
|
return JsonSerializer.DeserializeFromStream<FFProbeResult>(stream);
|
||||||
}
|
}
|
||||||
|
@ -40,10 +42,7 @@ namespace MediaBrowser.Controller.FFMpeg
|
||||||
// Use try catch to avoid having to use File.Exists
|
// Use try catch to avoid having to use File.Exists
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (FileStream stream = File.OpenRead(outputCachePath))
|
return GetCachedResult(outputCachePath);
|
||||||
{
|
|
||||||
return JsonSerializer.DeserializeFromStream<FFProbeResult>(stream);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException)
|
catch (FileNotFoundException)
|
||||||
{
|
{
|
||||||
|
@ -51,10 +50,7 @@ namespace MediaBrowser.Controller.FFMpeg
|
||||||
|
|
||||||
await Run(item.Path, outputCachePath).ConfigureAwait(false);
|
await Run(item.Path, outputCachePath).ConfigureAwait(false);
|
||||||
|
|
||||||
using (FileStream stream = File.OpenRead(outputCachePath))
|
return GetCachedResult(item.Path);
|
||||||
{
|
|
||||||
return JsonSerializer.DeserializeFromStream<FFProbeResult>(stream);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async static Task Run(string input, string output)
|
private async static Task Run(string input, string output)
|
||||||
|
|
|
@ -86,7 +86,7 @@ namespace MediaBrowser.Controller.IO
|
||||||
await ProcessPathChanges(paths).ConfigureAwait(false);
|
await ProcessPathChanges(paths).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ProcessPathChanges(IEnumerable<string> paths)
|
private Task ProcessPathChanges(IEnumerable<string> paths)
|
||||||
{
|
{
|
||||||
List<BaseItem> itemsToRefresh = new List<BaseItem>();
|
List<BaseItem> itemsToRefresh = new List<BaseItem>();
|
||||||
|
|
||||||
|
@ -105,11 +105,11 @@ namespace MediaBrowser.Controller.IO
|
||||||
return folder != null && folder.IsRoot;
|
return folder != null && folder.IsRoot;
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
await Kernel.Instance.ReloadRoot().ConfigureAwait(false);
|
return Kernel.Instance.ReloadRoot();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await Task.WhenAll(itemsToRefresh.Select(i => Kernel.Instance.ReloadItem(i))).ConfigureAwait(false);
|
return Task.WhenAll(itemsToRefresh.Select(i => Kernel.Instance.ReloadItem(i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,21 +68,17 @@ namespace MediaBrowser.Controller
|
||||||
|
|
||||||
public async override Task Init(IProgress<TaskProgress> progress)
|
public async override Task Init(IProgress<TaskProgress> progress)
|
||||||
{
|
{
|
||||||
await Task.Run(async () =>
|
ExtractFFMpeg();
|
||||||
{
|
|
||||||
await base.Init(progress).ConfigureAwait(false);
|
await base.Init(progress).ConfigureAwait(false);
|
||||||
|
|
||||||
progress.Report(new TaskProgress() { Description = "Loading Users", PercentComplete = 15 });
|
progress.Report(new TaskProgress() { Description = "Loading Users", PercentComplete = 15 });
|
||||||
ReloadUsers();
|
ReloadUsers();
|
||||||
|
|
||||||
progress.Report(new TaskProgress() { Description = "Extracting FFMpeg", PercentComplete = 20 });
|
progress.Report(new TaskProgress() { Description = "Loading Media Library", PercentComplete = 25 });
|
||||||
await ExtractFFMpeg().ConfigureAwait(false);
|
await ReloadRoot().ConfigureAwait(false);
|
||||||
|
|
||||||
progress.Report(new TaskProgress() { Description = "Loading Media Library", PercentComplete = 25 });
|
progress.Report(new TaskProgress() { Description = "Loading Complete", PercentComplete = 100 });
|
||||||
await ReloadRoot().ConfigureAwait(false);
|
|
||||||
|
|
||||||
progress.Report(new TaskProgress() { Description = "Loading Complete", PercentComplete = 100 });
|
|
||||||
}).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnComposablePartsLoaded()
|
protected override void OnComposablePartsLoaded()
|
||||||
|
@ -245,22 +241,21 @@ namespace MediaBrowser.Controller
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
await provider.Fetch(item, args).ConfigureAwait(false);
|
await provider.FetchAsync(item, args).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ExtractFFMpeg()
|
||||||
|
{
|
||||||
|
ExtractFFMpeg(ApplicationPaths.FFMpegPath);
|
||||||
|
ExtractFFMpeg(ApplicationPaths.FFProbePath);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Run these during Init.
|
/// Run these during Init.
|
||||||
/// Can't run do this on-demand because there will be multiple workers accessing them at once and we'd have to lock them
|
/// Can't run do this on-demand because there will be multiple workers accessing them at once and we'd have to lock them
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task ExtractFFMpeg()
|
private async void ExtractFFMpeg(string exe)
|
||||||
{
|
|
||||||
// FFMpeg.exe
|
|
||||||
await ExtractFFMpeg(ApplicationPaths.FFMpegPath).ConfigureAwait(false);
|
|
||||||
await ExtractFFMpeg(ApplicationPaths.FFProbePath).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ExtractFFMpeg(string exe)
|
|
||||||
{
|
{
|
||||||
if (File.Exists(exe))
|
if (File.Exists(exe))
|
||||||
{
|
{
|
||||||
|
|
|
@ -116,14 +116,17 @@ namespace MediaBrowser.Controller.Library
|
||||||
|
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
await Kernel.Instance.ExecuteMetadataProviders(item, args);
|
await Kernel.Instance.ExecuteMetadataProviders(item, args).ConfigureAwait(false);
|
||||||
|
|
||||||
var folder = item as Folder;
|
if (item.IsFolder)
|
||||||
|
|
||||||
if (folder != null)
|
|
||||||
{
|
{
|
||||||
// If it's a folder look for child entities
|
// If it's a folder look for child entities
|
||||||
await AttachChildren(folder, fileSystemChildren).ConfigureAwait(false);
|
(item as Folder).Children = (await Task.WhenAll<BaseItem>(GetChildren(item as Folder, fileSystemChildren)).ConfigureAwait(false))
|
||||||
|
.Where(i => i != null).OrderBy(f =>
|
||||||
|
{
|
||||||
|
return string.IsNullOrEmpty(f.SortName) ? f.Name : f.SortName;
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,27 +136,18 @@ namespace MediaBrowser.Controller.Library
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds child BaseItems for a given Folder
|
/// Finds child BaseItems for a given Folder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task AttachChildren(Folder folder, LazyFileInfo[] fileSystemChildren)
|
private Task<BaseItem>[] GetChildren(Folder folder, LazyFileInfo[] fileSystemChildren)
|
||||||
{
|
{
|
||||||
int count = fileSystemChildren.Length;
|
Task<BaseItem>[] tasks = new Task<BaseItem>[fileSystemChildren.Length];
|
||||||
|
|
||||||
Task<BaseItem>[] tasks = new Task<BaseItem>[count];
|
for (int i = 0; i < fileSystemChildren.Length; i++)
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
{
|
{
|
||||||
var child = fileSystemChildren[i];
|
var child = fileSystemChildren[i];
|
||||||
|
|
||||||
tasks[i] = GetItem(child.Path, folder, child.FileInfo);
|
tasks[i] = GetItem(child.Path, folder, child.FileInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseItem[] baseItemChildren = await Task<BaseItem>.WhenAll(tasks).ConfigureAwait(false);
|
return tasks;
|
||||||
|
|
||||||
// Sort them
|
|
||||||
folder.Children = baseItemChildren.Where(i => i != null).OrderBy(f =>
|
|
||||||
{
|
|
||||||
return string.IsNullOrEmpty(f.SortName) ? f.Name : f.SortName;
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -216,41 +210,41 @@ namespace MediaBrowser.Controller.Library
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a Person
|
/// Gets a Person
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<Person> GetPerson(string name)
|
public Task<Person> GetPerson(string name)
|
||||||
{
|
{
|
||||||
string path = Path.Combine(Kernel.Instance.ApplicationPaths.PeoplePath, name);
|
string path = Path.Combine(Kernel.Instance.ApplicationPaths.PeoplePath, name);
|
||||||
|
|
||||||
return await GetImagesByNameItem<Person>(path, name).ConfigureAwait(false);
|
return GetImagesByNameItem<Person>(path, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a Studio
|
/// Gets a Studio
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<Studio> GetStudio(string name)
|
public Task<Studio> GetStudio(string name)
|
||||||
{
|
{
|
||||||
string path = Path.Combine(Kernel.Instance.ApplicationPaths.StudioPath, name);
|
string path = Path.Combine(Kernel.Instance.ApplicationPaths.StudioPath, name);
|
||||||
|
|
||||||
return await GetImagesByNameItem<Studio>(path, name).ConfigureAwait(false);
|
return GetImagesByNameItem<Studio>(path, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a Genre
|
/// Gets a Genre
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<Genre> GetGenre(string name)
|
public Task<Genre> GetGenre(string name)
|
||||||
{
|
{
|
||||||
string path = Path.Combine(Kernel.Instance.ApplicationPaths.GenrePath, name);
|
string path = Path.Combine(Kernel.Instance.ApplicationPaths.GenrePath, name);
|
||||||
|
|
||||||
return await GetImagesByNameItem<Genre>(path, name).ConfigureAwait(false);
|
return GetImagesByNameItem<Genre>(path, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a Year
|
/// Gets a Year
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<Year> GetYear(int value)
|
public Task<Year> GetYear(int value)
|
||||||
{
|
{
|
||||||
string path = Path.Combine(Kernel.Instance.ApplicationPaths.YearPath, value.ToString());
|
string path = Path.Combine(Kernel.Instance.ApplicationPaths.YearPath, value.ToString());
|
||||||
|
|
||||||
return await GetImagesByNameItem<Year>(path, value.ToString()).ConfigureAwait(false);
|
return GetImagesByNameItem<Year>(path, value.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConcurrentDictionary<string, object> ImagesByNameItemCache = new ConcurrentDictionary<string, object>();
|
private ConcurrentDictionary<string, object> ImagesByNameItemCache = new ConcurrentDictionary<string, object>();
|
||||||
|
@ -258,7 +252,7 @@ namespace MediaBrowser.Controller.Library
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generically retrieves an IBN item
|
/// Generically retrieves an IBN item
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task<T> GetImagesByNameItem<T>(string path, string name)
|
private Task<T> GetImagesByNameItem<T>(string path, string name)
|
||||||
where T : BaseEntity, new()
|
where T : BaseEntity, new()
|
||||||
{
|
{
|
||||||
string key = path.ToLower();
|
string key = path.ToLower();
|
||||||
|
@ -266,12 +260,10 @@ namespace MediaBrowser.Controller.Library
|
||||||
// Look for it in the cache, if it's not there, create it
|
// Look for it in the cache, if it's not there, create it
|
||||||
if (!ImagesByNameItemCache.ContainsKey(key))
|
if (!ImagesByNameItemCache.ContainsKey(key))
|
||||||
{
|
{
|
||||||
T obj = await CreateImagesByNameItem<T>(path, name).ConfigureAwait(false);
|
ImagesByNameItemCache[key] = CreateImagesByNameItem<T>(path, name);
|
||||||
ImagesByNameItemCache[key] = obj;
|
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ImagesByNameItemCache[key] as T;
|
return ImagesByNameItemCache[key] as Task<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -23,16 +23,22 @@ namespace MediaBrowser.Controller.Providers
|
||||||
get { return MetadataProviderPriority.First; }
|
get { return MetadataProviderPriority.First; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
|
public async override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args)
|
||||||
{
|
{
|
||||||
Audio audio = item as Audio;
|
Audio audio = item as Audio;
|
||||||
|
|
||||||
|
Fetch(audio, await FFProbe.Run(audio, GetFFProbeOutputPath(item)).ConfigureAwait(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetFFProbeOutputPath(BaseEntity item)
|
||||||
|
{
|
||||||
string outputDirectory = Path.Combine(Kernel.Instance.ApplicationPaths.FFProbeAudioCacheDirectory, item.Id.ToString().Substring(0, 1));
|
string outputDirectory = Path.Combine(Kernel.Instance.ApplicationPaths.FFProbeAudioCacheDirectory, item.Id.ToString().Substring(0, 1));
|
||||||
|
|
||||||
string outputPath = Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".js");
|
return Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".js");
|
||||||
|
}
|
||||||
FFProbeResult data = await FFProbe.Run(audio, outputPath).ConfigureAwait(false);
|
|
||||||
|
|
||||||
|
private void Fetch(Audio audio, FFProbeResult data)
|
||||||
|
{
|
||||||
MediaStream stream = data.streams.First(s => s.codec_type.Equals("audio", StringComparison.OrdinalIgnoreCase));
|
MediaStream stream = data.streams.First(s => s.codec_type.Equals("audio", StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
string bitrate = null;
|
string bitrate = null;
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace MediaBrowser.Controller.Providers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Task Fetch(BaseEntity item, ItemResolveEventArgs args);
|
public abstract Task FetchAsync(BaseEntity item, ItemResolveEventArgs args);
|
||||||
|
|
||||||
public abstract MetadataProviderPriority Priority { get; }
|
public abstract MetadataProviderPriority Priority { get; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,14 +19,16 @@ namespace MediaBrowser.Controller.Providers
|
||||||
get { return MetadataProviderPriority.First; }
|
get { return MetadataProviderPriority.First; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
|
public override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args)
|
||||||
{
|
{
|
||||||
var metadataFile = args.GetFileSystemEntryByName("folder.xml");
|
var metadataFile = args.GetFileSystemEntryByName("folder.xml");
|
||||||
|
|
||||||
if (metadataFile.HasValue)
|
if (metadataFile.HasValue)
|
||||||
{
|
{
|
||||||
await Task.Run(() => { new FolderXmlParser().Fetch(item as Folder, metadataFile.Value.Path); }).ConfigureAwait(false);
|
return Task.Run(() => { new FolderXmlParser().Fetch(item as Folder, metadataFile.Value.Path); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Task.FromResult<object>(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,24 +21,23 @@ namespace MediaBrowser.Controller.Providers
|
||||||
get { return MetadataProviderPriority.First; }
|
get { return MetadataProviderPriority.First; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
|
public override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args)
|
||||||
{
|
{
|
||||||
return Task.Run(() =>
|
if (args.IsDirectory)
|
||||||
{
|
{
|
||||||
if (args.IsDirectory)
|
var baseItem = item as BaseItem;
|
||||||
{
|
|
||||||
var baseItem = item as BaseItem;
|
|
||||||
|
|
||||||
if (baseItem != null)
|
if (baseItem != null)
|
||||||
{
|
{
|
||||||
PopulateImages(baseItem, args);
|
return Task.Run(() => { PopulateImages(baseItem, args); });
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PopulateImages(item, args);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
else
|
||||||
|
{
|
||||||
|
return Task.Run(() => { PopulateImages(item, args); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.FromResult<object>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -49,7 +48,7 @@ namespace MediaBrowser.Controller.Providers
|
||||||
for (int i = 0; i < args.FileSystemChildren.Length; i++)
|
for (int i = 0; i < args.FileSystemChildren.Length; i++)
|
||||||
{
|
{
|
||||||
var file = args.FileSystemChildren[i];
|
var file = args.FileSystemChildren[i];
|
||||||
|
|
||||||
string filePath = file.Path;
|
string filePath = file.Path;
|
||||||
|
|
||||||
string ext = Path.GetExtension(filePath);
|
string ext = Path.GetExtension(filePath);
|
||||||
|
|
|
@ -20,10 +20,8 @@ namespace MediaBrowser.Controller.Providers
|
||||||
get { return MetadataProviderPriority.First; }
|
get { return MetadataProviderPriority.First; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
|
public async override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args)
|
||||||
{
|
{
|
||||||
BaseItem baseItem = item as BaseItem;
|
|
||||||
|
|
||||||
var trailerPath = args.GetFileSystemEntryByName("trailers", true);
|
var trailerPath = args.GetFileSystemEntryByName("trailers", true);
|
||||||
|
|
||||||
if (trailerPath.HasValue)
|
if (trailerPath.HasValue)
|
||||||
|
@ -36,9 +34,7 @@ namespace MediaBrowser.Controller.Providers
|
||||||
{
|
{
|
||||||
string file = allFiles[i];
|
string file = allFiles[i];
|
||||||
|
|
||||||
BaseItem child = await Kernel.Instance.ItemController.GetItem(file).ConfigureAwait(false);
|
Video video = await Kernel.Instance.ItemController.GetItem(file).ConfigureAwait(false) as Video;
|
||||||
|
|
||||||
Video video = child as Video;
|
|
||||||
|
|
||||||
if (video != null)
|
if (video != null)
|
||||||
{
|
{
|
||||||
|
@ -46,7 +42,7 @@ namespace MediaBrowser.Controller.Providers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
baseItem.LocalTrailers = localTrailers;
|
(item as BaseItem).LocalTrailers = localTrailers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace MediaBrowser.Controller.Providers
|
||||||
get { return MetadataProviderPriority.Second; }
|
get { return MetadataProviderPriority.Second; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Fetch(BaseEntity item, ItemResolveEventArgs args)
|
public override async Task FetchAsync(BaseEntity item, ItemResolveEventArgs args)
|
||||||
{
|
{
|
||||||
Video video = item as Video;
|
Video video = item as Video;
|
||||||
|
|
||||||
|
@ -39,11 +39,14 @@ namespace MediaBrowser.Controller.Providers
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Fetch(video, await FFProbe.Run(video, GetFFProbeOutputPath(video)).ConfigureAwait(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetFFProbeOutputPath(Video item)
|
||||||
|
{
|
||||||
string outputDirectory = Path.Combine(Kernel.Instance.ApplicationPaths.FFProbeVideoCacheDirectory, item.Id.ToString().Substring(0, 1));
|
string outputDirectory = Path.Combine(Kernel.Instance.ApplicationPaths.FFProbeVideoCacheDirectory, item.Id.ToString().Substring(0, 1));
|
||||||
|
|
||||||
string outputPath = Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".js");
|
return Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".js");
|
||||||
|
|
||||||
FFProbeResult data = await FFProbe.Run(video, outputPath).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Fetch(Video video, FFProbeResult data)
|
private void Fetch(Video video, FFProbeResult data)
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
|
|
|
@ -21,14 +21,16 @@ namespace MediaBrowser.Movies.Providers
|
||||||
get { return MetadataProviderPriority.First; }
|
get { return MetadataProviderPriority.First; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
|
public override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args)
|
||||||
{
|
{
|
||||||
var metadataFile = args.GetFileSystemEntryByName("movie.xml");
|
var metadataFile = args.GetFileSystemEntryByName("movie.xml");
|
||||||
|
|
||||||
if (metadataFile.HasValue)
|
if (metadataFile.HasValue)
|
||||||
{
|
{
|
||||||
await Task.Run(() => { new BaseItemXmlParser<Movie>().Fetch(item as Movie, metadataFile.Value.Path); }).ConfigureAwait(false);
|
return Task.Run(() => { new BaseItemXmlParser<Movie>().Fetch(item as Movie, metadataFile.Value.Path); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Task.FromResult<object>(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System.ComponentModel.Composition;
|
||||||
using System.ComponentModel.Composition;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -23,7 +22,7 @@ namespace MediaBrowser.TV.Providers
|
||||||
get { return MetadataProviderPriority.First; }
|
get { return MetadataProviderPriority.First; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
|
public override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args)
|
||||||
{
|
{
|
||||||
return Task.Run(() =>
|
return Task.Run(() =>
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,24 +22,21 @@ namespace MediaBrowser.TV.Providers
|
||||||
get { return MetadataProviderPriority.First; }
|
get { return MetadataProviderPriority.First; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
|
public override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args)
|
||||||
{
|
{
|
||||||
await Task.Run(() =>
|
return Fetch(item, args);
|
||||||
{
|
|
||||||
string metadataFolder = Path.Combine(args.Parent.Path, "metadata");
|
|
||||||
|
|
||||||
Episode episode = item as Episode;
|
|
||||||
|
|
||||||
string episodeFileName = Path.GetFileName(episode.Path);
|
|
||||||
|
|
||||||
string metadataFile = Path.Combine(metadataFolder, Path.ChangeExtension(episodeFileName, ".xml"));
|
|
||||||
|
|
||||||
FetchMetadata(episode, args.Parent as Season, metadataFile);
|
|
||||||
|
|
||||||
}).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FetchMetadata(Episode item, Season season, string metadataFile)
|
private Task Fetch(BaseEntity item, ItemResolveEventArgs args)
|
||||||
|
{
|
||||||
|
string metadataFolder = Path.Combine(args.Parent.Path, "metadata");
|
||||||
|
|
||||||
|
string metadataFile = Path.Combine(metadataFolder, Path.ChangeExtension(Path.GetFileName(args.Path), ".xml"));
|
||||||
|
|
||||||
|
return FetchMetadata(item as Episode, args.Parent as Season, metadataFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task FetchMetadata(Episode item, Season season, string metadataFile)
|
||||||
{
|
{
|
||||||
if (season == null)
|
if (season == null)
|
||||||
{
|
{
|
||||||
|
@ -47,18 +44,18 @@ namespace MediaBrowser.TV.Providers
|
||||||
// Need to validate it the slow way
|
// Need to validate it the slow way
|
||||||
if (!File.Exists(metadataFile))
|
if (!File.Exists(metadataFile))
|
||||||
{
|
{
|
||||||
return;
|
return Task.FromResult<object>(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!season.ContainsMetadataFile(metadataFile))
|
if (!season.ContainsMetadataFile(metadataFile))
|
||||||
{
|
{
|
||||||
return;
|
return Task.FromResult<object>(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new EpisodeXmlParser().Fetch(item, metadataFile);
|
return Task.Run(() => { new EpisodeXmlParser().Fetch(item, metadataFile); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,14 +21,16 @@ namespace MediaBrowser.TV.Providers
|
||||||
get { return MetadataProviderPriority.First; }
|
get { return MetadataProviderPriority.First; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
|
public override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args)
|
||||||
{
|
{
|
||||||
var metadataFile = args.GetFileSystemEntryByName("series.xml");
|
var metadataFile = args.GetFileSystemEntryByName("series.xml");
|
||||||
|
|
||||||
if (metadataFile.HasValue)
|
if (metadataFile.HasValue)
|
||||||
{
|
{
|
||||||
await Task.Run(() => { new SeriesXmlParser().Fetch(item as Series, metadataFile.Value.Path); }).ConfigureAwait(false);
|
return Task.Run(() => { new SeriesXmlParser().Fetch(item as Series, metadataFile.Value.Path); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Task.FromResult<object>(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue