diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index abc6c35666..26450c06ca 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -148,6 +148,34 @@ namespace Emby.Server.Implementations
}
}
+ public virtual bool CanLaunchWebBrowser
+ {
+ get
+ {
+ if (!Environment.UserInteractive)
+ {
+ return false;
+ }
+
+ if (StartupOptions.ContainsOption("-service"))
+ {
+ return false;
+ }
+
+ if (EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows)
+ {
+ return true;
+ }
+
+ if (EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.OSX)
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
+
///
/// Occurs when [has pending restart changed].
///
@@ -1936,6 +1964,7 @@ namespace Emby.Server.Implementations
OperatingSystemDisplayName = OperatingSystemDisplayName,
CanSelfRestart = CanSelfRestart,
CanSelfUpdate = CanSelfUpdate,
+ CanLaunchWebBrowser = CanLaunchWebBrowser,
WanAddress = ConnectManager.WanApiAddress,
HasUpdateAvailable = HasUpdateAvailable,
SupportsAutoRunAtStartup = SupportsAutoRunAtStartup,
@@ -2358,13 +2387,7 @@ namespace Emby.Server.Implementations
public virtual void LaunchUrl(string url)
{
- if (EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows &&
- EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.OSX)
- {
- throw new NotSupportedException();
- }
-
- if (!Environment.UserInteractive)
+ if (!CanLaunchWebBrowser)
{
throw new NotSupportedException();
}
diff --git a/Emby.Server.Implementations/Archiving/ZipClient.cs b/Emby.Server.Implementations/Archiving/ZipClient.cs
index d7d37bb61c..32938e151f 100644
--- a/Emby.Server.Implementations/Archiving/ZipClient.cs
+++ b/Emby.Server.Implementations/Archiving/ZipClient.cs
@@ -89,6 +89,24 @@ namespace Emby.Server.Implementations.Archiving
}
}
+ public void ExtractFirstFileFromGz(Stream source, string targetPath, string defaultFileName)
+ {
+ using (var reader = GZipReader.Open(source))
+ {
+ if (reader.MoveToNextEntry())
+ {
+ var entry = reader.Entry;
+
+ var filename = entry.Key;
+ if (string.IsNullOrWhiteSpace(filename))
+ {
+ filename = defaultFileName;
+ }
+ reader.WriteEntryToFile(Path.Combine(targetPath, filename));
+ }
+ }
+ }
+
///
/// Extracts all from7z.
///
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index ddead897eb..830d6447ec 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -5264,7 +5264,13 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
ItemIds = query.ItemIds,
TopParentIds = query.TopParentIds,
ParentId = query.ParentId,
- IsPlayed = query.IsPlayed
+ IsPlayed = query.IsPlayed,
+ IsAiring = query.IsAiring,
+ IsMovie = query.IsMovie,
+ IsSports = query.IsSports,
+ IsKids = query.IsKids,
+ IsNews = query.IsNews,
+ IsSeries = query.IsSeries
};
var innerWhereClauses = GetWhereClauses(innerQuery, null);
diff --git a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs
index 746edf9e7b..103b4b321e 100644
--- a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs
+++ b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs
@@ -35,15 +35,20 @@ namespace Emby.Server.Implementations.EntryPoints
///
public void Run()
{
+ if (!_appHost.CanLaunchWebBrowser)
+ {
+ return;
+ }
+
if (_appHost.IsFirstRun)
{
BrowserLauncher.OpenDashboardPage("wizardstart.html", _appHost);
}
- else if (_config.Configuration.IsStartupWizardCompleted)
+ else if (_config.Configuration.IsStartupWizardCompleted && _config.Configuration.AutoRunWebApp)
{
var options = ((ApplicationHost)_appHost).StartupOptions;
- if (!options.ContainsOption("-service") && !options.ContainsOption("-nobrowser"))
+ if (!options.ContainsOption("-noautorunwebapp"))
{
BrowserLauncher.OpenDashboardPage("index.html", _appHost);
}
diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
index 95ec1dee0d..7c251e3039 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
@@ -105,31 +105,64 @@ namespace Emby.Server.Implementations.LiveTv.Listings
if (string.Equals(ext, ".gz", StringComparison.OrdinalIgnoreCase))
{
- using (var stream = _fileSystem.OpenRead(file))
+ try
{
- var tempFolder = Path.Combine(_config.ApplicationPaths.TempDirectory, Guid.NewGuid().ToString());
- _fileSystem.CreateDirectory(tempFolder);
+ var tempFolder = ExtractGz(file);
+ return FindXmlFile(tempFolder);
+ }
+ catch (Exception ex)
+ {
+ //_logger.ErrorException("Error extracting from gz file {0}", ex, file);
+ }
- try
- {
- _zipClient.ExtractAllFromGz(stream, tempFolder, true);
- }
- catch
- {
- // If the extraction fails just return the original file, it could be a gz
- return file;
- }
-
- return _fileSystem.GetFiles(tempFolder, true)
- .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase))
- .Select(i => i.FullName)
- .FirstOrDefault();
+ try
+ {
+ var tempFolder = ExtractFirstFileFromGz(file);
+ return FindXmlFile(tempFolder);
+ }
+ catch (Exception ex)
+ {
+ //_logger.ErrorException("Error extracting from zip file {0}", ex, file);
}
}
return file;
}
+ private string ExtractFirstFileFromGz(string file)
+ {
+ using (var stream = _fileSystem.OpenRead(file))
+ {
+ var tempFolder = Path.Combine(_config.ApplicationPaths.TempDirectory, Guid.NewGuid().ToString());
+ _fileSystem.CreateDirectory(tempFolder);
+
+ _zipClient.ExtractFirstFileFromGz(stream, tempFolder, "data.xml");
+
+ return tempFolder;
+ }
+ }
+
+ private string ExtractGz(string file)
+ {
+ using (var stream = _fileSystem.OpenRead(file))
+ {
+ var tempFolder = Path.Combine(_config.ApplicationPaths.TempDirectory, Guid.NewGuid().ToString());
+ _fileSystem.CreateDirectory(tempFolder);
+
+ _zipClient.ExtractAllFromGz(stream, tempFolder, true);
+
+ return tempFolder;
+ }
+ }
+
+ private string FindXmlFile(string directory)
+ {
+ return _fileSystem.GetFiles(directory, true)
+ .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase))
+ .Select(i => i.FullName)
+ .FirstOrDefault();
+ }
+
public async Task> GetProgramsAsync(ListingsProviderInfo info, string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
{
if (string.IsNullOrWhiteSpace(channelId))
@@ -149,6 +182,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
_logger.Debug("Getting xmltv programs for channel {0}", channelId);
var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false);
+ _logger.Debug("Opening XmlTvReader for {0}", path);
var reader = new XmlTvReader(path, GetLanguage(info));
var results = reader.GetProgrammes(channelId, startDateUtc, endDateUtc, cancellationToken);
@@ -251,6 +285,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
// In theory this should never be called because there is always only one lineup
var path = await GetXml(info.Path, CancellationToken.None).ConfigureAwait(false);
+ _logger.Debug("Opening XmlTvReader for {0}", path);
var reader = new XmlTvReader(path, GetLanguage(info));
var results = reader.GetChannels();
@@ -262,6 +297,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
// In theory this should never be called because there is always only one lineup
var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false);
+ _logger.Debug("Opening XmlTvReader for {0}", path);
var reader = new XmlTvReader(path, GetLanguage(info));
var results = reader.GetChannels();
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index 7e27877e7c..66eabf523a 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -125,7 +125,7 @@ namespace Emby.Server.Implementations.LiveTv
public void AddParts(IEnumerable services, IEnumerable tunerHosts, IEnumerable listingProviders)
{
_services = services.ToArray();
- _tunerHosts.AddRange(tunerHosts);
+ _tunerHosts.AddRange(tunerHosts.Where(i => i.IsSupported));
_listingProviders.AddRange(listingProviders);
foreach (var service in _services)
@@ -947,6 +947,7 @@ namespace Emby.Server.Implementations.LiveTv
IsKids = query.IsKids,
IsNews = query.IsNews,
Genres = query.Genres,
+ GenreIds = query.GenreIds,
StartIndex = query.StartIndex,
Limit = query.Limit,
OrderBy = query.OrderBy,
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
index e0fd32aeef..45e96c36d8 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
@@ -39,6 +39,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
FileSystem = fileSystem;
}
+ public virtual bool IsSupported
+ {
+ get
+ {
+ return true;
+ }
+ }
+
protected abstract Task> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken);
public abstract string Type { get; }
diff --git a/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs b/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs
index 6e0e55bef4..d790f4ab8b 100644
--- a/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs
+++ b/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs
@@ -76,6 +76,21 @@ namespace Emby.Server.Implementations.MediaEncoder
return false;
}
+ if (video.VideoType == VideoType.Iso)
+ {
+ return false;
+ }
+
+ if (video.VideoType == VideoType.BluRay || video.VideoType == VideoType.Dvd)
+ {
+ return false;
+ }
+
+ if (video.IsShortcut)
+ {
+ return false;
+ }
+
if (!video.IsCompleteMedia)
{
return false;
@@ -118,16 +133,6 @@ namespace Emby.Server.Implementations.MediaEncoder
{
if (extractImages)
{
- if (video.VideoType == VideoType.Iso)
- {
- continue;
- }
-
- if (video.VideoType == VideoType.BluRay || video.VideoType == VideoType.Dvd)
- {
- continue;
- }
-
try
{
// Add some time for the first chapter to make sure we don't end up with a black image
diff --git a/MediaBrowser.Api/FilterService.cs b/MediaBrowser.Api/FilterService.cs
index 52b274653b..585e9c49bc 100644
--- a/MediaBrowser.Api/FilterService.cs
+++ b/MediaBrowser.Api/FilterService.cs
@@ -2,6 +2,7 @@
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Querying;
+using MediaBrowser.Model.Dto;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -11,7 +12,7 @@ using MediaBrowser.Model.Services;
namespace MediaBrowser.Api
{
[Route("/Items/Filters", "GET", Summary = "Gets branding configuration")]
- public class GetQueryFilters : IReturn
+ public class GetQueryFiltersLegacy : IReturn
{
///
/// Gets or sets the user id.
@@ -40,6 +41,43 @@ namespace MediaBrowser.Api
}
}
+ [Route("/Items/Filters2", "GET", Summary = "Gets branding configuration")]
+ public class GetQueryFilters : IReturn
+ {
+ ///
+ /// Gets or sets the user id.
+ ///
+ /// The user id.
+ [ApiMember(Name = "UserId", Description = "User Id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public string UserId { get; set; }
+
+ [ApiMember(Name = "ParentId", Description = "Specify this to localize the search to a specific item or folder. Omit to use the root", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public string ParentId { get; set; }
+
+ [ApiMember(Name = "IncludeItemTypes", Description = "Optional. If specified, results will be filtered based on item type. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
+ public string IncludeItemTypes { get; set; }
+
+ [ApiMember(Name = "MediaTypes", Description = "Optional filter by MediaType. Allows multiple, comma delimited.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
+ public string MediaTypes { get; set; }
+
+ public string[] GetMediaTypes()
+ {
+ return (MediaTypes ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+ }
+
+ public string[] GetIncludeItemTypes()
+ {
+ return (IncludeItemTypes ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+ }
+
+ public bool? IsAiring { get; set; }
+ public bool? IsMovie { get; set; }
+ public bool? IsSports { get; set; }
+ public bool? IsKids { get; set; }
+ public bool? IsNews { get; set; }
+ public bool? IsSeries { get; set; }
+ }
+
[Authenticated]
public class FilterService : BaseApiService
{
@@ -57,18 +95,96 @@ namespace MediaBrowser.Api
var parentItem = string.IsNullOrEmpty(request.ParentId) ? null : _libraryManager.GetItemById(request.ParentId);
var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
+ if (string.Equals(request.IncludeItemTypes, "BoxSet", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(request.IncludeItemTypes, "Playlist", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(request.IncludeItemTypes, typeof(Trailer).Name, StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(request.IncludeItemTypes, "Program", StringComparison.OrdinalIgnoreCase))
+ {
+ parentItem = null;
+ }
+
+ var filters = new QueryFilters();
+
+ var genreQuery = new InternalItemsQuery(user)
+ {
+ AncestorIds = parentItem == null ? new string[] { } : new string[] { parentItem.Id.ToString("N") },
+ IncludeItemTypes = request.GetIncludeItemTypes(),
+ DtoOptions = new Controller.Dto.DtoOptions
+ {
+ Fields = new ItemFields[] { },
+ EnableImages = false,
+ EnableUserData = false
+ },
+ IsAiring = request.IsAiring,
+ IsMovie = request.IsMovie,
+ IsSports = request.IsSports,
+ IsKids = request.IsKids,
+ IsNews = request.IsNews,
+ IsSeries = request.IsSeries
+ };
+
+ if (string.Equals(request.IncludeItemTypes, "MusicAlbum", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(request.IncludeItemTypes, "MusicVideo", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(request.IncludeItemTypes, "MusicArtist", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(request.IncludeItemTypes, "Audio", StringComparison.OrdinalIgnoreCase))
+ {
+ filters.Genres = _libraryManager.GetMusicGenres(genreQuery).Items.Select(i => new NameIdPair
+ {
+ Name = i.Item1.Name,
+ Id = i.Item1.Id.ToString("N")
+
+ }).ToArray();
+ }
+ else if (string.Equals(request.IncludeItemTypes, "Game", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(request.IncludeItemTypes, "GameSystem", StringComparison.OrdinalIgnoreCase))
+ {
+ filters.Genres = _libraryManager.GetGameGenres(genreQuery).Items.Select(i => new NameIdPair
+ {
+ Name = i.Item1.Name,
+ Id = i.Item1.Id.ToString("N")
+
+ }).ToArray();
+ }
+ else
+ {
+ filters.Genres = _libraryManager.GetGenres(genreQuery).Items.Select(i => new NameIdPair
+ {
+ Name = i.Item1.Name,
+ Id = i.Item1.Id.ToString("N")
+
+ }).ToArray();
+ }
+
+ return ToOptimizedResult(filters);
+ }
+
+ public object Get(GetQueryFiltersLegacy request)
+ {
+ var parentItem = string.IsNullOrEmpty(request.ParentId) ? null : _libraryManager.GetItemById(request.ParentId);
+ var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
+
+ if (string.Equals(request.IncludeItemTypes, "BoxSet", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(request.IncludeItemTypes, "Playlist", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(request.IncludeItemTypes, typeof(Trailer).Name, StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(request.IncludeItemTypes, "Program", StringComparison.OrdinalIgnoreCase))
+ {
+ parentItem = null;
+ }
+
var item = string.IsNullOrEmpty(request.ParentId) ?
user == null ? _libraryManager.RootFolder : user.RootFolder :
parentItem;
var result = ((Folder)item).GetItemList(GetItemsQuery(request, user));
- return ToOptimizedResult(GetFilters(result));
+ var filters = GetFilters(result);
+
+ return ToOptimizedResult(filters);
}
- private QueryFilters GetFilters(BaseItem[] items)
+ private QueryFiltersLegacy GetFilters(BaseItem[] items)
{
- var result = new QueryFilters();
+ var result = new QueryFiltersLegacy();
result.Years = items.Select(i => i.ProductionYear ?? -1)
.Where(i => i > 0)
@@ -97,7 +213,7 @@ namespace MediaBrowser.Api
return result;
}
- private InternalItemsQuery GetItemsQuery(GetQueryFilters request, User user)
+ private InternalItemsQuery GetItemsQuery(GetQueryFiltersLegacy request, User user)
{
var query = new InternalItemsQuery
{
diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs
index 703c96e0c6..c137620481 100644
--- a/MediaBrowser.Api/LiveTv/LiveTvService.cs
+++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs
@@ -379,6 +379,9 @@ namespace MediaBrowser.Api.LiveTv
[ApiMember(Name = "Genres", Description = "The genres to return guide information for.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")]
public string Genres { get; set; }
+ [ApiMember(Name = "GenreIds", Description = "The genres to return guide information for.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")]
+ public string GenreIds { get; set; }
+
[ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
public bool? EnableImages { get; set; }
@@ -1003,6 +1006,7 @@ namespace MediaBrowser.Api.LiveTv
query.IsSports = request.IsSports;
query.SeriesTimerId = request.SeriesTimerId;
query.Genres = (request.Genres ?? String.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+ query.GenreIds = (request.GenreIds ?? String.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
if (!string.IsNullOrWhiteSpace(request.LibrarySeriesId))
{
diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs
index 54e4657c11..c6345c17f4 100644
--- a/MediaBrowser.Api/StartupWizardService.cs
+++ b/MediaBrowser.Api/StartupWizardService.cs
@@ -67,6 +67,7 @@ namespace MediaBrowser.Api
public void Post(ReportStartupWizardComplete request)
{
_config.Configuration.IsStartupWizardCompleted = true;
+ _config.Configuration.AutoRunWebApp = true;
_config.SetOptimalValues();
_config.SaveConfiguration();
diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs
index 89ae85b508..3f7f8248b5 100644
--- a/MediaBrowser.Controller/IServerApplicationHost.cs
+++ b/MediaBrowser.Controller/IServerApplicationHost.cs
@@ -29,7 +29,9 @@ namespace MediaBrowser.Controller
///
/// true if [supports automatic run at startup]; otherwise, false.
bool SupportsAutoRunAtStartup { get; }
-
+
+ bool CanLaunchWebBrowser { get; }
+
///
/// Gets the HTTP server port.
///
diff --git a/MediaBrowser.Controller/LiveTv/ITunerHost.cs b/MediaBrowser.Controller/LiveTv/ITunerHost.cs
index 242011db06..80c40f8bde 100644
--- a/MediaBrowser.Controller/LiveTv/ITunerHost.cs
+++ b/MediaBrowser.Controller/LiveTv/ITunerHost.cs
@@ -46,6 +46,10 @@ namespace MediaBrowser.Controller.LiveTv
Task> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken);
Task> DiscoverDevices(int discoveryDurationMs, CancellationToken cancellationToken);
+ bool IsSupported
+ {
+ get;
+ }
}
public interface IConfigurableTunerHost
{
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index f2c3b7cc8a..41ed0648a6 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -61,6 +61,8 @@ namespace MediaBrowser.Model.Configuration
/// true if this instance is port authorized; otherwise, false.
public bool IsPortAuthorized { get; set; }
+ public bool AutoRunWebApp { get; set; }
+
///
/// Gets or sets a value indicating whether [enable case sensitive item ids].
///
diff --git a/MediaBrowser.Model/IO/IZipClient.cs b/MediaBrowser.Model/IO/IZipClient.cs
index 2dc4880c2f..4ebcba9d89 100644
--- a/MediaBrowser.Model/IO/IZipClient.cs
+++ b/MediaBrowser.Model/IO/IZipClient.cs
@@ -24,6 +24,7 @@ namespace MediaBrowser.Model.IO
void ExtractAll(Stream source, string targetPath, bool overwriteExistingFiles);
void ExtractAllFromGz(Stream source, string targetPath, bool overwriteExistingFiles);
+ void ExtractFirstFileFromGz(Stream source, string targetPath, string defaultFileName);
///
/// Extracts all from zip.
diff --git a/MediaBrowser.Model/LiveTv/ProgramQuery.cs b/MediaBrowser.Model/LiveTv/ProgramQuery.cs
index c0959635f3..ec3f8ad672 100644
--- a/MediaBrowser.Model/LiveTv/ProgramQuery.cs
+++ b/MediaBrowser.Model/LiveTv/ProgramQuery.cs
@@ -14,6 +14,7 @@ namespace MediaBrowser.Model.LiveTv
ChannelIds = new string[] { };
OrderBy = new Tuple[] { };
Genres = new string[] { };
+ GenreIds = new string[] { };
EnableTotalRecordCount = true;
EnableUserData = true;
}
@@ -110,6 +111,7 @@ namespace MediaBrowser.Model.LiveTv
/// Limit results to items containing specific genres
///
/// The genres.
+ public string[] GenreIds { get; set; }
public string[] Genres { get; set; }
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Model/Querying/QueryFilters.cs b/MediaBrowser.Model/Querying/QueryFilters.cs
index dd575c2a88..3a261857bd 100644
--- a/MediaBrowser.Model/Querying/QueryFilters.cs
+++ b/MediaBrowser.Model/Querying/QueryFilters.cs
@@ -1,14 +1,15 @@
-
+using MediaBrowser.Model.Dto;
+
namespace MediaBrowser.Model.Querying
{
- public class QueryFilters
+ public class QueryFiltersLegacy
{
public string[] Genres { get; set; }
public string[] Tags { get; set; }
public string[] OfficialRatings { get; set; }
public int[] Years { get; set; }
- public QueryFilters()
+ public QueryFiltersLegacy()
{
Genres = new string[] { };
Tags = new string[] { };
@@ -16,4 +17,15 @@ namespace MediaBrowser.Model.Querying
Years = new int[] { };
}
}
+ public class QueryFilters
+ {
+ public NameIdPair[] Genres { get; set; }
+ public string[] Tags { get; set; }
+
+ public QueryFilters()
+ {
+ Tags = new string[] { };
+ Genres = new NameIdPair[] { };
+ }
+ }
}
diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs
index b61d637293..9ed0f904f0 100644
--- a/MediaBrowser.Model/System/SystemInfo.cs
+++ b/MediaBrowser.Model/System/SystemInfo.cs
@@ -68,6 +68,8 @@ namespace MediaBrowser.Model.System
/// true if this instance can self update; otherwise, false.
public bool CanSelfUpdate { get; set; }
+ public bool CanLaunchWebBrowser { get; set; }
+
///
/// Gets or sets plugin assemblies that failed to load.
///
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
index e79aec33c1..6a2677b433 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
@@ -153,7 +153,6 @@ namespace MediaBrowser.Providers.MediaInfo
if (item.IsShortcut)
{
FetchShortcutInfo(item);
- return Task.FromResult(ItemUpdateType.MetadataImport);
}
var prober = new FFProbeVideoInfo(_logger, _isoManager, _mediaEncoder, _itemRepo, _blurayExaminer, _localization, _appPaths, _json, _encodingManager, _fileSystem, _config, _subtitleManager, _chapterManager, _libraryManager);
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
index 1582385571..443eb6eda4 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
@@ -75,49 +75,54 @@ namespace MediaBrowser.Providers.MediaInfo
try
{
- string[] streamFileNames = null;
+ Model.MediaInfo.MediaInfo mediaInfoResult = null;
- if (item.VideoType == VideoType.Iso)
+ if (!item.IsShortcut)
{
- item.IsoType = DetermineIsoType(isoMount);
- }
+ string[] streamFileNames = null;
- if (item.VideoType == VideoType.Dvd || (item.IsoType.HasValue && item.IsoType == IsoType.Dvd))
- {
- streamFileNames = FetchFromDvdLib(item, isoMount);
-
- if (streamFileNames.Length == 0)
+ if (item.VideoType == VideoType.Iso)
{
- _logger.Error("No playable vobs found in dvd structure, skipping ffprobe.");
- return ItemUpdateType.MetadataImport;
+ item.IsoType = DetermineIsoType(isoMount);
}
- }
- else if (item.VideoType == VideoType.BluRay || (item.IsoType.HasValue && item.IsoType == IsoType.BluRay))
- {
- var inputPath = isoMount != null ? isoMount.MountedPath : item.Path;
-
- blurayDiscInfo = GetBDInfo(inputPath);
-
- streamFileNames = blurayDiscInfo.Files;
-
- if (streamFileNames.Length == 0)
+ if (item.VideoType == VideoType.Dvd || (item.IsoType.HasValue && item.IsoType == IsoType.Dvd))
{
- _logger.Error("No playable vobs found in bluray structure, skipping ffprobe.");
- return ItemUpdateType.MetadataImport;
+ streamFileNames = FetchFromDvdLib(item, isoMount);
+
+ if (streamFileNames.Length == 0)
+ {
+ _logger.Error("No playable vobs found in dvd structure, skipping ffprobe.");
+ return ItemUpdateType.MetadataImport;
+ }
}
+
+ else if (item.VideoType == VideoType.BluRay || (item.IsoType.HasValue && item.IsoType == IsoType.BluRay))
+ {
+ var inputPath = isoMount != null ? isoMount.MountedPath : item.Path;
+
+ blurayDiscInfo = GetBDInfo(inputPath);
+
+ streamFileNames = blurayDiscInfo.Files;
+
+ if (streamFileNames.Length == 0)
+ {
+ _logger.Error("No playable vobs found in bluray structure, skipping ffprobe.");
+ return ItemUpdateType.MetadataImport;
+ }
+ }
+
+ if (streamFileNames == null)
+ {
+ streamFileNames = new string[] { };
+ }
+
+ mediaInfoResult = await GetMediaInfo(item, isoMount, streamFileNames, cancellationToken).ConfigureAwait(false);
+
+ cancellationToken.ThrowIfCancellationRequested();
}
- if (streamFileNames == null)
- {
- streamFileNames = new string[] { };
- }
-
- var result = await GetMediaInfo(item, isoMount, streamFileNames, cancellationToken).ConfigureAwait(false);
-
- cancellationToken.ThrowIfCancellationRequested();
-
- await Fetch(item, cancellationToken, result, isoMount, blurayDiscInfo, options).ConfigureAwait(false);
+ await Fetch(item, cancellationToken, mediaInfoResult, isoMount, blurayDiscInfo, options).ConfigureAwait(false);
}
finally
@@ -162,43 +167,60 @@ namespace MediaBrowser.Providers.MediaInfo
BlurayDiscInfo blurayInfo,
MetadataRefreshOptions options)
{
- var mediaStreams = mediaInfo.MediaStreams;
+ List mediaStreams;
+ List chapters;
- video.TotalBitrate = mediaInfo.Bitrate;
- //video.FormatName = (mediaInfo.Container ?? string.Empty)
- // .Replace("matroska", "mkv", StringComparison.OrdinalIgnoreCase);
-
- // For dvd's this may not always be accurate, so don't set the runtime if the item already has one
- var needToSetRuntime = video.VideoType != VideoType.Dvd || video.RunTimeTicks == null || video.RunTimeTicks.Value == 0;
-
- if (needToSetRuntime)
+ if (mediaInfo != null)
{
- video.RunTimeTicks = mediaInfo.RunTimeTicks;
- }
+ mediaStreams = mediaInfo.MediaStreams;
- if (video.VideoType == VideoType.VideoFile)
- {
- var extension = (Path.GetExtension(video.Path) ?? string.Empty).TrimStart('.');
+ video.TotalBitrate = mediaInfo.Bitrate;
+ //video.FormatName = (mediaInfo.Container ?? string.Empty)
+ // .Replace("matroska", "mkv", StringComparison.OrdinalIgnoreCase);
- video.Container = extension;
+ // For dvd's this may not always be accurate, so don't set the runtime if the item already has one
+ var needToSetRuntime = video.VideoType != VideoType.Dvd || video.RunTimeTicks == null || video.RunTimeTicks.Value == 0;
+
+ if (needToSetRuntime)
+ {
+ video.RunTimeTicks = mediaInfo.RunTimeTicks;
+ }
+
+ if (video.VideoType == VideoType.VideoFile)
+ {
+ var extension = (Path.GetExtension(video.Path) ?? string.Empty).TrimStart('.');
+
+ video.Container = extension;
+ }
+ else
+ {
+ video.Container = null;
+ }
+ video.Container = mediaInfo.Container;
+
+ chapters = mediaInfo.Chapters == null ? new List() : mediaInfo.Chapters.ToList();
+ if (blurayInfo != null)
+ {
+ FetchBdInfo(video, chapters, mediaStreams, blurayInfo);
+ }
}
else
{
- video.Container = null;
- }
- video.Container = mediaInfo.Container;
-
- var chapters = mediaInfo.Chapters == null ? new List() : mediaInfo.Chapters.ToList();
- if (blurayInfo != null)
- {
- FetchBdInfo(video, chapters, mediaStreams, blurayInfo);
+ mediaStreams = new List();
+ chapters = new List();
}
await AddExternalSubtitles(video, mediaStreams, options, cancellationToken).ConfigureAwait(false);
+
var libraryOptions = _libraryManager.GetLibraryOptions(video);
- FetchEmbeddedInfo(video, mediaInfo, options, libraryOptions);
- FetchPeople(video, mediaInfo, options);
+ if (mediaInfo != null)
+ {
+ FetchEmbeddedInfo(video, mediaInfo, options, libraryOptions);
+ FetchPeople(video, mediaInfo, options);
+ video.Timestamp = mediaInfo.Timestamp;
+ video.Video3DFormat = video.Video3DFormat ?? mediaInfo.Video3DFormat;
+ }
video.IsHD = mediaStreams.Any(i => i.Type == MediaStreamType.Video && i.Width.HasValue && i.Width.Value >= 1260);
@@ -207,9 +229,6 @@ namespace MediaBrowser.Providers.MediaInfo
video.DefaultVideoStreamIndex = videoStream == null ? (int?)null : videoStream.Index;
video.HasSubtitles = mediaStreams.Any(i => i.Type == MediaStreamType.Subtitle);
- video.Timestamp = mediaInfo.Timestamp;
-
- video.Video3DFormat = video.Video3DFormat ?? mediaInfo.Video3DFormat;
_itemRepo.SaveMediaStreams(video.Id, mediaStreams, cancellationToken);
diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
index 65742f6e6e..a000ed36e4 100644
--- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
+++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
@@ -262,7 +262,7 @@ namespace MediaBrowser.Providers.Movies
var keepTypes = new[]
{
PersonType.Director,
- PersonType.Writer,
+ //PersonType.Writer,
//PersonType.Producer
};
diff --git a/SharedVersion.cs b/SharedVersion.cs
index f5f637be07..db8007e851 100644
--- a/SharedVersion.cs
+++ b/SharedVersion.cs
@@ -1,3 +1,3 @@
using System.Reflection;
-[assembly: AssemblyVersion("3.2.40.6")]
+[assembly: AssemblyVersion("3.2.40.7")]