sync updates

pull/702/head
Luke Pulverenti 10 years ago
parent 6a4a29b803
commit db03846481

@ -96,6 +96,11 @@ namespace MediaBrowser.Model.Sync
/// </summary>
/// <value><c>true</c> if this instance is marked for removal; otherwise, <c>false</c>.</value>
public bool IsMarkedForRemoval { get; set; }
/// <summary>
/// Gets or sets the index of the job item.
/// </summary>
/// <value>The index of the job item.</value>
public int JobItemIndex { get; set; }
public SyncJobItem()
{

@ -2,14 +2,12 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Manager;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

@ -15,7 +15,7 @@ using TagLib.IFD.Tags;
namespace MediaBrowser.Providers.Photos
{
public class PhotoProvider : ICustomMetadataProvider<Photo>, IHasItemChangeMonitor
public class PhotoProvider : ICustomMetadataProvider<Photo>, IHasItemChangeMonitor, IForcedProvider
{
private readonly ILogger _logger;
private readonly IImageProcessor _imageProcessor;

@ -0,0 +1,67 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Server.Implementations.Photos;
using MoreLinq;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MediaBrowser.Server.Implementations.Collections
{
public class CollectionImageProvider : BaseDynamicImageProvider<BoxSet>, ICustomMetadataProvider<BoxSet>
{
public CollectionImageProvider(IFileSystem fileSystem, IProviderManager providerManager)
: base(fileSystem, providerManager)
{
}
protected override Task<List<BaseItem>> GetItemsWithImages(IHasImages item)
{
var playlist = (BoxSet)item;
var items = playlist.Children.Concat(playlist.GetLinkedChildren())
.Select(i =>
{
var subItem = i;
var episode = subItem as Episode;
if (episode != null)
{
var series = episode.Series;
if (series != null && series.HasImage(ImageType.Primary))
{
return series;
}
}
if (subItem.HasImage(ImageType.Primary))
{
return subItem;
}
var parent = subItem.Parent;
if (parent != null && parent.HasImage(ImageType.Primary))
{
if (parent is MusicAlbum)
{
return parent;
}
}
return null;
})
.Where(i => i != null)
.DistinctBy(i => i.Id)
.ToList();
return Task.FromResult(GetFinalItems(items));
}
}
}

@ -13,8 +13,8 @@ namespace MediaBrowser.Server.Implementations.Collections
public override bool IsVisible(User user)
{
return GetChildren(user, true).Any() &&
base.IsVisible(user);
return base.IsVisible(user) && GetChildren(user, false)
.Any();
}
public override bool IsHidden

@ -34,6 +34,7 @@
"MessageKeyRemoved": "Thank you. Your supporter key has been removed.",
"ErrorLaunchingChromecast": "There was an error launching chromecast. Please ensure your device is connected to your wireless network.",
"HeaderSearch": "Search",
"ValueDateCreated": "Date created: {0}",
"LabelArtist": "Artist",
"LabelMovie": "Movie",
"LabelMusicVideo": "Music Video",
@ -46,6 +47,7 @@
"ButtonSave": "Save",
"HeaderDevices": "Devices",
"ButtonScheduledTasks": "Scheduled tasks",
"HeaderSelectCertificatePath": "Select Certificate Path",
"ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:",
"HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.",
"HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Dashboard",

@ -55,6 +55,8 @@
"HeaderAudio": "Audio",
"HeaderVideo": "Video",
"HeaderPaths": "Paths",
"LabelCustomCertificatePath": "Custom certificate path:",
"LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.",
"TitleNotifications": "Notifications",
"ButtonDonateWithPayPal": "Donate with PayPal",
"OptionDetectArchiveFilesAsMedia": "Detect archive files as media",

@ -117,6 +117,7 @@
<Compile Include="Collections\CollectionManager.cs" />
<Compile Include="Collections\CollectionsDynamicFolder.cs" />
<Compile Include="Collections\ManualCollectionsFolder.cs" />
<Compile Include="Collections\CollectionImageProvider.cs" />
<Compile Include="Configuration\ServerConfigurationManager.cs" />
<Compile Include="Connect\ConnectData.cs" />
<Compile Include="Connect\ConnectManager.cs" />

@ -1,7 +1,6 @@
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;

@ -14,7 +14,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Server.Implementations.Photos
{
public abstract class BaseDynamicImageProvider<T> : IHasChangeMonitor
public abstract class BaseDynamicImageProvider<T> : IHasChangeMonitor, IForcedProvider
where T : IHasImages
{
protected IFileSystem FileSystem { get; private set; }

@ -16,7 +16,7 @@ namespace MediaBrowser.Server.Implementations.Playlists
public override bool IsVisible(User user)
{
return base.IsVisible(user) && GetRecursiveChildren(user, false)
return base.IsVisible(user) && GetChildren(user, false)
.OfType<Playlist>()
.Any(i => i.IsVisible(user));
}

@ -90,6 +90,10 @@ namespace MediaBrowser.Server.Implementations.Sync
continue;
}
var index = jobItems.Count == 0 ?
0 :
(jobItems.Select(i => i.JobItemIndex).Max() + 1);
jobItem = new SyncJobItem
{
Id = Guid.NewGuid().ToString("N"),
@ -97,7 +101,8 @@ namespace MediaBrowser.Server.Implementations.Sync
ItemName = GetSyncJobItemName(item),
JobId = job.Id,
TargetId = job.TargetId,
DateCreated = DateTime.UtcNow
DateCreated = DateTime.UtcNow,
JobItemIndex = index
};
await _syncRepo.Create(jobItem).ConfigureAwait(false);

@ -41,7 +41,7 @@ namespace MediaBrowser.Server.Implementations.Sync
public async Task Initialize()
{
var dbFile = Path.Combine(_appPaths.DataPath, "sync13.db");
var dbFile = Path.Combine(_appPaths.DataPath, "sync14.db");
_connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false);
@ -50,7 +50,7 @@ namespace MediaBrowser.Server.Implementations.Sync
"create table if not exists SyncJobs (Id GUID PRIMARY KEY, TargetId TEXT NOT NULL, Name TEXT NOT NULL, Quality TEXT NOT NULL, Status TEXT NOT NULL, Progress FLOAT, UserId TEXT NOT NULL, ItemIds TEXT NOT NULL, Category TEXT, ParentId TEXT, UnwatchedOnly BIT, ItemLimit INT, SyncNewContent BIT, DateCreated DateTime, DateLastModified DateTime, ItemCount int)",
"create index if not exists idx_SyncJobs on SyncJobs(Id)",
"create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, TemporaryPath TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT, AdditionalFiles TEXT, MediaSource TEXT, IsMarkedForRemoval BIT)",
"create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, TemporaryPath TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT, AdditionalFiles TEXT, MediaSource TEXT, IsMarkedForRemoval BIT, JobItemIndex INT)",
"create index if not exists idx_SyncJobItems on SyncJobs(Id)",
//pragmas
@ -95,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.Sync
_saveJobCommand.Parameters.Add(_saveJobCommand, "@ItemCount");
_saveJobItemCommand = _connection.CreateCommand();
_saveJobItemCommand.CommandText = "replace into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @TemporaryPath, @OutputPath, @Status, @TargetId, @DateCreated, @Progress, @AdditionalFiles, @MediaSource, @IsMarkedForRemoval)";
_saveJobItemCommand.CommandText = "replace into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval, JobItemIndex) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @TemporaryPath, @OutputPath, @Status, @TargetId, @DateCreated, @Progress, @AdditionalFiles, @MediaSource, @IsMarkedForRemoval, @JobItemIndex)";
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@Id");
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@ItemId");
@ -111,10 +111,11 @@ namespace MediaBrowser.Server.Implementations.Sync
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@AdditionalFiles");
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@MediaSource");
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@IsMarkedForRemoval");
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@JobItemIndex");
}
private const string BaseJobSelectText = "select Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, Category, ParentId, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount from SyncJobs";
private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval from SyncJobItems";
private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval, JobItemIndex from SyncJobItems";
public SyncJob GetJob(string id)
{
@ -496,7 +497,7 @@ namespace MediaBrowser.Server.Implementations.Sync
var startIndex = query.StartIndex ?? 0;
if (startIndex > 0)
{
whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM SyncJobItems ORDER BY DateCreated LIMIT {0})",
whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM SyncJobItems ORDER BY JobItemIndex, DateCreated LIMIT {0})",
startIndex.ToString(_usCulture)));
}
@ -505,7 +506,7 @@ namespace MediaBrowser.Server.Implementations.Sync
cmd.CommandText += " where " + string.Join(" AND ", whereClauses.ToArray());
}
cmd.CommandText += " ORDER BY DateCreated";
cmd.CommandText += " ORDER BY JobItemIndex, DateCreated";
if (query.Limit.HasValue)
{
@ -574,6 +575,7 @@ namespace MediaBrowser.Server.Implementations.Sync
_saveJobItemCommand.GetParameter(index++).Value = _json.SerializeToString(jobItem.AdditionalFiles);
_saveJobItemCommand.GetParameter(index++).Value = jobItem.MediaSource == null ? null : _json.SerializeToString(jobItem.MediaSource);
_saveJobItemCommand.GetParameter(index++).Value = jobItem.IsMarkedForRemoval;
_saveJobItemCommand.GetParameter(index++).Value = jobItem.JobItemIndex;
_saveJobItemCommand.Transaction = transaction;
@ -648,7 +650,7 @@ namespace MediaBrowser.Server.Implementations.Sync
info.TargetId = reader.GetString(8);
info.DateCreated = reader.GetDateTime(9);
info.DateCreated = reader.GetDateTime(9).ToUniversalTime();
if (!reader.IsDBNull(10))
{
@ -676,7 +678,8 @@ namespace MediaBrowser.Server.Implementations.Sync
}
info.IsMarkedForRemoval = reader.GetBoolean(13);
info.JobItemIndex = reader.GetInt32(14);
return info;
}

@ -163,7 +163,10 @@ namespace MediaBrowser.Server.Implementations.TV
return new Tuple<Episode, DateTime>(nextUp, lastWatchedDate);
}
return new Tuple<Episode, DateTime>(null, lastWatchedDate);
var firstEpisode = allEpisodes.LastOrDefault(i => i.LocationType != LocationType.Virtual && !i.IsPlayed(user));
// Return the first episode
return new Tuple<Episode, DateTime>(firstEpisode, DateTime.MinValue);
}
private IEnumerable<Series> FilterSeries(NextUpQuery request, IEnumerable<Series> items)

@ -796,35 +796,35 @@ namespace MediaBrowser.Server.Startup.Common
private string GetCertificatePath(bool generateCertificate)
{
if (string.IsNullOrWhiteSpace(ServerConfigurationManager.Configuration.CertificatePath))
if (!string.IsNullOrWhiteSpace(ServerConfigurationManager.Configuration.CertificatePath))
{
// Generate self-signed cert
var certHost = GetHostnameFromExternalDns(ServerConfigurationManager.Configuration.WanDdns);
var certPath = Path.Combine(ServerConfigurationManager.ApplicationPaths.ProgramDataPath, "ssl", "cert_" + certHost.GetMD5().ToString("N") + ".pfx");
// Custom cert
return ServerConfigurationManager.Configuration.CertificatePath;
}
// Generate self-signed cert
var certHost = GetHostnameFromExternalDns(ServerConfigurationManager.Configuration.WanDdns);
var certPath = Path.Combine(ServerConfigurationManager.ApplicationPaths.ProgramDataPath, "ssl", "cert_" + certHost.GetMD5().ToString("N") + ".pfx");
if (generateCertificate)
if (generateCertificate)
{
if (!File.Exists(certPath))
{
if (!File.Exists(certPath))
Directory.CreateDirectory(Path.GetDirectoryName(certPath));
try
{
Directory.CreateDirectory(Path.GetDirectoryName(certPath));
try
{
NetworkManager.GenerateSelfSignedSslCertificate(certPath, certHost);
}
catch (Exception ex)
{
Logger.ErrorException("Error creating ssl cert", ex);
return null;
}
NetworkManager.GenerateSelfSignedSslCertificate(certPath, certHost);
}
catch (Exception ex)
{
Logger.ErrorException("Error creating ssl cert", ex);
return null;
}
}
return certPath;
}
// Custom cert
return ServerConfigurationManager.Configuration.CertificatePath;
return certPath;
}
/// <summary>

Loading…
Cancel
Save