diff --git a/MediaBrowser.Api/Sync/SyncService.cs b/MediaBrowser.Api/Sync/SyncService.cs index 31442c1d94..a7467c12f1 100644 --- a/MediaBrowser.Api/Sync/SyncService.cs +++ b/MediaBrowser.Api/Sync/SyncService.cs @@ -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> { @@ -118,9 +123,9 @@ namespace MediaBrowser.Api.Sync return ToOptimizedResult(result); } - public object Get(GetSyncJobs request) + public async Task 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); + } } } diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs index 6cad197369..59136c0e6f 100644 --- a/MediaBrowser.Controller/Sync/ISyncManager.cs +++ b/MediaBrowser.Controller/Sync/ISyncManager.cs @@ -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. /// /// QueryResult<SyncJob>. - QueryResult GetJobs(SyncJobQuery query); + Task> GetJobs(SyncJobQuery query); /// /// Gets the job items. @@ -37,6 +37,13 @@ namespace MediaBrowser.Controller.Sync /// SyncJob. SyncJob GetJob(string id); + /// + /// Updates the job. + /// + /// The job. + /// Task. + Task UpdateJob(SyncJob job); + /// /// Cancels the job. /// diff --git a/MediaBrowser.Controller/Sync/ISyncProvider.cs b/MediaBrowser.Controller/Sync/ISyncProvider.cs index 5ebdee2070..af08edb5ea 100644 --- a/MediaBrowser.Controller/Sync/ISyncProvider.cs +++ b/MediaBrowser.Controller/Sync/ISyncProvider.cs @@ -18,6 +18,13 @@ namespace MediaBrowser.Controller.Sync /// IEnumerable<SyncTarget>. IEnumerable GetSyncTargets(); + /// + /// Gets the synchronize targets. + /// + /// The user identifier. + /// IEnumerable<SyncTarget>. + IEnumerable GetSyncTargets(string userId); + /// /// Gets the device profile. /// diff --git a/MediaBrowser.Model/Devices/DeviceQuery.cs b/MediaBrowser.Model/Devices/DeviceQuery.cs index c3b4313f46..2cd2389d89 100644 --- a/MediaBrowser.Model/Devices/DeviceQuery.cs +++ b/MediaBrowser.Model/Devices/DeviceQuery.cs @@ -18,5 +18,10 @@ namespace MediaBrowser.Model.Devices /// /// null if [supports synchronize] contains no value, true if [supports synchronize]; otherwise, false. public bool? SupportsSync { get; set; } + /// + /// Gets or sets the user identifier. + /// + /// The user identifier. + public string UserId { get; set; } } } diff --git a/MediaBrowser.Model/Sync/SyncJob.cs b/MediaBrowser.Model/Sync/SyncJob.cs index 92662d7bbf..24680d1720 100644 --- a/MediaBrowser.Model/Sync/SyncJob.cs +++ b/MediaBrowser.Model/Sync/SyncJob.cs @@ -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() { diff --git a/MediaBrowser.Model/Sync/SyncJobItem.cs b/MediaBrowser.Model/Sync/SyncJobItem.cs index d9fb1ed095..4090d82b0b 100644 --- a/MediaBrowser.Model/Sync/SyncJobItem.cs +++ b/MediaBrowser.Model/Sync/SyncJobItem.cs @@ -22,6 +22,12 @@ namespace MediaBrowser.Model.Sync /// The item identifier. public string ItemId { get; set; } + /// + /// Gets or sets the name of the item. + /// + /// The name of the item. + public string ItemName { get; set; } + /// /// Gets or sets the media source identifier. /// @@ -57,5 +63,15 @@ namespace MediaBrowser.Model.Sync /// /// The date created. public DateTime DateCreated { get; set; } + /// + /// Gets or sets the primary image item identifier. + /// + /// The primary image item identifier. + public string PrimaryImageItemId { get; set; } + /// + /// Gets or sets the primary image tag. + /// + /// The primary image tag. + public string PrimaryImageTag { get; set; } } } diff --git a/MediaBrowser.Model/Sync/SyncJobItemQuery.cs b/MediaBrowser.Model/Sync/SyncJobItemQuery.cs index f2cf781a3f..d211382049 100644 --- a/MediaBrowser.Model/Sync/SyncJobItemQuery.cs +++ b/MediaBrowser.Model/Sync/SyncJobItemQuery.cs @@ -29,6 +29,11 @@ namespace MediaBrowser.Model.Sync /// /// The status. public List Statuses { get; set; } + /// + /// Gets or sets a value indicating whether [add metadata]. + /// + /// true if [add metadata]; otherwise, false. + public bool AddMetadata { get; set; } public SyncJobItemQuery() { diff --git a/MediaBrowser.Model/Sync/SyncJobItemStatus.cs b/MediaBrowser.Model/Sync/SyncJobItemStatus.cs index 606f8cde44..913f9e259c 100644 --- a/MediaBrowser.Model/Sync/SyncJobItemStatus.cs +++ b/MediaBrowser.Model/Sync/SyncJobItemStatus.cs @@ -7,7 +7,8 @@ namespace MediaBrowser.Model.Sync Converting = 1, Transferring = 2, Synced = 3, - Failed = 4, - RemovedFromDevice = 5 + RemovedFromDevice = 4, + Failed = 5, + Cancelled = 6 } } diff --git a/MediaBrowser.Model/Sync/SyncJobQuery.cs b/MediaBrowser.Model/Sync/SyncJobQuery.cs index 2af06bcfa4..35f0e076df 100644 --- a/MediaBrowser.Model/Sync/SyncJobQuery.cs +++ b/MediaBrowser.Model/Sync/SyncJobQuery.cs @@ -23,5 +23,10 @@ namespace MediaBrowser.Model.Sync /// /// The target identifier. public string TargetId { get; set; } + /// + /// Gets or sets the user identifier. + /// + /// The user identifier. + public string UserId { get; set; } } } diff --git a/MediaBrowser.Model/Sync/SyncQuality.cs b/MediaBrowser.Model/Sync/SyncQuality.cs index f915e27686..d34ad22c28 100644 --- a/MediaBrowser.Model/Sync/SyncQuality.cs +++ b/MediaBrowser.Model/Sync/SyncQuality.cs @@ -6,16 +6,16 @@ namespace MediaBrowser.Model.Sync /// /// The good /// - Good = 0, + Low = 0, /// /// The better /// - Better = 1, + Medium = 1, /// /// The best /// - Best = 2 + High = 2 } } diff --git a/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs b/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs index 3810fec667..99fa40789e 100644 --- a/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs +++ b/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs @@ -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 diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json index 051e8a7453..3b34c2ca50 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json @@ -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." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/it.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/it.json index f6d57b44cb..8892ce5f86 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/it.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/it.json @@ -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." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index ed52684c1a..02fdf9b938 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -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" } diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json index 96f55451cf..76ce474cfa 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json @@ -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", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/de.json b/MediaBrowser.Server.Implementations/Localization/Server/de.json index fb886e32de..5571fa71aa 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/de.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/de.json @@ -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?", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/it.json b/MediaBrowser.Server.Implementations/Localization/Server/it.json index c551052bd5..0835b2ef52 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/it.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/it.json @@ -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 (.)" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json b/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json index 4c3b9c6bbe..0ae8a400f8 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json @@ -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", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 64b183b7e6..cf4f0c4bf5 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -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" } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index f9f482b96a..4e698b12f3 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -302,7 +302,6 @@ - diff --git a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs index deef503eaf..8f6129dca9 100644 --- a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs +++ b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs @@ -30,6 +30,20 @@ namespace MediaBrowser.Server.Implementations.Sync }); } + public IEnumerable 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(); diff --git a/MediaBrowser.Server.Implementations/Sync/CloudSyncProvider.cs b/MediaBrowser.Server.Implementations/Sync/CloudSyncProvider.cs index fd12b1f8aa..da3ecdfa66 100644 --- a/MediaBrowser.Server.Implementations/Sync/CloudSyncProvider.cs +++ b/MediaBrowser.Server.Implementations/Sync/CloudSyncProvider.cs @@ -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(); } + public IEnumerable GetSyncTargets(string userId) + { + return new List(); + } + public DeviceProfile GetDeviceProfile(SyncTarget target) { return new DeviceProfile(); diff --git a/MediaBrowser.Server.Implementations/Sync/MockSyncProvider.cs b/MediaBrowser.Server.Implementations/Sync/MockSyncProvider.cs deleted file mode 100644 index 7d29446b92..0000000000 --- a/MediaBrowser.Server.Implementations/Sync/MockSyncProvider.cs +++ /dev/null @@ -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 GetSyncTargets() - { - return new List - { - new SyncTarget - { - Id = GetType().Name.GetMD5().ToString("N"), - Name = Name - } - }; - } - - public DeviceProfile GetDeviceProfile(SyncTarget target) - { - return new DeviceProfile(); - } - } -} diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 44e95f07d6..97c6a6dc89 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -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); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 199c6a9751..7e8db3e6a4 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -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 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> 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 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 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; } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 323e3f964f..09c1b316ef 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -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.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.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(_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); + if (!reader.IsDBNull(6)) + { + info.Status = (SyncJobItemStatus)Enum.Parse(typeof(SyncJobItemStatus), reader.GetString(6), true); + } - info.DateCreated = reader.GetDateTime(7); + info.TargetId = reader.GetString(7); - if (!reader.IsDBNull(8)) + info.DateCreated = reader.GetDateTime(8); + + if (!reader.IsDBNull(9)) { - info.Progress = reader.GetDouble(8); + info.Progress = reader.GetDouble(9); } return info; diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index d727dda6e3..2f9f3f5f57 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -334,6 +334,7 @@ namespace MediaBrowser.WebDashboard.Api "chromecast.js", "backdrops.js", "sync.js", + "syncjob.js", "playlistmanager.js", "mediaplayer.js", diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 166d3ce67d..df8f4072a5 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -93,6 +93,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -102,6 +108,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -114,6 +123,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest