create sync job items pages

This commit is contained in:
Luke Pulverenti 2014-12-31 01:24:49 -05:00
parent 5e6354854d
commit 8f26921d00
28 changed files with 327 additions and 157 deletions

View File

@ -28,6 +28,11 @@ namespace MediaBrowser.Api.Sync
public string Id { get; set; }
}
[Route("/Sync/Jobs/{Id}", "POST", Summary = "Updates a sync job.")]
public class UpdateSyncJob : SyncJob, IReturnVoid
{
}
[Route("/Sync/JobItems", "GET", Summary = "Gets sync job items.")]
public class GetSyncJobItems : SyncJobItemQuery, IReturn<QueryResult<SyncJobItem>>
{
@ -118,9 +123,9 @@ namespace MediaBrowser.Api.Sync
return ToOptimizedResult(result);
}
public object Get(GetSyncJobs request)
public async Task<object> Get(GetSyncJobs request)
{
var result = _syncManager.GetJobs(request);
var result = await _syncManager.GetJobs(request).ConfigureAwait(false);
return ToOptimizedResult(result);
}
@ -193,7 +198,7 @@ namespace MediaBrowser.Api.Sync
}
};
var dtos = request.ItemIds.Split(',')
var dtos = request.ItemIds.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(_libraryManager.GetItemById)
.Where(i => i != null)
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions))
@ -231,5 +236,12 @@ namespace MediaBrowser.Api.Sync
return ToOptimizedResult(response);
}
public void Post(UpdateSyncJob request)
{
var task = _syncManager.UpdateJob(request);
Task.WaitAll(task);
}
}
}

View File

@ -2,9 +2,9 @@
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Sync;
using MediaBrowser.Model.Users;
using System.Collections.Generic;
using System.Threading.Tasks;
using MediaBrowser.Model.Users;
namespace MediaBrowser.Controller.Sync
{
@ -21,7 +21,7 @@ namespace MediaBrowser.Controller.Sync
/// Gets the jobs.
/// </summary>
/// <returns>QueryResult&lt;SyncJob&gt;.</returns>
QueryResult<SyncJob> GetJobs(SyncJobQuery query);
Task<QueryResult<SyncJob>> GetJobs(SyncJobQuery query);
/// <summary>
/// Gets the job items.
@ -37,6 +37,13 @@ namespace MediaBrowser.Controller.Sync
/// <returns>SyncJob.</returns>
SyncJob GetJob(string id);
/// <summary>
/// Updates the job.
/// </summary>
/// <param name="job">The job.</param>
/// <returns>Task.</returns>
Task UpdateJob(SyncJob job);
/// <summary>
/// Cancels the job.
/// </summary>

View File

@ -18,6 +18,13 @@ namespace MediaBrowser.Controller.Sync
/// <returns>IEnumerable&lt;SyncTarget&gt;.</returns>
IEnumerable<SyncTarget> GetSyncTargets();
/// <summary>
/// Gets the synchronize targets.
/// </summary>
/// <param name="userId">The user identifier.</param>
/// <returns>IEnumerable&lt;SyncTarget&gt;.</returns>
IEnumerable<SyncTarget> GetSyncTargets(string userId);
/// <summary>
/// Gets the device profile.
/// </summary>

View File

@ -18,5 +18,10 @@ namespace MediaBrowser.Model.Devices
/// </summary>
/// <value><c>null</c> if [supports synchronize] contains no value, <c>true</c> if [supports synchronize]; otherwise, <c>false</c>.</value>
public bool? SupportsSync { get; set; }
/// <summary>
/// Gets or sets the user identifier.
/// </summary>
/// <value>The user identifier.</value>
public string UserId { get; set; }
}
}

View File

@ -89,7 +89,6 @@ namespace MediaBrowser.Model.Sync
public string ParentName { get; set; }
public string PrimaryImageItemId { get; set; }
public string PrimaryImageTag { get; set; }
public double? PrimaryImageAspectRatio { get; set; }
public SyncJob()
{

View File

@ -22,6 +22,12 @@ namespace MediaBrowser.Model.Sync
/// <value>The item identifier.</value>
public string ItemId { get; set; }
/// <summary>
/// Gets or sets the name of the item.
/// </summary>
/// <value>The name of the item.</value>
public string ItemName { get; set; }
/// <summary>
/// Gets or sets the media source identifier.
/// </summary>
@ -57,5 +63,15 @@ namespace MediaBrowser.Model.Sync
/// </summary>
/// <value>The date created.</value>
public DateTime DateCreated { get; set; }
/// <summary>
/// Gets or sets the primary image item identifier.
/// </summary>
/// <value>The primary image item identifier.</value>
public string PrimaryImageItemId { get; set; }
/// <summary>
/// Gets or sets the primary image tag.
/// </summary>
/// <value>The primary image tag.</value>
public string PrimaryImageTag { get; set; }
}
}

View File

@ -29,6 +29,11 @@ namespace MediaBrowser.Model.Sync
/// </summary>
/// <value>The status.</value>
public List<SyncJobItemStatus> Statuses { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [add metadata].
/// </summary>
/// <value><c>true</c> if [add metadata]; otherwise, <c>false</c>.</value>
public bool AddMetadata { get; set; }
public SyncJobItemQuery()
{

View File

@ -7,7 +7,8 @@ namespace MediaBrowser.Model.Sync
Converting = 1,
Transferring = 2,
Synced = 3,
Failed = 4,
RemovedFromDevice = 5
RemovedFromDevice = 4,
Failed = 5,
Cancelled = 6
}
}

View File

@ -23,5 +23,10 @@ namespace MediaBrowser.Model.Sync
/// </summary>
/// <value>The target identifier.</value>
public string TargetId { get; set; }
/// <summary>
/// Gets or sets the user identifier.
/// </summary>
/// <value>The user identifier.</value>
public string UserId { get; set; }
}
}

View File

@ -6,16 +6,16 @@ namespace MediaBrowser.Model.Sync
/// <summary>
/// The good
/// </summary>
Good = 0,
Low = 0,
/// <summary>
/// The better
/// </summary>
Better = 1,
Medium = 1,
/// <summary>
/// The best
/// </summary>
Best = 2
High = 2
}
}

View File

@ -105,7 +105,12 @@ namespace MediaBrowser.Server.Implementations.Devices
var val = query.SupportsUniqueIdentifier.Value;
devices = devices.Where(i => GetCapabilities(i.Id).SupportsUniqueIdentifier == val);
}
}
if (!string.IsNullOrWhiteSpace(query.UserId))
{
devices = devices.Where(i => CanAccessDevice(query.UserId, i.Id));
}
var array = devices.ToArray();
return new QueryResult<DeviceInfo>

View File

@ -40,11 +40,11 @@
"LabelStopping": "Stoppe",
"LabelCancelled": "(abgebrochen)",
"LabelFailed": "(fehlgeschlagen)",
"ButtonHelp": "Help",
"ButtonHelp": "Hilfe",
"HeaderLibraryAccess": "Bibliothekszugriff",
"HeaderChannelAccess": "Channelzugriff",
"HeaderDeviceAccess": "Device Access",
"HeaderSelectDevices": "Select Devices",
"HeaderDeviceAccess": "Ger\u00e4te Zugang",
"HeaderSelectDevices": "Ger\u00e4t w\u00e4hlen",
"LabelAbortedByServerShutdown": "(Durch herunterfahrenden Server abgebrochen)",
"LabelScheduledTaskLastRan": "Zuletzt ausgef\u00fchrt vor: {0}. Ben\u00f6tigte Zeit: {1}.",
"HeaderDeleteTaskTrigger": "Entferne Aufgabenausl\u00f6ser",
@ -254,7 +254,7 @@
"ButtonMoveRight": "Nach rechts",
"ButtonBrowseOnlineImages": "Durchsuche Onlinebilder",
"HeaderDeleteItem": "L\u00f6sche Element",
"ConfirmDeleteItem": "Deleting this item will delete it from both the file system and your media library. Are you sure you wish to continue?",
"ConfirmDeleteItem": "L\u00f6schen dieses Eintrages bedeutet das L\u00f6schen der Datei und das Entfernen aus der Medien-Bibliothek. M\u00f6chten Sie wirklich fortfahren?",
"MessagePleaseEnterNameOrId": "Bitte gib einen Namen oder eine externe Id an.",
"MessageValueNotCorrect": "Der eingegeben Wert ist nicht korrekt. Bitte versuche es noch einmal.",
"MessageItemSaved": "Element gespeichert",
@ -417,7 +417,7 @@
"HeaderMediaLocations": "Medienquellen",
"LabelFolderTypeValue": "Verzeichnistyp: {0}",
"LabelPathSubstitutionHelp": "Optional: Die Pfadersetzung kann Serverpfade zu Netzwerkfreigaben umleiten, die von Endger\u00e4ten f\u00fcr die direkte Wiedergabe genutzt werden k\u00f6nnen.",
"FolderTypeUnset": "Unset (mixed content)",
"FolderTypeUnset": "Keine Auswahl (gemischter Inhalt)",
"FolderTypeMovies": "Filme",
"FolderTypeMusic": "Musik",
"FolderTypeAdultVideos": "Videos f\u00fcr Erwachsene",
@ -593,7 +593,7 @@
"WebClientTourMobile2": "und steuert einfach andere Ger\u00e4te und Media Browser Anwendungen",
"MessageEnjoyYourStay": "Genie\u00dfe deinen Aufenthalt",
"DashboardTourDashboard": "Die Server\u00fcbersicht erlaubt es dir deinen Server und dessen Benutzer im Blick zu behalten. Somit wei\u00dft du immer wer gerade was macht und wo er sich befindet.",
"DashboardTourHelp": "In-app help provides easy buttons to open wiki pages relating to the on-screen content.",
"DashboardTourHelp": "Die In-App-Hilfe Schaltfl\u00e4che bietet eine schnelle M\u00f6glichkeit um eine Wiki-Seite zum aktuellen Inhalt zu \u00f6ffnen.",
"DashboardTourUsers": "Erstelle einfach Benutzeraccounts f\u00fcr Freunde und Familie. Jeder mit seinen individuellen Einstellungen bei Berechtigungen, Blibliothekenzugriff, Kindersicherung und mehr.",
"DashboardTourCinemaMode": "Der Kino-Modus bringt das Kinoerlebnis direkt in dein Wohnzimmer, mit der F\u00e4higkeit Trailer und benutzerdefinierte Intros vor dem Hauptfilm zu spielen.",
"DashboardTourChapters": "Aktiviere die Bildgenerierung f\u00fcr die Kapitel deiner Videos f\u00fcr eine bessere Darstellung w\u00e4hrend des Ansehens.",
@ -656,5 +656,5 @@
"LabelItemLimitHelp": "Optional. Legen Sie die maximale Anzahl der zu synchronisierenden Eintr\u00e4ge fest.",
"MessageBookPluginRequired": "Setzt die Installation des Bookshelf-Plugins voraus.",
"MessageGamePluginRequired": "Setzt die Installation des GameBrowser-Plugins voraus.",
"MessageUnsetContentHelp": "Content will be displayed as plain folders. For best results use the metadata manager to set the content types of sub-folders."
"MessageUnsetContentHelp": "Inhalte werden als Verzeichnisse dargestellt. F\u00fcr eine besser Anzeige nutzen Sie nach M\u00f6glichkeit den Meta-Data Manager und w\u00e4hlen Sie einen Medien-Typen f\u00fcr Unterverzeichnisse."
}

View File

@ -40,11 +40,11 @@
"LabelStopping": "Sto fermando",
"LabelCancelled": "(cancellato)",
"LabelFailed": "(fallito)",
"ButtonHelp": "Help",
"ButtonHelp": "Aiuto",
"HeaderLibraryAccess": "Accesso libreria",
"HeaderChannelAccess": "Accesso canali",
"HeaderDeviceAccess": "Device Access",
"HeaderSelectDevices": "Select Devices",
"HeaderDeviceAccess": "Accesso dispositivo",
"HeaderSelectDevices": "Seleziona periferiche",
"LabelAbortedByServerShutdown": "(Interrotto dalla chiusura del server)",
"LabelScheduledTaskLastRan": "Ultima esecuzione {0}, taking {1}.",
"HeaderDeleteTaskTrigger": "Elimina Operazione pianificata",
@ -254,7 +254,7 @@
"ButtonMoveRight": "Muovi a destra",
"ButtonBrowseOnlineImages": "Sfoglia le immagini Online",
"HeaderDeleteItem": "Elimina elemento",
"ConfirmDeleteItem": "Deleting this item will delete it from both the file system and your media library. Are you sure you wish to continue?",
"ConfirmDeleteItem": "L'eliminazione di questo articolo sar\u00e0 eliminarlo sia dal file system e la vostra libreria multimediale. Sei sicuro di voler continuare?",
"MessagePleaseEnterNameOrId": "Inserisci il nome o id esterno.",
"MessageValueNotCorrect": "Il valore inserito non \u00e8 corretto.Riprova di nuovo.",
"MessageItemSaved": "Elemento salvato.",
@ -401,7 +401,7 @@
"LabelYear": "Anno:",
"LabelDateOfBirth": "Data nascita:",
"LabelBirthYear": "Anno nascita:",
"LabelBirthDate": "Birth date:",
"LabelBirthDate": "Data nascita:",
"LabelDeathDate": "Anno morte:",
"HeaderRemoveMediaLocation": "Rimuovi percorso media",
"MessageConfirmRemoveMediaLocation": "Sei sicuro di voler rimuovere questa posizione?",
@ -417,7 +417,7 @@
"HeaderMediaLocations": "Posizioni Media",
"LabelFolderTypeValue": "Tipo cartella: {0}",
"LabelPathSubstitutionHelp": "Opzionale: cambio Path pu\u00f2 mappare i percorsi del server a condivisioni di rete che i clienti possono accedere per la riproduzione diretta.",
"FolderTypeUnset": "Unset (mixed content)",
"FolderTypeUnset": "Disinserito (contenuto misto)",
"FolderTypeMovies": "Film",
"FolderTypeMusic": "Musica",
"FolderTypeAdultVideos": "Video per adulti",
@ -426,7 +426,7 @@
"FolderTypeHomeVideos": "Video personali",
"FolderTypeGames": "Giochi",
"FolderTypeBooks": "Libri",
"FolderTypeTvShows": "TV",
"FolderTypeTvShows": "Tv",
"TabMovies": "Film",
"TabSeries": "Serie TV",
"TabEpisodes": "Episodi",
@ -593,7 +593,7 @@
"WebClientTourMobile2": "e controlla facilmente altri dispositivi e applicazioni Media Browser",
"MessageEnjoyYourStay": "Godetevi il vostro soggiorno",
"DashboardTourDashboard": "Il pannello di controllo del server consente di monitorare il vostro server e gli utenti. Potrai sempre sapere chi sta facendo cosa e dove sono.",
"DashboardTourHelp": "In-app help provides easy buttons to open wiki pages relating to the on-screen content.",
"DashboardTourHelp": "In-app help offre pulsanti facili da aprire le pagine wiki relative al contenuto sullo schermo.",
"DashboardTourUsers": "Facile creazione di account utente per i vostri amici e la famiglia, ognuno con le proprie autorizzazioni, accesso alla libreria, controlli parentali e altro ancora.",
"DashboardTourCinemaMode": "Modalit\u00e0 Cinema porta l'esperienza del teatro direttamente nel tuo salotto con la possibilit\u00e0 di giocare trailer e intro personalizzati prima la caratteristica principale.",
"DashboardTourChapters": "Abilita capitolo generazione di immagini per i vostri video per una presentazione pi\u00f9 gradevole durante la visualizzazione.",
@ -617,7 +617,7 @@
"MessageInvitationSentToUser": "Una e-mail \u00e8 stata inviata a {0}, invitandoli ad accettare l'invito di condivisione.",
"MessageInvitationSentToNewUser": "Una e-mail \u00e8 stata inviata a {0} invitandoli a firmare con Media Browser.",
"HeaderConnectionFailure": "Errore di connessione",
"MessageUnableToConnectToServer": "We're unable to connect to the selected server right now. Please try again later.",
"MessageUnableToConnectToServer": "Non siamo in grado di connettersi al server selezionato al momento. Si prega di riprovare pi\u00f9 tardi.",
"ButtonSelectServer": "Selezionare il server",
"MessagePluginConfigurationRequiresLocalAccess": "Per configurare questo plugin si prega di accedere al proprio server locale direttamente.",
"MessageLoggedOutParentalControl": "L'accesso \u00e8 attualmente limitato. Si prega di riprovare pi\u00f9 tardi.",
@ -635,26 +635,26 @@
"ButtonLinkMyMediaBrowserAccount": "Collega il mio account",
"MessageConnectAccountRequiredToInviteGuest": "Per invitare gli ospiti \u00e8 necessario collegare prima il tuo account browser media a questo server.",
"ButtonSync": "Sinc.",
"SyncMedia": "Sync Media",
"SyncMedia": "Sync media",
"HeaderCancelSyncJob": "Cancel Sync",
"CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
"CancelSyncJobConfirmation": "Sei sicuro di voler annullare questo lavoro di sincronizzazione?",
"TabSync": "Sinc",
"MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
"MessagePleaseSelectDeviceToSyncTo": "Selezionare un dispositivo per la sincronizzazione",
"MessageSyncJobCreated": "Sync job created.",
"LabelSyncTo": "Sync to:",
"LabelSyncJobName": "Sync job name:",
"LabelQuality": "Quality:",
"OptionHigh": "High",
"OptionMedium": "Medium",
"OptionLow": "Low",
"HeaderSettings": "Settings",
"OptionAutomaticallySyncNewContent": "Automatically sync new content",
"OptionAutomaticallySyncNewContentHelp": "New content added to this category will be automatically synced to the device.",
"OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
"OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched.",
"LabelItemLimit": "Item limit:",
"LabelItemLimitHelp": "Optional. Set a limit to the number of items that will be synced.",
"MessageBookPluginRequired": "Requires installation of the Bookshelf plugin",
"MessageGamePluginRequired": "Requires installation of the GameBrowser plugin",
"MessageUnsetContentHelp": "Content will be displayed as plain folders. For best results use the metadata manager to set the content types of sub-folders."
"LabelQuality": "Qualit\u00e0:",
"OptionHigh": "Alto",
"OptionMedium": "Medio",
"OptionLow": "Basso",
"HeaderSettings": "Configurazione",
"OptionAutomaticallySyncNewContent": "Sincronizza automaticamente nuovi contenuti",
"OptionAutomaticallySyncNewContentHelp": "Nuovi contenuti aggiunti a questa categoria viene sincronizzata automaticamente al dispositivo.",
"OptionSyncUnwatchedVideosOnly": "Sincronizza solo i video non visti",
"OptionSyncUnwatchedVideosOnlyHelp": "Solo i video non visti saranno sincronizzati, e video saranno rimossi dal dispositivo in cui sono guardato.",
"LabelItemLimit": "limite elementi:",
"LabelItemLimitHelp": "Opzionale. Impostare un limite al numero di elementi che verranno sincronizzati.",
"MessageBookPluginRequired": "Richiede l'installazione del plugin Bookshelf",
"MessageGamePluginRequired": "Richiede l'installazione del plugin GameBrowser",
"MessageUnsetContentHelp": "Il contenuto verr\u00e0 visualizzato come pianura cartelle. Per ottenere i migliori risultati utilizzare il gestore di metadati per impostare i tipi di contenuto di sottocartelle."
}

View File

@ -41,6 +41,8 @@
"LabelCancelled": "(cancelled)",
"LabelFailed": "(failed)",
"ButtonHelp": "Help",
"ButtonSave": "Save",
"MessageNoSyncJobsFound": "No sync jobs found. Create sync jobs using the Sync buttons found throughout the web interface.",
"HeaderLibraryAccess": "Library Access",
"HeaderChannelAccess": "Channel Access",
"HeaderDeviceAccess": "Device Access",
@ -664,5 +666,13 @@
"LabelItemLimitHelp": "Optional. Set a limit to the number of items that will be synced.",
"MessageBookPluginRequired": "Requires installation of the Bookshelf plugin",
"MessageGamePluginRequired": "Requires installation of the GameBrowser plugin",
"MessageUnsetContentHelp": "Content will be displayed as plain folders. For best results use the metadata manager to set the content types of sub-folders."
"MessageUnsetContentHelp": "Content will be displayed as plain folders. For best results use the metadata manager to set the content types of sub-folders.",
"SyncJobItemStatusQueued": "Queued",
"SyncJobItemStatusConverting": "Converting",
"SyncJobItemStatusTransferring": "Transferring",
"SyncJobItemStatusSynced": "Synced",
"SyncJobItemStatusFailed": "Failed",
"SyncJobItemStatusRemovedFromDevice": "Removed from device",
"SyncJobItemStatusCancelled": "Cancelled",
"MessageJobItemHasNoActions": "d"
}

View File

@ -43,8 +43,8 @@
"ButtonHelp": "Ajuda",
"HeaderLibraryAccess": "Acesso \u00e0 Biblioteca",
"HeaderChannelAccess": "Acesso ao Canal",
"HeaderDeviceAccess": "Device Access",
"HeaderSelectDevices": "Select Devices",
"HeaderDeviceAccess": "Acesso ao Dispositivo",
"HeaderSelectDevices": "Selecionar Dispositivos",
"LabelAbortedByServerShutdown": "(Abortada pelo desligamento do servidor)",
"LabelScheduledTaskLastRan": "\u00daltima execu\u00e7\u00e3o {0}, demorando {1}.",
"HeaderDeleteTaskTrigger": "Excluir Disparador da Tarefa",

View File

@ -63,16 +63,16 @@
"TabPreferences": "Einstellungen",
"TabPassword": "Passwort",
"TabLibraryAccess": "Bibliothekenzugriff",
"TabAccess": "Access",
"TabAccess": "Zugang",
"TabImage": "Bild",
"TabProfile": "Profil",
"TabMetadata": "Metadata",
"TabImages": "Bilder",
"TabNotifications": "Benachrichtigungen",
"TabCollectionTitles": "Titel",
"HeaderDeviceAccess": "Device Access",
"OptionEnableAccessFromAllDevices": "Enable access from all devices",
"DeviceAccessHelp": "This only applies to devices that can be uniquely identified and will not prevent browser access. Filtering user device access will prevent them from using new devices until they've been approved here.",
"HeaderDeviceAccess": "Ger\u00e4te Zugang",
"OptionEnableAccessFromAllDevices": "Zugriff von allen Ger\u00e4ten erlauben",
"DeviceAccessHelp": "Dies wird nur auf Ger\u00e4te angewandt die eindeutig identifiziert werden k\u00f6nnen und verhindert nicht den Web-Zugriff. Gefilterter Zugriff auf Ger\u00e4te verhindert die Nutzung neuer Ger\u00e4te solange, bis der Zugriff f\u00fcr diese freigegeben wird.",
"LabelDisplayMissingEpisodesWithinSeasons": "Zeige fehlende Episoden innerhalb von Staffeln",
"LabelUnairedMissingEpisodesWithinSeasons": "Zeige noch nicht ausgestahlte Episoden innerhalb von Staffeln",
"HeaderVideoPlaybackSettings": "Videowiedergabe Einstellungen",
@ -380,8 +380,8 @@
"LabelMaxScreenshotsPerItem": "Maximale Anzahl von Screenshots pro Element:",
"LabelMinBackdropDownloadWidth": "Minimale Breite f\u00fcr zu herunterladende Hintergr\u00fcnde:",
"LabelMinScreenshotDownloadWidth": "Minimale Breite f\u00fcr zu herunterladende Screenshot:",
"ButtonAddScheduledTaskTrigger": "F\u00fcge Task Ausl\u00f6ser hinzu",
"HeaderAddScheduledTaskTrigger": "F\u00fcge Task Ausl\u00f6ser hinzu",
"ButtonAddScheduledTaskTrigger": "Ausl\u00f6ser hinzuf\u00fcgen",
"HeaderAddScheduledTaskTrigger": "Ausl\u00f6ser hinzuf\u00fcgen",
"ButtonAdd": "Hinzuf\u00fcgen",
"LabelTriggerType": "Ausl\u00f6ser Typ:",
"OptionDaily": "T\u00e4glich",
@ -1261,7 +1261,7 @@
"HeaderTrailerReel": "Trailer Rolle",
"OptionPlayUnwatchedTrailersOnly": "Spiele nur bisher nicht gesehene Trailer",
"HeaderTrailerReelHelp": "Starte eine Trailer Rolle, um dir eine lang andauernde Playlist mit Trailern anzuschauen.",
"MessageNoTrailersFound": "No trailers found. Install the Trailer channel to enhance your movie experience by adding a library of internet trailers.",
"MessageNoTrailersFound": "Keine Trailer gefunden. Installieren Sie den Trailer-Channel um Ihre Film-Bibliothek mit Trailer aus dem Internet zu erweitern.",
"HeaderNewUsers": "Neue Benutzer",
"ButtonSignUp": "Anmeldung",
"ButtonForgotPassword": "Passwort vergessen?",

View File

@ -37,7 +37,7 @@
"ButtonOk": "OK",
"ButtonCancel": "Annulla",
"ButtonNew": "Nuovo",
"FolderTypeMixed": "Mixed content",
"FolderTypeMixed": "contenuto misto",
"FolderTypeMovies": "Film",
"FolderTypeMusic": "Musica",
"FolderTypeAdultVideos": "Video per adulti",
@ -46,9 +46,9 @@
"FolderTypeHomeVideos": "Video personali",
"FolderTypeGames": "Giochi",
"FolderTypeBooks": "Libri",
"FolderTypeTvShows": "TV",
"FolderTypeInherit": "Inherit",
"LabelContentType": "Content type:",
"FolderTypeTvShows": "Tv",
"FolderTypeInherit": "ereditare",
"LabelContentType": "Tipo di contenuto:",
"HeaderSetupLibrary": "Configura la tua libreria",
"ButtonAddMediaFolder": "Aggiungi cartella",
"LabelFolderType": "Tipo cartella",
@ -63,16 +63,16 @@
"TabPreferences": "Preferenze",
"TabPassword": "Password",
"TabLibraryAccess": "Accesso libreria",
"TabAccess": "Access",
"TabAccess": "Accesso",
"TabImage": "Immagine",
"TabProfile": "Profilo",
"TabMetadata": "Metadata",
"TabImages": "Immagini",
"TabNotifications": "Notifiche",
"TabCollectionTitles": "Titolo",
"HeaderDeviceAccess": "Device Access",
"OptionEnableAccessFromAllDevices": "Enable access from all devices",
"DeviceAccessHelp": "This only applies to devices that can be uniquely identified and will not prevent browser access. Filtering user device access will prevent them from using new devices until they've been approved here.",
"HeaderDeviceAccess": "Accesso dispositivo",
"OptionEnableAccessFromAllDevices": "Abilitare l'accesso da tutti i dispositivi",
"DeviceAccessHelp": "Questo vale solo per i dispositivi che possono essere identificati in modo univoco e non impedire l'accesso del browser. Filtraggio di accesso al dispositivo dell'utente impedir\u00e0 loro di usare nuovi dispositivi fino a quando non sono state approvate qui.",
"LabelDisplayMissingEpisodesWithinSeasons": "Visualizza gli episodi mancanti nelle stagioni",
"LabelUnairedMissingEpisodesWithinSeasons": "Visualizzare episodi mai andati in onda all'interno stagioni",
"HeaderVideoPlaybackSettings": "Impostazioni di riproduzione video",
@ -247,10 +247,10 @@
"HeaderFeatureAccess": "Caratteristiche di accesso",
"OptionAllowMediaPlayback": "Consenti la riproduzione",
"OptionAllowBrowsingLiveTv": "Consenti la navigazione sulla Tv indiretta",
"OptionAllowDeleteLibraryContent": "Allow deletion of library content",
"OptionAllowDeleteLibraryContent": "Consenti cancellazione di contenuti biblioteca",
"OptionAllowManageLiveTv": "Consenti la modifica delle operazioni pianificate della TV",
"OptionAllowRemoteControlOthers": "Allow remote control of other users",
"OptionAllowRemoteSharedDevices": "Allow remote control of shared devices",
"OptionAllowRemoteControlOthers": "Consenti controllo remoto di altri utenti",
"OptionAllowRemoteSharedDevices": "Consenti controllo remoto di dispositivi condivisi",
"OptionAllowRemoteSharedDevicesHelp": "Dispositivi DLNA sono considerati condivisa fino a quando un utente inizia controllarlo.",
"HeaderRemoteControl": "telecomando",
"OptionMissingTmdbId": "Tmdb Id mancante",
@ -380,8 +380,8 @@
"LabelMaxScreenshotsPerItem": "Massimo numero di foto per oggetto:",
"LabelMinBackdropDownloadWidth": "Massima larghezza sfondo:",
"LabelMinScreenshotDownloadWidth": "Minima larghezza foto:",
"ButtonAddScheduledTaskTrigger": "Aggiungi operazione:",
"HeaderAddScheduledTaskTrigger": "Aggiungi operazione:",
"ButtonAddScheduledTaskTrigger": "Aggiungi operazione",
"HeaderAddScheduledTaskTrigger": "Aggiungi operazione",
"ButtonAdd": "Aggiungi",
"LabelTriggerType": "Tipo Evento:",
"OptionDaily": "Giornal.",
@ -1261,7 +1261,7 @@
"HeaderTrailerReel": "Trailer b.",
"OptionPlayUnwatchedTrailersOnly": "Riproduci solo i trailer non visti",
"HeaderTrailerReelHelp": "Inizia a riprodurre una lunga playlist di trailer",
"MessageNoTrailersFound": "No trailers found. Install the Trailer channel to enhance your movie experience by adding a library of internet trailers.",
"MessageNoTrailersFound": "Nessun Trailer trovato.Installa Il plug in dei trailer per importare la libreria dei trailer da internet",
"HeaderNewUsers": "Nuovo Utente",
"ButtonSignUp": "Iscriviti",
"ButtonForgotPassword": "Dimenticato la password?",
@ -1288,15 +1288,15 @@
"HeaderParentalRatings": "Valutazioni genitori",
"HeaderVideoTypes": "Tipi Video",
"HeaderYears": "Anni",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
"HeaderAddTag": "Aggiungi Tag",
"LabelBlockItemsWithTags": "Oggetti di blocco con tag:",
"LabelTag": "Tag:",
"LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
"LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
"TabActivity": "Activity",
"LabelEnableSingleImageInDidlLimit": "Limitato a singola immagine incorporata",
"LabelEnableSingleImageInDidlLimitHelp": "Alcuni dispositivi non renderanno correttamente se pi\u00f9 immagini sono incorporati all'interno didl.",
"TabActivity": "Attivit\u00e0",
"TitleSync": "Sync",
"OptionAllowSyncContent": "Allow syncing media to devices",
"NameSeasonUnknown": "Season Unknown",
"NameSeasonNumber": "Season {0}",
"LabelNewUserNameHelp": "Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)"
"OptionAllowSyncContent": "Consenti sincronizzazione media per dispositivi",
"NameSeasonUnknown": "Stagione sconosciuto",
"NameSeasonNumber": "Stagione {0}",
"LabelNewUserNameHelp": "I nomi utente possono contenere lettere (az), numeri (0-9), trattini (-), underscore (_), apostrofi ('), e periodi (.)"
}

View File

@ -70,9 +70,9 @@
"TabImages": "Imagens",
"TabNotifications": "Notifica\u00e7\u00f5es",
"TabCollectionTitles": "T\u00edtulos",
"HeaderDeviceAccess": "Device Access",
"OptionEnableAccessFromAllDevices": "Enable access from all devices",
"DeviceAccessHelp": "This only applies to devices that can be uniquely identified and will not prevent browser access. Filtering user device access will prevent them from using new devices until they've been approved here.",
"HeaderDeviceAccess": "Acesso ao Dispositivo",
"OptionEnableAccessFromAllDevices": "Ativar o acesso de todos os dispositivos",
"DeviceAccessHelp": "Isto apenas aplica para dispositivos que podem ser identificados como \u00fanicos e n\u00e3o evitar\u00e3o o acesso do navegador. Filtrar o acesso ao dispositivo do usu\u00e1rio evitar\u00e1 que sejam usados novos dispositivos at\u00e9 que sejam aprovados aqui.",
"LabelDisplayMissingEpisodesWithinSeasons": "Exibir epis\u00f3dios que faltam dentro das temporadas",
"LabelUnairedMissingEpisodesWithinSeasons": "Exibir epis\u00f3dios por estrear dentro das temporadas",
"HeaderVideoPlaybackSettings": "Ajustes da Reprodu\u00e7\u00e3o de V\u00eddeo",

View File

@ -19,7 +19,7 @@
"TitleMediaBrowser": "Media Browser",
"ThisWizardWillGuideYou": "This wizard will help guide you through the setup process. To begin, please select your preferred language.",
"TellUsAboutYourself": "Tell us about yourself",
"ButtonQuickStartGuide": "Quick start guide",
"ButtonQuickStartGuide": "Quick start guide",
"LabelYourFirstName": "Your first name:",
"MoreUsersCanBeAddedLater": "More users can be added later within the Dashboard.",
"UserProfilesIntro": "Media Browser includes built-in support for user profiles, enabling each user to have their own display settings, playstate and parental controls.",
@ -38,6 +38,7 @@
"ButtonOk": "Ok",
"ButtonCancel": "Cancel",
"ButtonNew": "New",
"HeaderSyncJobInfo": "Sync Job",
"FolderTypeMixed": "Mixed content",
"FolderTypeMovies": "Movies",
"FolderTypeMusic": "Music",
@ -1315,5 +1316,6 @@
"OptionAllowSyncContent": "Allow syncing media to devices",
"NameSeasonUnknown": "Season Unknown",
"NameSeasonNumber": "Season {0}",
"LabelNewUserNameHelp": "Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)"
"LabelNewUserNameHelp": "Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)",
"TabSyncJobs": "Sync Jobs"
}

View File

@ -302,7 +302,6 @@
<Compile Include="Sorting\VideoBitRateComparer.cs" />
<Compile Include="Sync\AppSyncProvider.cs" />
<Compile Include="Sync\CloudSyncProvider.cs" />
<Compile Include="Sync\MockSyncProvider.cs" />
<Compile Include="Sync\SyncJobProcessor.cs" />
<Compile Include="Sync\SyncManager.cs" />
<Compile Include="Sync\SyncRepository.cs" />

View File

@ -30,6 +30,20 @@ namespace MediaBrowser.Server.Implementations.Sync
});
}
public IEnumerable<SyncTarget> GetSyncTargets(string userId)
{
return _deviceManager.GetDevices(new DeviceQuery
{
SupportsSync = true,
UserId = userId
}).Items.Select(i => new SyncTarget
{
Id = i.Id,
Name = i.Name
});
}
public DeviceProfile GetDeviceProfile(SyncTarget target)
{
return new DeviceProfile();

View File

@ -2,7 +2,6 @@
using MediaBrowser.Controller.Sync;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Sync;
using System;
using System.Collections.Generic;
using System.Linq;
@ -10,7 +9,7 @@ namespace MediaBrowser.Server.Implementations.Sync
{
public class CloudSyncProvider : ISyncProvider
{
private ICloudSyncProvider[] _providers = new ICloudSyncProvider[] {};
private ICloudSyncProvider[] _providers = {};
public CloudSyncProvider(IApplicationHost appHost)
{
@ -22,6 +21,11 @@ namespace MediaBrowser.Server.Implementations.Sync
return new List<SyncTarget>();
}
public IEnumerable<SyncTarget> GetSyncTargets(string userId)
{
return new List<SyncTarget>();
}
public DeviceProfile GetDeviceProfile(SyncTarget target)
{
return new DeviceProfile();

View File

@ -1,33 +0,0 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Sync;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Sync;
using System.Collections.Generic;
namespace MediaBrowser.Server.Implementations.Sync
{
public class MockSyncProvider : ISyncProvider
{
public string Name
{
get { return "Test Sync"; }
}
public IEnumerable<SyncTarget> GetSyncTargets()
{
return new List<SyncTarget>
{
new SyncTarget
{
Id = GetType().Name.GetMD5().ToString("N"),
Name = Name
}
};
}
public DeviceProfile GetDeviceProfile(SyncTarget target)
{
return new DeviceProfile();
}
}
}

View File

@ -81,6 +81,7 @@ namespace MediaBrowser.Server.Implementations.Sync
{
Id = Guid.NewGuid().ToString("N"),
ItemId = itemId,
ItemName = GetSyncJobItemName(item),
JobId = job.Id,
TargetId = job.TargetId,
DateCreated = DateTime.UtcNow
@ -98,6 +99,11 @@ namespace MediaBrowser.Server.Implementations.Sync
await UpdateJobStatus(job, jobItems).ConfigureAwait(false);
}
private string GetSyncJobItemName(BaseItem item)
{
return item.Name;
}
public Task UpdateJobStatus(string id)
{
var job = _syncRepo.GetJob(id);

View File

@ -73,11 +73,7 @@ namespace MediaBrowser.Server.Implementations.Sync
if (string.IsNullOrWhiteSpace(request.Name))
{
if (request.Category.HasValue)
{
request.Name = request.Category.Value.ToString();
}
else if (request.ItemIds.Count == 1)
if (request.ItemIds.Count == 1)
{
request.Name = GetDefaultName(_libraryManager.GetItemById(request.ItemIds[0]));
}
@ -132,21 +128,49 @@ namespace MediaBrowser.Server.Implementations.Sync
};
}
public QueryResult<SyncJob> GetJobs(SyncJobQuery query)
public Task UpdateJob(SyncJob job)
{
// Get fresh from the db and only update the fields that are supported to be changed.
var instance = _repo.GetJob(job.Id);
instance.Name = job.Name;
instance.Quality = job.Quality;
instance.UnwatchedOnly = job.UnwatchedOnly;
instance.SyncNewContent = job.SyncNewContent;
instance.ItemLimit = job.ItemLimit;
return _repo.Update(instance);
}
public async Task<QueryResult<SyncJob>> GetJobs(SyncJobQuery query)
{
var result = _repo.GetJobs(query);
result.Items.ForEach(FillMetadata);
foreach (var item in result.Items)
{
await FillMetadata(item).ConfigureAwait(false);
}
return result;
}
private void FillMetadata(SyncJob job)
private async Task FillMetadata(SyncJob job)
{
var item = job.RequestedItemIds
.Select(_libraryManager.GetItemById)
.FirstOrDefault(i => i != null);
if (item == null)
{
var processor = new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager, _tvSeriesManager);
var user = _userManager.GetUserById(job.UserId);
item = (await processor
.GetItemsForSync(job.Category, job.ParentId, job.RequestedItemIds, user, job.UnwatchedOnly).ConfigureAwait(false))
.FirstOrDefault();
}
if (item != null)
{
var hasSeries = item as IHasSeries;
@ -162,13 +186,25 @@ namespace MediaBrowser.Server.Implementations.Sync
}
var primaryImage = item.GetImageInfo(ImageType.Primary, 0);
var itemWithImage = item;
if (primaryImage == null)
{
var parentWithImage = item.Parents.FirstOrDefault(i => i.HasImage(ImageType.Primary));
if (parentWithImage != null)
{
itemWithImage = parentWithImage;
primaryImage = parentWithImage.GetImageInfo(ImageType.Primary, 0);
}
}
if (primaryImage != null)
{
try
{
job.PrimaryImageTag = _imageProcessor.GetImageCacheTag(item, ImageType.Primary);
job.PrimaryImageItemId = item.Id.ToString("N");
job.PrimaryImageTag = _imageProcessor.GetImageCacheTag(itemWithImage, ImageType.Primary);
job.PrimaryImageItemId = itemWithImage.Id.ToString("N");
}
catch (Exception ex)
@ -179,6 +215,44 @@ namespace MediaBrowser.Server.Implementations.Sync
}
}
private void FillMetadata(SyncJobItem jobItem)
{
var item = _libraryManager.GetItemById(jobItem.ItemId);
if (item == null)
{
return;
}
var primaryImage = item.GetImageInfo(ImageType.Primary, 0);
var itemWithImage = item;
if (primaryImage == null)
{
var parentWithImage = item.Parents.FirstOrDefault(i => i.HasImage(ImageType.Primary));
if (parentWithImage != null)
{
itemWithImage = parentWithImage;
primaryImage = parentWithImage.GetImageInfo(ImageType.Primary, 0);
}
}
if (primaryImage != null)
{
try
{
jobItem.PrimaryImageTag = _imageProcessor.GetImageCacheTag(itemWithImage, ImageType.Primary);
jobItem.PrimaryImageItemId = itemWithImage.Id.ToString("N");
}
catch (Exception ex)
{
_logger.ErrorException("Error getting image info", ex);
}
}
}
public Task CancelJob(string id)
{
return _repo.DeleteJob(id);
@ -198,7 +272,7 @@ namespace MediaBrowser.Server.Implementations.Sync
private IEnumerable<SyncTarget> GetSyncTargets(ISyncProvider provider, string userId)
{
return provider.GetSyncTargets().Select(i => new SyncTarget
return provider.GetSyncTargets(userId).Select(i => new SyncTarget
{
Name = i.Name,
Id = GetSyncTargetId(provider, i)
@ -330,7 +404,14 @@ namespace MediaBrowser.Server.Implementations.Sync
public QueryResult<SyncJobItem> GetJobItems(SyncJobItemQuery query)
{
return _repo.GetJobItems(query);
var result = _repo.GetJobItems(query);
if (query.AddMetadata)
{
result.Items.ForEach(FillMetadata);
}
return result;
}
private SyncedItem GetJobItemInfo(SyncJobItem jobItem)
@ -449,7 +530,7 @@ namespace MediaBrowser.Server.Implementations.Sync
}
response.ItemIdsToRemove = response.ItemIdsToRemove.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
return response;
}

View File

@ -36,7 +36,7 @@ namespace MediaBrowser.Server.Implementations.Sync
public async Task Initialize()
{
var dbFile = Path.Combine(_appPaths.DataPath, "sync9.db");
var dbFile = Path.Combine(_appPaths.DataPath, "sync10.db");
_connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false);
@ -45,7 +45,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, MediaSourceId TEXT, JobId TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT)",
"create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT)",
"create index if not exists idx_SyncJobItems on SyncJobs(Id)",
//pragmas
@ -90,21 +90,22 @@ namespace MediaBrowser.Server.Implementations.Sync
_saveJobCommand.Parameters.Add(_saveJobCommand, "@ItemCount");
_saveJobItemCommand = _connection.CreateCommand();
_saveJobItemCommand.CommandText = "replace into SyncJobItems (Id, ItemId, MediaSourceId, JobId, OutputPath, Status, TargetId, DateCreated, Progress) values (@Id, @ItemId, @MediaSourceId, @JobId, @OutputPath, @Status, @TargetId, @DateCreated, @Progress)";
_saveJobItemCommand.CommandText = "replace into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, OutputPath, Status, TargetId, DateCreated, Progress) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @OutputPath, @Status, @TargetId, @DateCreated, @Progress)";
_saveJobItemCommand.Parameters.Add(_saveJobCommand, "@Id");
_saveJobItemCommand.Parameters.Add(_saveJobCommand, "@ItemId");
_saveJobItemCommand.Parameters.Add(_saveJobCommand, "@MediaSourceId");
_saveJobItemCommand.Parameters.Add(_saveJobCommand, "@JobId");
_saveJobItemCommand.Parameters.Add(_saveJobCommand, "@OutputPath");
_saveJobItemCommand.Parameters.Add(_saveJobCommand, "@Status");
_saveJobItemCommand.Parameters.Add(_saveJobCommand, "@TargetId");
_saveJobItemCommand.Parameters.Add(_saveJobCommand, "@DateCreated");
_saveJobItemCommand.Parameters.Add(_saveJobCommand, "@Progress");
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@Id");
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@ItemId");
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@ItemName");
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@MediaSourceId");
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@JobId");
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@OutputPath");
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@Status");
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@TargetId");
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@DateCreated");
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@Progress");
}
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, MediaSourceId, JobId, OutputPath, Status, TargetId, DateCreated, Progress from SyncJobItems";
private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, OutputPath, Status, TargetId, DateCreated, Progress from SyncJobItems";
public SyncJob GetJob(string id)
{
@ -366,6 +367,11 @@ namespace MediaBrowser.Server.Implementations.Sync
whereClauses.Add("TargetId=@TargetId");
cmd.Parameters.Add(cmd, "@TargetId", DbType.String).Value = query.TargetId;
}
if (!string.IsNullOrWhiteSpace(query.UserId))
{
whereClauses.Add("UserId=@UserId");
cmd.Parameters.Add(cmd, "@UserId", DbType.String).Value = query.UserId;
}
var whereTextWithoutPaging = whereClauses.Count == 0 ?
string.Empty :
@ -547,6 +553,7 @@ namespace MediaBrowser.Server.Implementations.Sync
_saveJobItemCommand.GetParameter(index++).Value = new Guid(jobItem.Id);
_saveJobItemCommand.GetParameter(index++).Value = jobItem.ItemId;
_saveJobItemCommand.GetParameter(index++).Value = jobItem.ItemName;
_saveJobItemCommand.GetParameter(index++).Value = jobItem.MediaSourceId;
_saveJobItemCommand.GetParameter(index++).Value = jobItem.JobId;
_saveJobItemCommand.GetParameter(index++).Value = jobItem.OutputPath;
@ -602,28 +609,33 @@ namespace MediaBrowser.Server.Implementations.Sync
if (!reader.IsDBNull(2))
{
info.MediaSourceId = reader.GetString(2);
info.ItemName = reader.GetString(2);
}
info.JobId = reader.GetString(3);
if (!reader.IsDBNull(4))
if (!reader.IsDBNull(3))
{
info.OutputPath = reader.GetString(4);
info.MediaSourceId = reader.GetString(3);
}
info.JobId = reader.GetString(4);
if (!reader.IsDBNull(5))
{
info.Status = (SyncJobItemStatus)Enum.Parse(typeof(SyncJobItemStatus), reader.GetString(5), true);
info.OutputPath = reader.GetString(5);
}
info.TargetId = reader.GetString(6);
info.DateCreated = reader.GetDateTime(7);
if (!reader.IsDBNull(8))
if (!reader.IsDBNull(6))
{
info.Progress = reader.GetDouble(8);
info.Status = (SyncJobItemStatus)Enum.Parse(typeof(SyncJobItemStatus), reader.GetString(6), true);
}
info.TargetId = reader.GetString(7);
info.DateCreated = reader.GetDateTime(8);
if (!reader.IsDBNull(9))
{
info.Progress = reader.GetDouble(9);
}
return info;

View File

@ -334,6 +334,7 @@ namespace MediaBrowser.WebDashboard.Api
"chromecast.js",
"backdrops.js",
"sync.js",
"syncjob.js",
"playlistmanager.js",
"mediaplayer.js",

View File

@ -93,6 +93,12 @@
<Content Include="dashboard-ui\forgotpasswordpin.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\mysync.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\mysyncjob.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\forgotpassword.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -102,6 +108,9 @@
<Content Include="dashboard-ui\scripts\selectserver.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\syncjob.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\syncsettings.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -114,6 +123,9 @@
<Content Include="dashboard-ui\selectserver.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\syncjob.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\syncsettings.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>