diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs
index cd6bd7854c..3b8702e7dd 100644
--- a/MediaBrowser.Api/UserLibrary/ItemsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs
@@ -2,6 +2,7 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
@@ -124,6 +125,20 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "AirDays", Description = "Optional filter by Series Air Days. Allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string AirDays { get; set; }
+ ///
+ /// Gets or sets the min offical rating.
+ ///
+ /// The min offical rating.
+ [ApiMember(Name = "MinOfficalRating", Description = "Optional filter by minimum official rating (PG, PG-13, TV-MA, etc).", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public string MinOfficalRating { get; set; }
+
+ ///
+ /// Gets or sets the max offical rating.
+ ///
+ /// The max offical rating.
+ [ApiMember(Name = "MaxOfficalRating", Description = "Optional filter by maximum official rating (PG, PG-13, TV-MA, etc).", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public string MaxOfficalRating { get; set; }
+
///
/// Gets the order by.
///
@@ -357,6 +372,22 @@ namespace MediaBrowser.Api.UserLibrary
/// IEnumerable{BaseItem}.
internal static IEnumerable ApplyAdditionalFilters(GetItems request, IEnumerable items)
{
+ // Min official rating
+ if (!string.IsNullOrEmpty(request.MinOfficalRating))
+ {
+ var level = Ratings.Level(request.MinOfficalRating);
+
+ items = items.Where(i => Ratings.Level(i.CustomRating ?? i.OfficialRating) >= level);
+ }
+
+ // Max official rating
+ if (!string.IsNullOrEmpty(request.MaxOfficalRating))
+ {
+ var level = Ratings.Level(request.MaxOfficalRating);
+
+ items = items.Where(i => Ratings.Level(i.CustomRating ?? i.OfficialRating) <= level);
+ }
+
// Exclude item types
if (!string.IsNullOrEmpty(request.ExcludeItemTypes))
{
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 3c60d3a392..295b9b27de 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -32,7 +32,7 @@ namespace MediaBrowser.Controller.Entities
/// Gets or sets the name.
///
/// The name.
- public string Name { get; set; }
+ public virtual string Name { get; set; }
///
/// Gets or sets the id.
@@ -957,7 +957,7 @@ namespace MediaBrowser.Controller.Entities
{
if (person == null)
{
- throw new ArgumentNullException();
+ throw new ArgumentNullException("person");
}
if (string.IsNullOrWhiteSpace(person.Name))
@@ -967,14 +967,37 @@ namespace MediaBrowser.Controller.Entities
if (People == null)
{
- People = new List();
+ People = new List { person };
+ return;
}
- // Check for dupes based on the combination of Name and Type
+ // If the type is GuestStar and there's already an Actor entry, then update it to avoid dupes
+ if (string.Equals(person.Type, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase))
+ {
+ var existing = People.FirstOrDefault(p => p.Name.Equals(person.Name, StringComparison.OrdinalIgnoreCase) && p.Type.Equals(PersonType.Actor, StringComparison.OrdinalIgnoreCase));
+
+ if (existing != null)
+ {
+ existing.Type = PersonType.GuestStar;
+ return;
+ }
+ }
- if (!People.Any(p => p.Name.Equals(person.Name, StringComparison.OrdinalIgnoreCase) && p.Type.Equals(person.Type, StringComparison.OrdinalIgnoreCase)))
+ if (string.Equals(person.Type, PersonType.Actor, StringComparison.OrdinalIgnoreCase))
{
- People.Add(person);
+ // Only add actors if there isn't an existing one of type Actor or GuestStar
+ if (!People.Any(p => p.Name.Equals(person.Name, StringComparison.OrdinalIgnoreCase) && (p.Type.Equals(PersonType.Actor, StringComparison.OrdinalIgnoreCase) || p.Type.Equals(PersonType.GuestStar, StringComparison.OrdinalIgnoreCase))))
+ {
+ People.Add(person);
+ }
+ }
+ else
+ {
+ // Check for dupes based on the combination of Name and Type
+ if (!People.Any(p => p.Name.Equals(person.Name, StringComparison.OrdinalIgnoreCase) && p.Type.Equals(person.Type, StringComparison.OrdinalIgnoreCase)))
+ {
+ People.Add(person);
+ }
}
}
diff --git a/MediaBrowser.Installer/MainWindow.xaml.cs b/MediaBrowser.Installer/MainWindow.xaml.cs
index ee87e9bf2e..16cde95925 100644
--- a/MediaBrowser.Installer/MainWindow.xaml.cs
+++ b/MediaBrowser.Installer/MainWindow.xaml.cs
@@ -269,22 +269,13 @@ namespace MediaBrowser.Installer
{
ExtractPackage(archive);
// We're done with it so delete it (this is necessary for update operations)
- try
- {
- File.Delete(archive);
- }
- catch (FileNotFoundException)
- {
- }
- catch (Exception e)
- {
- SystemClose("Error Removing Archive - " + e.GetType().FullName + "\n\n" + e.Message);
- return;
- }
+ TryDelete(archive);
}
catch (Exception e)
{
SystemClose("Error Extracting - " + e.GetType().FullName + "\n\n" + e.Message);
+ // Delete archive even if failed so we don't try again with this one
+ TryDelete(archive);
return;
}
@@ -337,6 +328,23 @@ namespace MediaBrowser.Installer
}
+ private bool TryDelete(string file)
+ {
+ try
+ {
+ File.Delete(file);
+ }
+ catch (FileNotFoundException)
+ {
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
private void PismoInstall()
{
// Kick off the Pismo installer and wait for it to end
@@ -441,8 +449,24 @@ namespace MediaBrowser.Installer
var backupDir = Path.Combine(RootPath, "System.old");
if (Directory.Exists(systemDir))
{
- if (Directory.Exists(backupDir)) Directory.Delete(backupDir,true);
- Directory.Move(systemDir, backupDir);
+ try
+ {
+ if (Directory.Exists(backupDir)) Directory.Delete(backupDir,true);
+
+ }
+ catch (Exception e)
+ {
+ throw new ApplicationException("Could not delete previous backup directory.\n\n"+e.Message);
+ }
+
+ try
+ {
+ Directory.Move(systemDir, backupDir);
+ }
+ catch (Exception e)
+ {
+ throw new ApplicationException("Could not move system directory to backup.\n\n"+e.Message);
+ }
}
// And extract
@@ -461,7 +485,7 @@ namespace MediaBrowser.Installer
}
}
}
- catch
+ catch (Exception e)
{
if (retryCount < 3)
{
@@ -472,8 +496,8 @@ namespace MediaBrowser.Installer
{
//Rollback
RollBack(systemDir, backupDir);
- File.Delete(archive); // so we don't try again if its an update
- throw;
+ TryDelete(archive); // so we don't try again if its an update
+ throw new ApplicationException(string.Format("Could not extract {0} to {1} after {2} attempts.\n\n{3}", archive, RootPath, retryCount, e.Message));
}
}
}
diff --git a/MediaBrowser.Model/Querying/ItemQuery.cs b/MediaBrowser.Model/Querying/ItemQuery.cs
index 59a5e938d8..7b2a4903eb 100644
--- a/MediaBrowser.Model/Querying/ItemQuery.cs
+++ b/MediaBrowser.Model/Querying/ItemQuery.cs
@@ -157,5 +157,17 @@ namespace MediaBrowser.Model.Querying
///
/// The ids.
public string[] Ids { get; set; }
+
+ ///
+ /// Gets or sets the min official rating.
+ ///
+ /// The min official rating.
+ public string MinOfficialRating { get; set; }
+
+ ///
+ /// Gets or sets the max official rating.
+ ///
+ /// The max official rating.
+ public string MaxOfficialRating { get; set; }
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs
index dbb2d7b320..6a162d154e 100644
--- a/MediaBrowser.Server.Implementations/Library/UserManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs
@@ -106,10 +106,12 @@ namespace MediaBrowser.Server.Implementations.Library
///
/// The logger.
/// The configuration manager.
- public UserManager(ILogger logger, IServerConfigurationManager configurationManager)
+ /// The user data repository.
+ public UserManager(ILogger logger, IServerConfigurationManager configurationManager, IUserDataRepository userDataRepository)
{
_logger = logger;
ConfigurationManager = configurationManager;
+ _userDataRepository = userDataRepository;
}
#region Events
diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs
index 59395e4698..11a262ef8d 100644
--- a/MediaBrowser.ServerApplication/ApplicationHost.cs
+++ b/MediaBrowser.ServerApplication/ApplicationHost.cs
@@ -220,12 +220,12 @@ namespace MediaBrowser.ServerApplication
ZipClient = new DotNetZipClient();
RegisterSingleInstance(ZipClient);
- UserManager = new UserManager(Logger, ServerConfigurationManager);
- RegisterSingleInstance(UserManager);
-
UserDataRepository = new SQLiteUserDataRepository(ApplicationPaths, JsonSerializer, LogManager);
RegisterSingleInstance(UserDataRepository);
+ UserManager = new UserManager(Logger, ServerConfigurationManager, UserDataRepository);
+ RegisterSingleInstance(UserManager);
+
LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataRepository);
RegisterSingleInstance(LibraryManager);
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index 861112b505..7663d918bc 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Common.Internal
- 3.0.75
+ 3.0.76
MediaBrowser.Common.Internal
Luke
ebr,Luke,scottisafool
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index f034329f9c..a2202f1db1 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Common
- 3.0.75
+ 3.0.76
MediaBrowser.Common
Media Browser Team
ebr,Luke,scottisafool
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index 1797f275c8..b6870c309b 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Server.Core
- 3.0.75
+ 3.0.76
Media Browser.Server.Core
Media Browser Team
ebr,Luke,scottisafool
@@ -12,7 +12,7 @@
Contains core components required to build plugins for Media Browser Server.
Copyright © Media Browser 2013
-
+