public MainWindow() { try { InitializeComponent(); _serviceOptions = new ServiceRefreshOptions(); Instance = this; Go(); } catch (Exception e) { Console.WriteLine("Critical error launching Media Browser Service, please report this bug with the full contents below to http://community.mediabrowser.tv"); Console.WriteLine(e.ToString()); Console.WriteLine(e.StackTrace); Console.WriteLine(e.InnerException); Console.ReadKey(); } }
void FullRefresh(bool force, ServiceRefreshOptions manualOptions) { _refreshRunning = true; Dispatcher.Invoke(DispatcherPriority.Background, (System.Windows.Forms.MethodInvoker)(() => { gbManual.IsEnabled = false; refreshProgress.Value = 0; refreshProgress.Visibility = Visibility.Visible; _refreshCanceled = false; _refreshCanceledTime = DateTime.MinValue; _config.RefreshFailed = false; _config.Save(); _refreshStartTime = DateTime.Now; if (manualOptions.AllowCancel) { btnCancelRefresh.IsEnabled = true; btnCancelRefresh.Visibility = Visibility.Visible; } lblSvcActivity.Content = "Refresh Running..."; lblSvcActivity.Foreground = Brushes.Black; lblNextSvcRefresh.Foreground = Brushes.Black; notifyIcon.ContextMenu.MenuItems["refresh"].Enabled = false; notifyIcon.ContextMenu.MenuItems["exit"].Enabled = false; notifyIcon.ContextMenu.MenuItems["refresh"].Text = "Refresh Running..."; //Stream iconStream = Application.GetResourceStream(new Uri("pack://application:,,,/MediaBrowserService;component/MBServiceRefresh.ico")).Stream; notifyIcon.Icon = RefreshIcons[0]; lblNextSvcRefresh.Content = ""; })); bool onSchedule = (!force && (DateTime.Now.Hour == _config.FullRefreshPreferredHour)); Logger.ReportInfo("Full Refresh Started"); refreshElapsed = Async.Every(1000, UpdateRefreshElapsed); using (new Profiler(Kernel.Instance.GetString("FullRefreshProf"))) { try { Kernel.Instance.ReLoadRoot(); // make sure we are dealing with the current state of the library if (force) { if (manualOptions.ClearCacheOption) { //clear all cache items except displayprefs and playstate Logger.ReportInfo("Clearing Cache on manual refresh..."); UpdateProgress("Clearing Cache", 0); try { Kernel.Instance.ItemRepository.ClearEntireCache(); } catch (Exception e) { Logger.ReportException("Error attempting to clear cache.", e); } } if (manualOptions.ClearImageCacheOption) { try { Directory.Delete(ApplicationPaths.AppImagePath, true); Thread.Sleep(1000); //wait for the delete to fiinish } catch (Exception e) { Logger.ReportException("Error trying to clear image cache.", e); } //just log it try { Directory.CreateDirectory(ApplicationPaths.AppImagePath); Thread.Sleep(1000); //wait for the directory to create } catch (Exception e) { Logger.ReportException("Error trying to create image cache.", e); } //just log it } } MetadataRefreshOptions refreshOptions = manualOptions.AllowSlowProviderOption ? MetadataRefreshOptions.Default : MetadataRefreshOptions.FastOnly; if (FullRefresh(Kernel.Instance.RootFolder, refreshOptions, manualOptions)) { _config.LastFullRefresh = DateTime.Now; _lastRefreshElapsedTime = DateTime.Now - _refreshStartTime; _config.Save(); } MBServiceController.SendCommandToCore(IPCCommands.ReloadItems); } catch (Exception ex) { Logger.ReportException("Failed to refresh library! ", ex); Debug.Assert(false, "Full refresh service should never crash!"); } finally { Kernel.Instance.ReLoadRoot(); // re-dump this to stay clean refreshElapsed.Change(-1,0); //kill the progress timer _refreshRunning = false; Logger.ReportInfo("Full Refresh Finished"); Dispatcher.Invoke(DispatcherPriority.Background, (System.Windows.Forms.MethodInvoker)(() => { refreshProgress.Value = 0; refreshProgress.Visibility = Visibility.Hidden; btnCancelRefresh.Visibility = Visibility.Hidden; gbManual.IsEnabled = true; refreshElapsed = null; notifyIcon.ContextMenu.MenuItems["exit"].Enabled = true; notifyIcon.ContextMenu.MenuItems["refresh"].Enabled = true; notifyIcon.ContextMenu.MenuItems["refresh"].Text = "Refresh Now"; Stream iconStream = Application.GetResourceStream(new Uri("pack://application:,,,/MediaBrowserService;component/MBService.ico")).Stream; notifyIcon.Icon = new System.Drawing.Icon(iconStream); UpdateStatus(); })); if (onSchedule) { ClearLogFiles(Kernel.Instance.ConfigData.LogFileRetentionDays); if (_config.SleepAfterScheduledRefresh) { Async.Queue("Sleep After Refresh", () => { Logger.ReportInfo("Putting computer to sleep..."); System.Windows.Forms.Application.SetSuspendState(System.Windows.Forms.PowerState.Suspend, true, false); }, 10000); } } } } }
bool FullRefresh(AggregateFolder folder, MetadataRefreshOptions options, ServiceRefreshOptions manualOptions) { int phases = manualOptions.AnyImageOptionsSelected || manualOptions.MigrateOption ? 3 : 2; double totalIterations = 0; UpdateProgress("Determining Library Size", 0); //this will trap any circular references in the library tree try { Async.RunWithTimeout(() => { totalIterations = folder.AllRecursiveChildren.Count() * phases; }, 600000); } catch (TimeoutException) { Logger.ReportError("ERROR DURING REFRESH. Timed out attempting to retrieve count of all items. Most likely there is a circular reference in your library. Look for *.lnk files that might be pointing back to a parent of the folder that contatians that link."); _config.RefreshFailed = true; _config.Save(); return false; } if (totalIterations == 0) return true; //nothing to do int currentIteration = 0; UpdateProgress("Validating Root", 0); folder.RefreshMetadata(options); using (new Profiler(Kernel.Instance.GetString("FullValidationProf"))) { if (!RunActionRecursively(folder, item => { currentIteration++; UpdateProgress("Validating",currentIteration / totalIterations); var f = item as Folder; if (f != null) { f.ValidateChildren(); } })) return false; } string msg = (options & MetadataRefreshOptions.FastOnly) == MetadataRefreshOptions.FastOnly ? "Not allowing internet and other slow providers." : "Allowing internet and other slow providers."; Logger.ReportInfo(msg); var processedItems = new HashSet<Guid>(); using (new Profiler(Kernel.Instance.GetString("SlowRefresh"))) { if (!RunActionRecursively(folder, item => { currentIteration++; UpdateProgress("All Metadata",(currentIteration / totalIterations)); if (!processedItems.Contains(item.Id)) //only process any given item once (could be multiple refs to same item) { if (manualOptions.MigrateOption) { MigratePlayState(item); } item.RefreshMetadata(options); processedItems.Add(item.Id); //Logger.ReportInfo(item.Name + " id: " + item.Id); //test //throw new InvalidOperationException("Test Error..."); } })) return false; } if (manualOptions.AnyImageOptionsSelected || manualOptions.MigrateOption) { processedItems.Clear(); using (new Profiler(Kernel.Instance.GetString("ImageRefresh"))) { var studiosProcessed = new List<string>(); var genresProcessed = new List<string>(); var peopleProcessed = new List<string>(); var yearsProcessed = new List<string>(); if (!RunActionRecursively(folder, item => { currentIteration++; UpdateProgress("Images",(currentIteration / totalIterations)); if (!processedItems.Contains(item.Id)) { if (manualOptions.IncludeImagesOption) //main images { Logger.ReportInfo("Caching all images for " + item.Name ); item.ReCacheAllImages(); } if (manualOptions.MigrateOption) //migrate main images { item.MigrateAllImages(); } // optionally cause genre, poeple, year and studio images to cache as well if (item is Show) { var show = item as Show; if ((manualOptions.IncludeGenresOption || manualOptions.MigrateOption) && show.Genres != null) { foreach (var genre in show.Genres) { if (!genresProcessed.Contains(genre)) { Genre g = Genre.GetGenre(genre); g.RefreshMetadata(); if (g.PrimaryImage != null) { if (manualOptions.IncludeGenresOption) { Logger.ReportInfo("Caching image for genre: " + genre); g.PrimaryImage.ClearLocalImages(); g.PrimaryImage.GetLocalImagePath(); } if (manualOptions.MigrateOption) { Logger.ReportInfo("Migrating image for genre: " + genre); g.PrimaryImage.MigrateFromOldID(); } } foreach (MediaBrowser.Library.ImageManagement.LibraryImage image in g.BackdropImages) { if (manualOptions.IncludeGenresOption) { image.GetLocalImagePath(); } if (manualOptions.MigrateOption) { image.MigrateFromOldID(); } } genresProcessed.Add(genre); } } } if ((manualOptions.IncludeStudiosOption || manualOptions.MigrateOption) && show.Studios != null) { foreach (var studio in show.Studios) { if (!studiosProcessed.Contains(studio)) { Logger.ReportInfo("Caching image for studio: " + studio); Studio st = Studio.GetStudio(studio); st.RefreshMetadata(); if (st.PrimaryImage != null) { if (manualOptions.IncludeStudiosOption) { Logger.ReportInfo("Caching image for studio: " + studio); st.PrimaryImage.ClearLocalImages(); st.PrimaryImage.GetLocalImagePath(); } if (manualOptions.MigrateOption) { Logger.ReportInfo("Migrating image for studio: " + studio); st.PrimaryImage.MigrateFromOldID(); } } foreach (MediaBrowser.Library.ImageManagement.LibraryImage image in st.BackdropImages) { if (manualOptions.IncludeStudiosOption) { image.ClearLocalImages(); image.GetLocalImagePath(); } if (manualOptions.MigrateOption) { image.MigrateFromOldID(); } } studiosProcessed.Add(studio); } } } if ((manualOptions.IncludePeopleOption || manualOptions.MigrateOption) && show.Actors != null) { foreach (var actor in show.Actors) { if (!peopleProcessed.Contains(actor.Name)) { Person p = Person.GetPerson(actor.Name); p.RefreshMetadata(); if (p.PrimaryImage != null) { if (manualOptions.IncludePeopleOption) { Logger.ReportInfo("Caching image for person: " + actor.Name); p.PrimaryImage.ClearLocalImages(); p.PrimaryImage.GetLocalImagePath(); } if (manualOptions.MigrateOption) { Logger.ReportInfo("Migrating image for person: " + actor.Name); p.PrimaryImage.MigrateFromOldID(); } } foreach (MediaBrowser.Library.ImageManagement.LibraryImage image in p.BackdropImages) { if (manualOptions.IncludePeopleOption) { image.ClearLocalImages(); image.GetLocalImagePath(); } if (manualOptions.MigrateOption) { image.MigrateFromOldID(); } } peopleProcessed.Add(actor.Name); } } } if (manualOptions.IncludePeopleOption && show.Directors != null) { foreach (var director in show.Directors) { if (!peopleProcessed.Contains(director)) { Person p = Person.GetPerson(director); p.RefreshMetadata(); if (p.PrimaryImage != null) { Logger.ReportInfo("Caching image for person: " + director); p.PrimaryImage.ClearLocalImages(); p.PrimaryImage.GetLocalImagePath(); } foreach (MediaBrowser.Library.ImageManagement.LibraryImage image in p.BackdropImages) { image.ClearLocalImages(); image.GetLocalImagePath(); } peopleProcessed.Add(director); } } } if (manualOptions.IncludeYearOption && show.ProductionYear != null) { if (!yearsProcessed.Contains(show.ProductionYear.ToString())) { Year yr = Year.GetYear(show.ProductionYear.ToString()); yr.RefreshMetadata(); if (yr.PrimaryImage != null) { Logger.ReportInfo("Caching image for year: " + yr); yr.PrimaryImage.ClearLocalImages(); yr.PrimaryImage.GetLocalImagePath(); } foreach (MediaBrowser.Library.ImageManagement.LibraryImage image in yr.BackdropImages) { image.ClearLocalImages(); image.GetLocalImagePath(); } yearsProcessed.Add(show.ProductionYear.ToString()); } } } processedItems.Add(item.Id); } else Logger.ReportInfo("Not processing " + item.Name + " again."); })) return false; } } return true; }
public void ForceRebuild() { //force a re-build of the entire library - used when new version requires cache clear //first create options - just the items as we will attempt to migrate the old images var options = new ServiceRefreshOptions() { ClearCacheOption = true, ClearImageCacheOption = false, IncludeImagesOption = false, IncludeGenresOption = false, IncludeStudiosOption = false, IncludeYearOption = false, MigrateOption = true, AllowSlowProviderOption = true, AllowCancel = false }; //kick off a manual refresh on a high-priority thread Thread manual = new Thread(new ThreadStart(() => { _config.ForceRebuildInProgress = true; _config.Save(); FullRefresh(true, options); _config.ForceRebuildInProgress = false; _config.Save(); })); manual.Name = "Force Rebuild"; manual.IsBackground = true; manual.Priority = ThreadPriority.Highest; manual.Start(); }