Bladeren bron

some initial work on cloud sync

Luke Pulverenti 10 jaren geleden
bovenliggende
commit
7d415fc2fd

+ 4 - 1
MediaBrowser.Api/Sync/SyncService.cs

@@ -211,6 +211,9 @@ namespace MediaBrowser.Api.Sync
                 throw new ArgumentException("The job item is not yet ready for transfer.");
             }
 
+            var task = _syncManager.ReportSyncJobItemTransferBeginning(request.Id);
+            Task.WaitAll(task);
+
             return ToStaticFileResult(jobItem.OutputPath);
         }
 
@@ -235,7 +238,7 @@ namespace MediaBrowser.Api.Sync
                     }
                 };
 
-                var items = request.ItemIds.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries)
+                var items = request.ItemIds.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                     .Select(_libraryManager.GetItemById)
                     .Where(i => i != null);
 

+ 6 - 7
MediaBrowser.Controller/Entities/Folder.cs

@@ -245,14 +245,13 @@ namespace MediaBrowser.Controller.Entities
         protected virtual IEnumerable<string> GetIndexByOptions()
         {
             return new List<string> {            
-                {LocalizedStrings.Instance.GetString("NoneDispPref")}, 
-                {LocalizedStrings.Instance.GetString("PerformerDispPref")},
-                {LocalizedStrings.Instance.GetString("GenreDispPref")},
-                {LocalizedStrings.Instance.GetString("DirectorDispPref")},
-                {LocalizedStrings.Instance.GetString("YearDispPref")},
-                {LocalizedStrings.Instance.GetString("StudioDispPref")}
+                {"None"}, 
+                {"Performer"},
+                {"Genre"},
+                {"Director"},
+                {"Year"},
+                {"Studio"}
             };
-
         }
 
         /// <summary>

+ 4 - 4
MediaBrowser.Controller/Entities/TV/Season.cs

@@ -81,10 +81,10 @@ namespace MediaBrowser.Controller.Entities.TV
         protected override IEnumerable<string> GetIndexByOptions()
         {
             return new List<string> {            
-                {LocalizedStrings.Instance.GetString("NoneDispPref")}, 
-                {LocalizedStrings.Instance.GetString("PerformerDispPref")},
-                {LocalizedStrings.Instance.GetString("DirectorDispPref")},
-                {LocalizedStrings.Instance.GetString("YearDispPref")},
+                {"None"}, 
+                {"Performer"},
+                {"Director"},
+                {"Year"},
             };
         }
 

+ 4 - 4
MediaBrowser.Controller/Entities/TV/Series.cs

@@ -133,10 +133,10 @@ namespace MediaBrowser.Controller.Entities.TV
         protected override IEnumerable<string> GetIndexByOptions()
         {
             return new List<string> {            
-                {LocalizedStrings.Instance.GetString("NoneDispPref")}, 
-                {LocalizedStrings.Instance.GetString("PerformerDispPref")},
-                {LocalizedStrings.Instance.GetString("DirectorDispPref")},
-                {LocalizedStrings.Instance.GetString("YearDispPref")},
+                {"None"}, 
+                {"Performer"},
+                {"Director"},
+                {"Year"},
             };
         }
 

+ 0 - 287
MediaBrowser.Controller/Localization/BaseStrings.cs

@@ -1,287 +0,0 @@
-
-namespace MediaBrowser.Controller.Localization
-{
-    public class BaseStrings : LocalizedStringData
-    {
-        public BaseStrings()
-        {
-            ThisVersion = "1.0002";
-            Prefix = LocalizedStrings.BasePrefix;
-        }
-
-
-
-        //Config Panel
-        public string ConfigConfig = "Configuration";
-        public string VersionConfig = "Version";
-        public string MediaOptionsConfig = "Media Options";
-        public string ThemesConfig = "Theme Options";
-        public string ParentalControlConfig = "Parental Control";
-        public string ContinueConfig = "Continue";
-        public string ResetDefaultsConfig = "Reset Defaults";
-        public string ClearCacheConfig = "Clear Cache";
-        public string UnlockConfig = "Unlock";
-        public string GeneralConfig = "General";
-        public string EnableScreenSaverConfig = "Screen Saver";
-        public string SSTimeOutConfig = "Timeout (mins)";
-        public string TrackingConfig = "Tracking";
-        public string AssumeWatchedIfOlderThanConfig = "Assume Played If Older Than";
-        public string MetadataConfig = "Metadata";
-        public string EnableInternetProvidersConfig = "Allow Internet Providers";
-        public string UpdatesConfig = "Updates";
-        public string AutomaticUpdatesConfig = "Check For Updates";
-        public string LoggingConfig = "Logging";
-        public string BetaUpdatesConfig = "Beta Updates";
-        public string GlobalConfig = "Global";
-        public string EnableEHSConfig = "Enable EHS";
-        public string ShowClockConfig = "Show Clock";
-        public string DimUnselectedPostersConfig = "Dim Unselected Posters";
-        public string HideFocusFrameConfig = "Hide Focus Frame";
-        public string AlwaysShowDetailsConfig = "Always Show Details";
-        public string ExcludeRemoteContentInSearchesConfig = "Exclude Remote Content In Searches";
-        public string EnhancedMouseSupportConfig = "Enhanced Mouse Support";
-        public string ViewsConfig = "Views";
-        public string PosterGridSpacingConfig = "Poster Grid Spacing";
-        public string ThumbWidthSplitConfig = "Thumb Width Split";
-        public string BreadcrumbCountConfig = "Breadcrumb Count";
-        public string ShowFanArtonViewsConfig = "Show Fan Art on Views";
-        public string ShowInitialFolderBackgroundConfig = "Show Initial Folder Background";
-        public string ShowThemeBackgroundConfig = "Show Theme Background";
-        public string ShowHDOverlayonPostersConfig = "Show HD Overlay on Posters";
-        public string ShowIcononRemoteContentConfig = "Show Icon on Remote Content";
-        public string EnableAdvancedCmdsConfig = "Enable Advanced Commands";
-        public string MediaTrackingConfig = "Media Tracking";
-        public string RememberFolderIndexingConfig = "Remember Folder Indexing";
-        public string ShowUnwatchedCountConfig = "Show Unplayed Count";
-        public string WatchedIndicatoronFoldersConfig = "Played Indicator on Folders";
-        public string HighlightUnwatchedItemsConfig = "Highlight Unplayed Items";
-        public string WatchedIndicatoronVideosConfig = "Played Indicator on Items";
-        public string WatchedIndicatorinDetailViewConfig = "Played Indicator in Detail View";
-        public string DefaultToFirstUnwatchedItemConfig = "Default To First Unplayed Item";
-        public string GeneralBehaviorConfig = "General Behavior";
-        public string AllowNestedMovieFoldersConfig = "Allow Nested Movie Folders";
-        public string AutoEnterSingleFolderItemsConfig = "Auto Enter Single Folder Items";
-        public string MultipleFileBehaviorConfig = "Multiple File Behavior";
-        public string TreatMultipleFilesAsSingleMovieConfig = "Treat Multiple Files As Single Movie";
-        public string MultipleFileSizeLimitConfig = "Multiple File Size Limit";
-        public string MBThemeConfig = "Media Browser Theme";
-        public string VisualThemeConfig = "Visual Theme";
-        public string ColorSchemeConfig = "Color Scheme *";
-        public string FontSizeConfig = "Font Size *";
-        public string RequiresRestartConfig = "* Requires a restart to take effect.";
-        public string ThemeSettingsConfig = "Theme Specific Settings";
-        public string ShowConfigButtonConfig = "Show Config Button";
-        public string AlphaBlendingConfig = "Alpha Blending";
-        public string SecurityPINConfig = "Security PIN";
-        public string PCUnlockedTxtConfig = "Parental Controls are Temporarily Unlocked.  You cannot change values unless you re-lock.";
-        public string RelockBtnConfig = "Re-Lock";
-        public string EnableParentalBlocksConfig = "Enable Parental Blocks";
-        public string MaxAllowedRatingConfig = "Max Allowed Rating ";
-        public string BlockUnratedContentConfig = "Block Unrated Content";
-        public string HideBlockedContentConfig = "Hide Blocked Content";
-        public string UnlockonPINEntryConfig = "Unlock on PIN Entry";
-        public string UnlockPeriodHoursConfig = "Unlock Period (Hours)";
-        public string EnterNewPINConfig = "Enter New PIN";
-        public string RandomizeBackdropConfig = "Randomize";
-        public string RotateBackdropConfig = "Rotate";
-        public string UpdateLibraryConfig = "Update Library";
-        public string BackdropSettingsConfig = "Backdrop Settings";
-        public string BackdropRotationIntervalConfig = "Rotation Time";
-        public string BackdropTransitionIntervalConfig = "Transition Time";
-        public string BackdropLoadDelayConfig = "Load Delay";
-        public string AutoScrollTextConfig = "Auto Scroll Overview";
-        public string SortYearsAscConfig = "Sort by Year in Ascending Order";
-        public string AutoValidateConfig = "Automatically Validate Items";
-        public string SaveLocalMetaConfig = "Save Locally";
-        public string HideEmptyFoldersConfig = "Hide Empty TV Folders";
-
-
-        //EHS        
-        public string RecentlyWatchedEHS = "last played";
-        public string RecentlyAddedEHS = "last added";
-        public string RecentlyAddedUnwatchedEHS = "last added unplayed";
-        public string WatchedEHS = "Played";
-        public string AddedEHS = "Added";
-        public string UnwatchedEHS = "Unplayed";
-        public string AddedOnEHS = "Added on";
-        public string OnEHS = "on";
-        public string OfEHS = "of";
-        public string NoItemsEHS = "No Items To Show";
-        public string VariousEHS = "(various)";
-
-        //Context menu
-        public string CloseCMenu = "Close";
-        public string PlayMenuCMenu = "Play Menu";
-        public string ItemMenuCMenu = "Item Menu";
-        public string PlayAllCMenu = "Play All";
-        public string PlayAllFromHereCMenu = "Play All From Here";
-        public string ResumeCMenu = "Resume";
-        public string MarkUnwatchedCMenu = "Mark Unplayed";
-        public string MarkWatchedCMenu = "Mark Played";
-        public string ShufflePlayCMenu = "Shuffle Play";
-
-        //Media Detail Page
-        public string GeneralDetail = "General";
-        public string ActorsDetail = "Actors";
-        public string ArtistsDetail = "Artists";
-        public string PlayDetail = "Play";
-        public string ResumeDetail = "Resume";
-        public string RefreshDetail = "Refresh";
-        public string PlayTrailersDetail = "Trailer";
-        public string CacheDetail = "Cache 2 xml";
-        public string DeleteDetail = "Delete";
-        public string TMDBRatingDetail = "TMDb Rating";
-        public string OutOfDetail = "out of";
-        public string DirectorDetail = "Director";
-        public string ComposerDetail = "Composer";
-        public string HostDetail = "Host";
-        public string RuntimeDetail = "Runtime";
-        public string NextItemDetail = "Next";
-        public string PreviousItemDetail = "Previous";
-        public string FirstAiredDetail = "First aired";
-        public string LastPlayedDetail = "Last played";
-        public string TrackNumberDetail = "Track";
-
-        public string DirectedByDetail = "Directed By: ";
-        public string WrittenByDetail = "Written By: ";
-        public string ComposedByDetail = "Composed By: ";
-
-        //Display Prefs
-        public string ViewDispPref = "View";
-        public string ViewSearch = "Search";
-        public string CoverFlowDispPref = "Cover Flow";
-        public string DetailDispPref = "Detail";
-        public string PosterDispPref = "Poster";
-        public string ThumbDispPref = "Thumb";
-        public string ThumbStripDispPref = "Thumb Strip";
-        public string ShowLabelsDispPref = "Show Labels";
-        public string VerticalScrollDispPref = "Vertical Scroll";
-        public string UseBannersDispPref = "Use Banners";
-        public string UseCoverflowDispPref = "Use Coverflow Style";
-        public string ThumbSizeDispPref = "Thumb Size";
-        public string NameDispPref = "Name";
-        public string DateDispPref = "Date";
-        public string RatingDispPref = "User Rating";
-        public string OfficialRatingDispPref = "Rating";
-        public string RuntimeDispPref = "Runtime";
-        public string UnWatchedDispPref = "Unplayed";
-        public string YearDispPref = "Year";
-        public string NoneDispPref = "None";
-        public string PerformerDispPref = "Performer";
-        public string ActorDispPref = "Actor";
-        public string GenreDispPref = "Genre";
-        public string DirectorDispPref = "Director";
-        public string StudioDispPref = "Studio";
-
-        //Dialog boxes
-        //public string BrokenEnvironmentDial = "Application will now close due to broken MediaCenterEnvironment object, possibly due to 5 minutes of idle time and/or running with TVPack installed.";
-        //public string InitialConfigDial = "Initial configuration is complete, please restart Media Browser";
-        //public string DeleteMediaDial = "Are you sure you wish to delete this media item?";
-        //public string DeleteMediaCapDial = "Delete Confirmation";
-        //public string NotDeletedDial = "Item NOT Deleted.";
-        //public string NotDeletedCapDial = "Delete Cancelled by User";
-        //public string NotDelInvalidPathDial = "The selected media item cannot be deleted due to an invalid path. Or you may not have sufficient access rights to perform this command.";
-        //public string DelFailedDial = "Delete Failed";
-        //public string NotDelUnknownDial = "The selected media item cannot be deleted due to an unknown error.";
-        //public string NotDelTypeDial = "The selected media item cannot be deleted due to its Item-Type or you have not enabled this feature in the configuration file.";
-        //public string FirstTimeDial = "As this is the first time you have run Media Browser please setup the inital configuration";
-        //public string FirstTimeCapDial = "Configure";
-        //public string EntryPointErrorDial = "Media Browser could not launch directly into ";
-        //public string EntryPointErrorCapDial = "Entrypoint Error";
-        //public string CriticalErrorDial = "Media Browser encountered a critical error and had to shut down: ";
-        //public string CriticalErrorCapDial = "Critical Error";
-        //public string ClearCacheErrorDial = "An error occured during the clearing of the cache, you may wish to manually clear it from {0} before restarting Media Browser";
-        //public string RestartMBDial = "Please restart Media Browser";
-        //public string ClearCacheDial = "Are you sure you wish to clear the cache?\nThis will erase all cached and downloaded information and images.";
-        //public string ClearCacheCapDial = "Clear Cache";
-        //public string CacheClearedDial = "Cache Cleared";
-        //public string ResetConfigDial = "Are you sure you wish to reset all configuration to defaults?";
-        //public string ResetConfigCapDial = "Reset Configuration";
-        //public string ConfigResetDial = "Configuration Reset";
-        //public string UpdateMBDial = "Please visit www.mediabrowser.tv/download to install the new version.";
-        //public string UpdateMBCapDial = "Update Available";
-        //public string UpdateMBExtDial = "There is an update available for Media Browser.  Please update Media Browser next time you are at your MediaCenter PC.";
-        //public string DLUpdateFailDial = "Media Browser will operate normally and prompt you again the next time you load it.";
-        //public string DLUpdateFailCapDial = "Update Download Failed";
-        //public string UpdateSuccessDial = "Media Browser must now exit to apply the update.  It will restart automatically when it is done";
-        //public string UpdateSuccessCapDial = "Update Downloaded";
-        //public string CustomErrorDial = "Customisation Error";
-        //public string ConfigErrorDial = "Reset to default?";
-        //public string ConfigErrorCapDial = "Error in configuration file";
-        //public string ContentErrorDial = "There was a problem playing the content. Check location exists";
-        //public string ContentErrorCapDial = "Content Error";
-        //public string CannotMaximizeDial = "We can not maximize the window! This is a known bug with Windows 7 and TV Pack, you will have to restart Media Browser!";
-        //public string IncorrectPINDial = "Incorrect PIN Entered";
-        //public string ContentProtected = "Content Protected";
-        //public string CantChangePINDial = "Cannot Change PIN";
-        //public string LibraryUnlockedDial = "Library Temporarily Unlocked.  Will Re-Lock in {0} Hour(s) or on Application Re-Start";
-        //public string LibraryUnlockedCapDial = "Unlock";
-        //public string PINChangedDial = "PIN Successfully Changed";
-        //public string PINChangedCapDial = "PIN Change";
-        //public string EnterPINToViewDial = "Please Enter PIN to View Protected Content";
-        //public string EnterPINToPlayDial = "Please Enter PIN to Play Protected Content";
-        //public string EnterCurrentPINDial = "Please Enter CURRENT PIN.";
-        //public string EnterNewPINDial = "Please Enter NEW PIN (exactly 4 digits).";
-        //public string EnterPINDial = "Please Enter PIN to Unlock Library";
-        //public string NoContentDial = "No Content that can be played in this context.";
-        //public string FontsMissingDial = "CustomFonts.mcml as been patched with missing values";
-        //public string StyleMissingDial = "{0} has been patched with missing values";
-        //public string ManualRefreshDial = "Library Update Started.  Will proceed in the background.";
-        //public string ForcedRebuildDial = "Your library is currently being migrated by the service.  The service will re-start when it is finished and you may then run Media Browser.";
-        //public string ForcedRebuildCapDial = "Library Migration";
-        //public string RefreshFailedDial = "The last service refresh process failed.  Please run a manual refresh from the service.";
-        //public string RefreshFailedCapDial = "Service Refresh Failed";
-        //public string RebuildNecDial = "This version of Media Browser requires a re-build of your library.  It has started automatically in the service.  Some information may be incomplete until this process finishes.";
-        //public string MigrateNecDial = "This version of Media Browser requires a migration of your library.  It has started automatically in the service.  The service will restart when it is complete and you may then run Media Browser.";
-        //public string RebuildFailedDial = "There was an error attempting to tell the service to re-build your library.  Please run the service and do a manual refresh with the cache clear options selected.";
-        //public string MigrateFailedDial = "There was an error attempting to tell the service to re-build your library.  Please run the service and do a manual refresh with the cache clear options selected.";
-        //public string RefreshFolderDial = "Refresh all contents too?";
-        //public string RefreshFolderCapDial = "Refresh Folder";
-
-        //Generic
-        public string Restartstr = "Restart";
-        public string Errorstr = "Error";
-        public string Playstr = "Play";
-        public string MinutesStr = "mins"; //Minutes abbreviation
-        public string HoursStr = "hrs"; //Hours abbreviation
-        public string EndsStr = "Ends";
-        public string KBsStr = "Kbps";  //Kilobytes per second
-        public string FrameRateStr = "fps";  //Frames per second
-        public string AtStr = "at";  //x at y, e.g. 1920x1080 at 25 fps
-        public string Rated = "Rated";
-        public string Or = "Or ";
-        public string Lower = "Lower";
-        public string Higher = "Higher";
-        public string Search = "Search";
-        public string Cancel = "Cancel";
-        public string TitleContains = "Title Contains ";
-        public string Any = "Any";
-
-        //Search
-        public string IncludeNested = "Include Subfolders";
-        public string UnwatchedOnly = "Include Only Unwatched";
-        public string FilterByRated = "Filter by Rating";
-
-        //Profiler
-        public string WelcomeProf = "Welcome to Media Browser";
-        public string ProfilerTimeProf = "{1} took {2} seconds.";
-        public string RefreshProf = "Refresh";
-        public string SetWatchedProf = "Set Played {0}";
-        public string RefreshFolderProf = "Refresh Folder and all Contents of";
-        public string ClearWatchedProf = "Clear Played {0}";
-        public string FullRefreshProf = "Full Library Refresh";
-        public string FullValidationProf = "Full Library Validation";
-        public string FastRefreshProf = "Fast Metadata refresh";
-        public string SlowRefresh = "Slow Metadata refresh";
-        public string ImageRefresh = "Image refresh";
-        public string PluginUpdateProf = "An update is available for plug-in {0}";
-        public string NoPluginUpdateProf = "No Plugin Updates Currently Available.";
-        public string LibraryUnLockedProf = "Library Temporarily UnLocked. Will Re-Lock in {0} Hour(s)";
-        public string LibraryReLockedProf = "Library Re-Locked";
-
-        //Messages
-        public string FullRefreshMsg = "Updating Media Library...";
-        public string FullRefreshFinishedMsg = "Library update complete";
-
-    }
-}

+ 0 - 51
MediaBrowser.Controller/Localization/LocalizedStringData.cs

@@ -1,51 +0,0 @@
-using System.IO;
-using System.Xml.Serialization;
-
-namespace MediaBrowser.Controller.Localization
-{
-    /// <summary>
-    /// Class LocalizedStringData
-    /// </summary>
-    public class LocalizedStringData
-    {
-        /// <summary>
-        /// The this version
-        /// </summary>
-        [XmlIgnore]
-        public string ThisVersion = "1.0000";
-        /// <summary>
-        /// The prefix
-        /// </summary>
-        [XmlIgnore]
-        public string Prefix = "";
-        /// <summary>
-        /// The file name
-        /// </summary>
-        public string FileName; //this is public so it will serialize and we know where to save ourselves
-        /// <summary>
-        /// The version
-        /// </summary>
-        public string Version = ""; //this will get saved so we can check it against us for changes
-
-        /// <summary>
-        /// Saves this instance.
-        /// </summary>
-        public void Save()
-        {
-            Save(FileName);
-        }
-
-        /// <summary>
-        /// Saves the specified file.
-        /// </summary>
-        /// <param name="file">The file.</param>
-        public void Save(string file)
-        {
-            var xs = new XmlSerializer(GetType());
-            using (var fs = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.None))
-            {
-                xs.Serialize(fs, this);
-            }
-        }
-    }
-}

+ 0 - 166
MediaBrowser.Controller/Localization/LocalizedStrings.cs

@@ -1,166 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-
-namespace MediaBrowser.Controller.Localization
-{
-    /// <summary>
-    /// Class LocalizedStrings
-    /// </summary>
-    public class LocalizedStrings
-    {
-        public static IServerApplicationPaths ApplicationPaths;
-
-        /// <summary>
-        /// Gets the list of Localized string files
-        /// </summary>
-        /// <value>The string files.</value>
-        public static IEnumerable<LocalizedStringData> StringFiles { get; set; }
-
-        /// <summary>
-        /// The base prefix
-        /// </summary>
-        public const string BasePrefix = "base-";
-        /// <summary>
-        /// The local strings
-        /// </summary>
-        protected ConcurrentDictionary<string, string> LocalStrings = new ConcurrentDictionary<string, string>();
-        /// <summary>
-        /// The _instance
-        /// </summary>
-        private static LocalizedStrings _instance;
-
-        private readonly IServerApplicationPaths _appPaths;
-
-        /// <summary>
-        /// Gets the instance.
-        /// </summary>
-        /// <value>The instance.</value>
-        public static LocalizedStrings Instance { get { return _instance ?? (_instance = new LocalizedStrings(ApplicationPaths)); } }
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="LocalizedStrings" /> class.
-        /// </summary>
-        public LocalizedStrings(IServerApplicationPaths appPaths)
-        {
-            _appPaths = appPaths;
-
-            foreach (var stringObject in StringFiles)
-            {
-                AddStringData(LoadFromFile(GetFileName(stringObject),stringObject.GetType()));
-            }
-        }
-
-        /// <summary>
-        /// Gets the name of the file.
-        /// </summary>
-        /// <param name="stringObject">The string object.</param>
-        /// <returns>System.String.</returns>
-        protected string GetFileName(LocalizedStringData stringObject)
-        {
-            var path = _appPaths.LocalizationPath;
-            var name = Path.Combine(path, stringObject.Prefix + "strings-" + CultureInfo.CurrentCulture + ".xml");
-            if (File.Exists(name))
-            {
-                return name;
-            }
-
-            name = Path.Combine(path, stringObject.Prefix + "strings-" + CultureInfo.CurrentCulture.Parent + ".xml");
-            if (File.Exists(name))
-            {
-                return name;
-            }
-
-            //just return default
-            return Path.Combine(path, stringObject.Prefix + "strings-en.xml");
-        }
-
-        /// <summary>
-        /// Loads from file.
-        /// </summary>
-        /// <param name="file">The file.</param>
-        /// <param name="t">The t.</param>
-        /// <returns>LocalizedStringData.</returns>
-        protected LocalizedStringData LoadFromFile(string file, Type t)
-        {
-            return new BaseStrings {FileName = file};
-            //var xs = new XmlSerializer(t);
-            //var strings = (LocalizedStringData)Activator.CreateInstance(t);
-            //strings.FileName = file;
-            //Logger.Info("Using String Data from {0}", file);
-            //if (File.Exists(file))
-            //{
-            //    using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read))
-            //    {
-            //        strings = (LocalizedStringData)xs.Deserialize(fs);
-            //    }
-            //}
-            //else
-            //{
-            //    strings.Save(); //brand new - save it
-            //}
-
-            //if (strings.ThisVersion != strings.Version && file.ToLower().Contains("-en.xml"))
-            //{
-            //    //only re-save the english version as that is the one defined internally
-            //    strings = new BaseStrings {FileName = file};
-            //    strings.Save();
-            //}
-            //return strings;
-
-        }
-
-        /// <summary>
-        /// Adds the string data.
-        /// </summary>
-        /// <param name="stringData">The string data.</param>
-        public void AddStringData(object stringData )
-        {
-            //translate our object definition into a dictionary for lookups
-            // and a reverse dictionary so we can lookup keys by value
-            foreach (var field in stringData.GetType().GetFields().Where(f => f != null && f.FieldType == typeof(string)))
-            {
-                string value;
-
-                try
-                {
-                    value = field.GetValue(stringData) as string;
-                }
-                catch (TargetException)
-                {
-                    //Logger.ErrorException("Error getting value for field: {0}", ex, field.Name);
-                    continue;
-                }
-                catch (FieldAccessException)
-                {
-                    //Logger.ErrorException("Error getting value for field: {0}", ex, field.Name);
-                    continue;
-                }
-                catch (NotSupportedException)
-                {
-                    //Logger.ErrorException("Error getting value for field: {0}", ex, field.Name);
-                    continue;
-                }
-
-                LocalStrings.TryAdd(field.Name, value);
-            }
-        }
-
-        /// <summary>
-        /// Gets the string.
-        /// </summary>
-        /// <param name="key">The key.</param>
-        /// <returns>System.String.</returns>
-        public string GetString(string key)
-        {
-            string value;
-
-            LocalStrings.TryGetValue(key, out value);
-            return value;
-        }
-    }
-}

+ 1 - 3
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -313,9 +313,6 @@
     <Compile Include="Library\ILibraryManager.cs" />
     <Compile Include="Library\IUserManager.cs" />
     <Compile Include="Library\Profiler.cs" />
-    <Compile Include="Localization\BaseStrings.cs" />
-    <Compile Include="Localization\LocalizedStringData.cs" />
-    <Compile Include="Localization\LocalizedStrings.cs" />
     <Compile Include="Persistence\IDisplayPreferencesRepository.cs" />
     <Compile Include="Persistence\IItemRepository.cs" />
     <Compile Include="Persistence\IRepository.cs" />
@@ -344,6 +341,7 @@
     <Compile Include="Subtitles\SubtitleResponse.cs" />
     <Compile Include="Subtitles\SubtitleSearchRequest.cs" />
     <Compile Include="Sync\ICloudSyncProvider.cs" />
+    <Compile Include="Sync\IServerSyncProvider.cs" />
     <Compile Include="Sync\ISyncManager.cs" />
     <Compile Include="Sync\ISyncProvider.cs" />
     <Compile Include="Sync\ISyncRepository.cs" />

+ 52 - 0
MediaBrowser.Controller/Sync/IServerSyncProvider.cs

@@ -0,0 +1,52 @@
+using MediaBrowser.Model.Sync;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Controller.Sync
+{
+    public interface IServerSyncProvider : ISyncProvider
+    {
+        /// <summary>
+        /// Gets the server item ids.
+        /// </summary>
+        /// <param name="serverId">The server identifier.</param>
+        /// <param name="target">The target.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task&lt;List&lt;System.String&gt;&gt;.</returns>
+        Task<List<string>> GetServerItemIds(string serverId, SyncTarget target, CancellationToken cancellationToken);
+
+        /// <summary>
+        /// Removes the item.
+        /// </summary>
+        /// <param name="serverId">The server identifier.</param>
+        /// <param name="itemId">The item identifier.</param>
+        /// <param name="target">The target.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task.</returns>
+        Task DeleteItem(string serverId, string itemId, SyncTarget target, CancellationToken cancellationToken);
+
+        /// <summary>
+        /// Transfers the file.
+        /// </summary>
+        /// <param name="serverId">The server identifier.</param>
+        /// <param name="itemId">The item identifier.</param>
+        /// <param name="path">The path.</param>
+        /// <param name="target">The target.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task.</returns>
+        Task TransferItemFile(string serverId, string itemId, string path, SyncTarget target, CancellationToken cancellationToken);
+
+        /// <summary>
+        /// Transfers the related file.
+        /// </summary>
+        /// <param name="serverId">The server identifier.</param>
+        /// <param name="itemId">The item identifier.</param>
+        /// <param name="path">The path.</param>
+        /// <param name="type">The type.</param>
+        /// <param name="target">The target.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task.</returns>
+        Task TransferRelatedFile(string serverId, string itemId, string path, ItemFileType type, SyncTarget target, CancellationToken cancellationToken);
+    }
+}

+ 14 - 0
MediaBrowser.Controller/Sync/ISyncManager.cs

@@ -167,5 +167,19 @@ namespace MediaBrowser.Controller.Sync
         /// <param name="job">The job.</param>
         /// <returns>VideoOptions.</returns>
         VideoOptions GetVideoOptions(SyncJobItem jobItem, SyncJob job);
+
+        /// <summary>
+        /// Reports the synchronize job item transfer beginning.
+        /// </summary>
+        /// <param name="id">The identifier.</param>
+        /// <returns>Task.</returns>
+        Task ReportSyncJobItemTransferBeginning(string id);
+
+        /// <summary>
+        /// Reports the synchronize job item transfer failed.
+        /// </summary>
+        /// <param name="id">The identifier.</param>
+        /// <returns>Task.</returns>
+        Task ReportSyncJobItemTransferFailed(string id);
     }
 }

+ 1 - 0
MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs

@@ -20,6 +20,7 @@ namespace MediaBrowser.Dlna.PlayTo
                 {
                     ItemId = item.Id.ToString("N"),
                     MediaType = DlnaProfileType.Photo,
+                    DeviceProfile = profile
                 },
 
                 Profile = profile

+ 12 - 25
MediaBrowser.Model/Dlna/StreamBuilder.cs

@@ -108,7 +108,8 @@ namespace MediaBrowser.Model.Dlna
                 MediaType = DlnaProfileType.Audio,
                 MediaSource = item,
                 RunTimeTicks = item.RunTimeTicks,
-                Context = options.Context
+                Context = options.Context,
+                DeviceProfile = options.Profile
             };
 
             int? maxBitrateSetting = options.GetMaxBitrate();
@@ -240,7 +241,8 @@ namespace MediaBrowser.Model.Dlna
                 MediaType = DlnaProfileType.Video,
                 MediaSource = item,
                 RunTimeTicks = item.RunTimeTicks,
-                Context = options.Context
+                Context = options.Context,
+                DeviceProfile = options.Profile
             };
 
             int? audioStreamIndex = options.AudioStreamIndex ?? item.DefaultAudioStreamIndex;
@@ -265,7 +267,7 @@ namespace MediaBrowser.Model.Dlna
 
                     if (subtitleStream != null)
                     {
-                        SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options);
+                        SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options.Profile);
 
                         playlistItem.SubtitleDeliveryMethod = subtitleProfile.Method;
                         playlistItem.SubtitleFormat = subtitleProfile.Format;
@@ -290,7 +292,7 @@ namespace MediaBrowser.Model.Dlna
             {
                 if (subtitleStream != null)
                 {
-                    SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options);
+                    SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options.Profile);
 
                     playlistItem.SubtitleDeliveryMethod = subtitleProfile.Method;
                     playlistItem.SubtitleFormat = subtitleProfile.Format;
@@ -524,7 +526,7 @@ namespace MediaBrowser.Model.Dlna
         {
             if (subtitleStream != null)
             {
-                SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options);
+                SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options.Profile);
 
                 if (subtitleProfile.Method != SubtitleDeliveryMethod.External && subtitleProfile.Method != SubtitleDeliveryMethod.Embed)
                 {
@@ -535,10 +537,10 @@ namespace MediaBrowser.Model.Dlna
             return IsAudioEligibleForDirectPlay(item, maxBitrate);
         }
 
-        private SubtitleProfile GetSubtitleProfile(MediaStream subtitleStream, VideoOptions options)
+        public static SubtitleProfile GetSubtitleProfile(MediaStream subtitleStream, DeviceProfile deviceProfile)
         {
             // Look for an external profile that matches the stream type (text/graphical)
-            foreach (SubtitleProfile profile in options.Profile.SubtitleProfiles)
+            foreach (SubtitleProfile profile in deviceProfile.SubtitleProfiles)
             {
                 if (profile.Method == SubtitleDeliveryMethod.External && subtitleStream.IsTextSubtitleStream == MediaStream.IsTextFormat(profile.Format))
                 {
@@ -546,13 +548,11 @@ namespace MediaBrowser.Model.Dlna
                 }
             }
 
-            if (subtitleStream.IsTextSubtitleStream)
+            foreach (SubtitleProfile profile in deviceProfile.SubtitleProfiles)
             {
-                SubtitleProfile embedProfile = GetSubtitleProfile(options.Profile.SubtitleProfiles, SubtitleDeliveryMethod.Embed);
-
-                if (embedProfile != null)
+                if (profile.Method == SubtitleDeliveryMethod.Embed && subtitleStream.IsTextSubtitleStream == MediaStream.IsTextFormat(profile.Format))
                 {
-                    return embedProfile;
+                    return profile;
                 }
             }
 
@@ -563,19 +563,6 @@ namespace MediaBrowser.Model.Dlna
             };
         }
 
-        private SubtitleProfile GetSubtitleProfile(SubtitleProfile[] profiles, SubtitleDeliveryMethod method)
-        {
-            foreach (SubtitleProfile profile in profiles)
-            {
-                if (method == profile.Method)
-                {
-                    return profile;
-                }
-            }
-
-            return null;
-        }
-
         private bool IsAudioEligibleForDirectPlay(MediaSourceInfo item, int? maxBitrate)
         {
             // Honor the max bitrate setting

+ 10 - 7
MediaBrowser.Model/Dlna/StreamInfo.cs

@@ -54,6 +54,7 @@ namespace MediaBrowser.Model.Dlna
         
         public float? MaxFramerate { get; set; }
 
+        public DeviceProfile DeviceProfile { get; set; }
         public string DeviceProfileId { get; set; }
         public string DeviceId { get; set; }
 
@@ -160,11 +161,6 @@ namespace MediaBrowser.Model.Dlna
 
             List<SubtitleStreamInfo> list = new List<SubtitleStreamInfo>();
 
-            if (SubtitleDeliveryMethod != SubtitleDeliveryMethod.External)
-            {
-                return list;
-            }
-
             // HLS will preserve timestamps so we can just grab the full subtitle stream
             long startPositionTicks = StringHelper.EqualsIgnoreCase(Protocol, "hls")
                 ? 0
@@ -175,7 +171,7 @@ namespace MediaBrowser.Model.Dlna
             {
                 foreach (MediaStream stream in MediaSource.MediaStreams)
                 {
-                    if (stream.Type == MediaStreamType.Subtitle && stream.IsTextSubtitleStream && stream.Index == SubtitleStreamIndex.Value)
+                    if (stream.Type == MediaStreamType.Subtitle && stream.Index == SubtitleStreamIndex.Value)
                     {
                         AddSubtitle(list, stream, baseUrl, startPositionTicks);
                     }
@@ -186,7 +182,7 @@ namespace MediaBrowser.Model.Dlna
             {
                 foreach (MediaStream stream in MediaSource.MediaStreams)
                 {
-                    if (stream.Type == MediaStreamType.Subtitle && stream.IsTextSubtitleStream && (!SubtitleStreamIndex.HasValue || stream.Index != SubtitleStreamIndex.Value))
+                    if (stream.Type == MediaStreamType.Subtitle && (!SubtitleStreamIndex.HasValue || stream.Index != SubtitleStreamIndex.Value))
                     {
                         AddSubtitle(list, stream, baseUrl, startPositionTicks);
                     }
@@ -198,6 +194,13 @@ namespace MediaBrowser.Model.Dlna
 
         private void AddSubtitle(List<SubtitleStreamInfo> list, MediaStream stream, string baseUrl, long startPositionTicks)
         {
+            var subtitleProfile = StreamBuilder.GetSubtitleProfile(stream, DeviceProfile);
+
+            if (subtitleProfile.Method != SubtitleDeliveryMethod.External)
+            {
+                return;
+            }
+
             string url = string.Format("{0}/Videos/{1}/{2}/Subtitles/{3}/{4}/Stream.{5}",
                 baseUrl,
                 ItemId,

+ 0 - 1
MediaBrowser.Server.Implementations/Localization/Server/server.json

@@ -614,7 +614,6 @@
     "PleaseUpdateManually": "Please shutdown the server and update manually.",
     "NewServerVersionAvailable": "A new version of Media Browser Server is available!",
     "ServerUpToDate": "Media Browser Server is up to date",
-    "ErrorConnectingToMediaBrowserRepository": "There was an error connecting to the remote Media Browser repository.",
     "LabelComponentsUpdated": "The following components have been installed or updated:",
     "MessagePleaseRestartServerToFinishUpdating": "Please restart the server to finish applying updates.",
     "LabelDownMixAudioScale": "Audio boost when downmixing:",

+ 1 - 0
MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj

@@ -306,6 +306,7 @@
     <Compile Include="Sorting\VideoBitRateComparer.cs" />
     <Compile Include="Sync\AppSyncProvider.cs" />
     <Compile Include="Sync\CloudSyncProvider.cs" />
+    <Compile Include="Sync\MediaSync.cs" />
     <Compile Include="Sync\SyncRegistrationInfo.cs" />
     <Compile Include="Sync\SyncConfig.cs" />
     <Compile Include="Sync\SyncJobProcessor.cs" />

+ 24 - 1
MediaBrowser.Server.Implementations/Sync/CloudSyncProvider.cs

@@ -2,12 +2,15 @@
 using MediaBrowser.Controller.Sync;
 using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Sync;
+using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
 
 namespace MediaBrowser.Server.Implementations.Sync
 {
-    public class CloudSyncProvider : ISyncProvider
+    public class CloudSyncProvider : IServerSyncProvider
     {
         private ICloudSyncProvider[] _providers = {};
 
@@ -35,5 +38,25 @@ namespace MediaBrowser.Server.Implementations.Sync
         {
             get { return "Cloud Sync"; }
         }
+
+        public Task<List<string>> GetServerItemIds(string serverId, SyncTarget target, CancellationToken cancellationToken)
+        {
+            throw new NotImplementedException();
+        }
+
+        public Task DeleteItem(string serverId, string itemId, SyncTarget target, CancellationToken cancellationToken)
+        {
+            throw new NotImplementedException();
+        }
+
+        public Task TransferItemFile(string serverId, string itemId, string path, SyncTarget target, CancellationToken cancellationToken)
+        {
+            throw new NotImplementedException();
+        }
+
+        public Task TransferRelatedFile(string serverId, string itemId, string path, ItemFileType type, SyncTarget target, CancellationToken cancellationToken)
+        {
+            throw new NotImplementedException();
+        }
     }
 }

+ 174 - 0
MediaBrowser.Server.Implementations/Sync/MediaSync.cs

@@ -0,0 +1,174 @@
+using MediaBrowser.Common.Progress;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Sync;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Sync;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Server.Implementations.Sync
+{
+    public class MediaSync
+    {
+        private readonly ISyncManager _syncManager;
+        private readonly IServerApplicationHost _appHost;
+        private readonly ILogger _logger;
+
+        public MediaSync(ILogger logger, ISyncManager syncManager, IServerApplicationHost appHost)
+        {
+            _logger = logger;
+            _syncManager = syncManager;
+            _appHost = appHost;
+        }
+
+        public async Task Sync(IServerSyncProvider provider, 
+            SyncTarget target,
+            IProgress<double> progress,
+            CancellationToken cancellationToken)
+        {
+            var serverId = _appHost.SystemId;
+
+            await SyncData(provider, serverId, target, cancellationToken).ConfigureAwait(false);
+            progress.Report(2);
+
+            // Do the data sync twice so the server knows what was removed from the device
+            await SyncData(provider, serverId, target, cancellationToken).ConfigureAwait(false);
+            progress.Report(3);
+
+            var innerProgress = new ActionableProgress<double>();
+            innerProgress.RegisterAction(pct =>
+            {
+                var totalProgress = pct * .97;
+                totalProgress += 1;
+                progress.Report(totalProgress);
+            });
+            await GetNewMedia(provider, target, serverId, innerProgress, cancellationToken);
+            progress.Report(100);
+        }
+
+        private async Task SyncData(IServerSyncProvider provider,
+            string serverId,
+            SyncTarget target,
+            CancellationToken cancellationToken)
+        {
+            var localIds = await provider.GetServerItemIds(serverId, target, cancellationToken).ConfigureAwait(false);
+
+            var result = await _syncManager.SyncData(new SyncDataRequest
+            {
+                TargetId = target.Id,
+                LocalItemIds = localIds
+
+            }).ConfigureAwait(false);
+
+            cancellationToken.ThrowIfCancellationRequested();
+
+            foreach (var itemIdToRemove in result.ItemIdsToRemove)
+            {
+                try
+                {
+                    await RemoveItem(provider, serverId, itemIdToRemove, target, cancellationToken).ConfigureAwait(false);
+                }
+                catch (Exception ex)
+                {
+                    _logger.ErrorException("Error deleting item from sync target. Id: {0}", ex, itemIdToRemove);
+                }
+            }
+        }
+
+        private async Task GetNewMedia(IServerSyncProvider provider,
+            SyncTarget target,
+            string serverId,
+            IProgress<double> progress,
+            CancellationToken cancellationToken)
+        {
+            var jobItems =  _syncManager.GetReadySyncItems(target.Id);
+            
+            var numComplete = 0;
+            double startingPercent = 0;
+            double percentPerItem = 1;
+            if (jobItems.Count > 0)
+            {
+                percentPerItem /= jobItems.Count;
+            }
+
+            foreach (var jobItem in jobItems)
+            {
+                cancellationToken.ThrowIfCancellationRequested();
+
+                var currentPercent = startingPercent;
+                var innerProgress = new ActionableProgress<double>();
+                innerProgress.RegisterAction(pct =>
+                {
+                    var totalProgress = pct * percentPerItem;
+                    totalProgress += currentPercent;
+                    progress.Report(totalProgress);
+                });
+
+                await GetItem(provider, target, serverId, jobItem, innerProgress, cancellationToken).ConfigureAwait(false);
+
+                numComplete++;
+                startingPercent = numComplete;
+                startingPercent /= jobItems.Count;
+                startingPercent *= 100;
+                progress.Report(startingPercent);
+            }
+        }
+
+        private async Task GetItem(IServerSyncProvider provider,
+            SyncTarget target,
+            string serverId,
+            SyncedItem jobItem,
+            IProgress<double> progress,
+            CancellationToken cancellationToken)
+        {
+            var libraryItem = jobItem.Item;
+            var internalSyncJobItem = _syncManager.GetJobItem(jobItem.SyncJobItemId);
+
+            var fileTransferProgress = new ActionableProgress<double>();
+            fileTransferProgress.RegisterAction(pct => progress.Report(pct * .92));
+
+            await _syncManager.ReportSyncJobItemTransferBeginning(internalSyncJobItem.Id);
+
+            var transferSuccess = false;
+            Exception transferException = null;
+
+            try
+            {
+                await provider.TransferItemFile(serverId, libraryItem.Id, internalSyncJobItem.OutputPath, target, cancellationToken)
+                        .ConfigureAwait(false);
+
+                progress.Report(92);
+
+                transferSuccess = true;
+
+                progress.Report(99);
+            }
+            catch (Exception ex)
+            {
+                _logger.ErrorException("Error transferring sync job file", ex);
+                transferException = ex;
+            }
+
+            if (transferSuccess)
+            {
+                await _syncManager.ReportSyncJobItemTransferred(jobItem.SyncJobItemId).ConfigureAwait(false);
+            }
+            else
+            {
+                await _syncManager.ReportSyncJobItemTransferFailed(jobItem.SyncJobItemId).ConfigureAwait(false);
+
+                throw transferException;
+            }
+        }
+
+        private Task RemoveItem(IServerSyncProvider provider,
+            string serverId,
+            string itemId,
+            SyncTarget target,
+            CancellationToken cancellationToken)
+        {
+            return provider.DeleteItem(serverId, itemId, target, cancellationToken);
+        }
+    }
+}

+ 26 - 0
MediaBrowser.Server.Implementations/Sync/SyncManager.cs

@@ -870,6 +870,32 @@ namespace MediaBrowser.Server.Implementations.Sync
             await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false);
         }
 
+        public async Task ReportSyncJobItemTransferBeginning(string id)
+        {
+            var jobItem = _repo.GetJobItem(id);
+
+            jobItem.Status = SyncJobItemStatus.Transferring;
+
+            await UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false);
+
+            var processor = GetSyncJobProcessor();
+
+            await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false);
+        }
+
+        public async Task ReportSyncJobItemTransferFailed(string id)
+        {
+            var jobItem = _repo.GetJobItem(id);
+
+            jobItem.Status = SyncJobItemStatus.ReadyToTransfer;
+
+            await UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false);
+
+            var processor = GetSyncJobProcessor();
+
+            await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false);
+        }
+
         public QueryResult<string> GetLibraryItemIds(SyncJobItemQuery query)
         {
             return _repo.GetLibraryItemIds(query);

+ 0 - 11
MediaBrowser.Server.Startup.Common/ApplicationHost.cs

@@ -536,8 +536,6 @@ namespace MediaBrowser.Server.Startup.Common
 
             SetStaticProperties();
 
-            SetKernelProperties();
-
             await ((UserManager)UserManager).Initialize().ConfigureAwait(false);
         }
 
@@ -573,14 +571,6 @@ namespace MediaBrowser.Server.Startup.Common
             RegisterSingleInstance(MediaEncoder);
         }
 
-        /// <summary>
-        /// Sets the kernel properties.
-        /// </summary>
-        private void SetKernelProperties()
-        {
-            LocalizedStrings.StringFiles = GetExports<LocalizedStringData>();
-        }
-
         /// <summary>
         /// Gets the user repository.
         /// </summary>
@@ -698,7 +688,6 @@ namespace MediaBrowser.Server.Startup.Common
             BaseItem.ItemRepository = ItemRepository;
             User.XmlSerializer = XmlSerializer;
             User.UserManager = UserManager;
-            LocalizedStrings.ApplicationPaths = ApplicationPaths;
             Folder.UserManager = UserManager;
             BaseItem.FileSystem = FileSystemManager;
             BaseItem.UserDataManager = UserDataManager;