public GeneralSettings() { this.NumProcessingThreads = 10; this.NumSimultaneousSearches = 5; this.DefaultMovieDatabase = MovieDatabaseSelection.TheMovieDb; this.DefaultTvDatabase = TvDataBaseSelection.TheTvDb; this.TorrentDirectory = Path.Combine(Organization.GetBasePath(true), "Torrents"); }
void saveWorker_DoWork(object sender, DoWorkEventArgs e) { // Get path to xml file string path = Path.Combine(Organization.GetBasePath(true), XML_ROOT + ".xml"); // Save data into temporary file, so that if application crashes in middle of saving XML is not corrupted! string tempPath = Path.Combine(Organization.GetBasePath(true), XML_ROOT + "_TEMP.xml"); //Console.WriteLine(this.ToString() + " lock save"); lock (XmlLock) { // Lock content and file lock (ContentLock) { using (XmlTextWriter xw = new XmlTextWriter(tempPath, Encoding.ASCII)) { xw.Formatting = Formatting.Indented; xw.WriteStartElement(XML_ROOT); xw.WriteElementString("LastUpdate", this.LastUpdate); foreach (Content content in this) { content.Save(xw); if (saveWorker.CancellationPending) { return; } } xw.WriteEndElement(); } if (saveWorker.CancellationPending) { return; } // Delete previous save data if (File.Exists(path)) { File.Delete(path); } // Move tempoarary save file to default File.Move(tempPath, path); } } //Console.WriteLine(this.ToString() + " release save"); // Trigger content saved event OnContentSaved(); }
/// <summary> /// Saves directory scan log to XML /// </summary> public static void SaveDirScanLog() { // Directory scan Logs string path = Path.Combine(GetBasePath(true), DIR_SCAN_LOG_XML + ".xml"); // Save data into temporary file, so that if application crashes in middle of saving XML is not corrupted! string tempPath = Path.Combine(Organization.GetBasePath(true), ACTION_LOG_XML + "_TEMP.xml"); lock (DirScanLogFileLock) { using (XmlTextWriter xw = new XmlTextWriter(tempPath, Encoding.ASCII)) { xw.Formatting = Formatting.Indented; xw.WriteStartElement(DIR_SCAN_LOG_XML); for (int i = 0; i < DirScanLog.Count; i++) { DirScanLog[i].Save(xw, true); } xw.WriteEndElement(); } // Delete previous save data if (File.Exists(path)) { File.Delete(path); } // Move tempoarary save file to default try { File.Move(tempPath, path); } catch { } } }
/// <summary> /// Saves action log to XML /// </summary> public static void SaveActionLog() { // Action Logs string path = Path.Combine(GetBasePath(true), ACTION_LOG_XML + ".xml"); // Save data into temporary file, so that if application crashes in middle of saving XML is not corrupted! string tempPath = Path.Combine(Organization.GetBasePath(true), ACTION_LOG_XML + "_TEMP" + Guid.NewGuid().ToString() + ".xml"); lock (ActionLogLock) { lock (ActionLogFileLock) { using (XmlTextWriter xw = new XmlTextWriter(tempPath, Encoding.ASCII)) { xw.Formatting = Formatting.Indented; xw.WriteStartElement(ACTION_LOG_XML); foreach (OrgItem action in ActionLog) { action.Save(xw, false); } xw.WriteEndElement(); } // Delete previous save data if (File.Exists(path)) { File.Delete(path); } // Move tempoarary save file to default File.Move(tempPath, path); } } }
/// <summary> /// Load collection from saved XML file /// </summary> public void Load(bool doUpdating) { XmlTextReader reader = null; XmlDocument xmlDoc = new XmlDocument(); try { string path = Path.Combine(Organization.GetBasePath(false), XML_ROOT + ".xml"); if (File.Exists(path)) { // Use dummy collection to load into so that loading doesn't hog use of object ContentCollection loadContent = new ContentCollection(this.ContentType, "Loading Shows"); lock (XmlLock) { // Load XML reader = new XmlTextReader(path); xmlDoc.Load(reader); // Extract data XmlNodeList contentNodes = xmlDoc.DocumentElement.ChildNodes; for (int i = 0; i < contentNodes.Count; i++) { // Update loading progress OnLoadProgressChange((int)(((double)i / contentNodes.Count) * 100)); // All elements will be content items or last update time if (contentNodes[i].Name == "LastUpdate") { loadContent.LastUpdate = contentNodes[i].InnerText; } else { // Load content from element based on type switch (this.ContentType) { case ContentType.TvShow: TvShow show = new TvShow(); if (show.Load(contentNodes[i])) { bool rootFolderExists = false; foreach (ContentRootFolder folder in Settings.GetAllRootFolders(this.ContentType, true)) { if (folder.FullPath == show.RootFolder) { rootFolderExists = true; } } if (!rootFolderExists || !Directory.Exists(show.Path)) { continue; } loadContent.Add(show); if (doUpdating) { show.UpdateMissing(); } } break; case ContentType.Movie: Movie movie = new Movie(); if (movie.Load(contentNodes[i])) { loadContent.Add(movie); } break; default: throw new Exception("Unknown content type"); } } } } // Update progress OnLoadProgressChange(100); this.LastUpdate = loadContent.LastUpdate; this.Clear(); AddMultiple(loadContent); } } catch (Exception e) { MessageBox.Show(e.ToString(), "Error loading " + this.ContentType + "s from saved data!"); } finally { if (reader != null) { reader.Close(); } } // Start updating of TV episode in scan dirs. if (this.ContentType == ContentType.TvShow && doUpdating) { TvItemInScanDirHelper.DoUpdate(false); TvItemInScanDirHelper.StartUpdateTimer(); } // Trigger load complete event OnLoadComplete(); }
/// <summary> /// Updates show's season/episode information from database. Use for newly /// added shows only, as it will replace all episode information in show. /// </summary> /// <param name="show">Show to load episode information into</param> protected override bool DoUpdate(string mirror, Content content) { TvShow show = (TvShow)content; bool success = true; string tempPath = string.Empty; try { // Download episodes XML string string showUrl = mirror + "/api/" + API_KEY + "/series/" + show.Id + "/all/en.zip"; string basePath = Organization.GetBasePath(true); Guid guid = Guid.NewGuid(); tempPath = Path.Combine(basePath, guid.ToString()); Directory.CreateDirectory(tempPath); string zipPath = Path.Combine(tempPath, "data" + ".zip"); string extractPath = Path.Combine(tempPath, "en.xml"); WebClient webClient = new WebClient(); webClient.DownloadFile(showUrl, zipPath); ZipFile zip = ZipFile.Read(zipPath); foreach (ZipEntry entry in zip.Entries) { if (entry.FileName == "en.xml") { entry.Extract(tempPath, ExtractExistingFileAction.OverwriteSilently); break; } } zip.Dispose(); XmlDocument showDoc = new XmlDocument(); showDoc.Load(extractPath); // Get root element and children XmlElement root = showDoc.DocumentElement; XmlNodeList rootNodes = root.ChildNodes; // Go through each node and get info for each episode foreach (XmlNode node in rootNodes) { if (node.Name == "Series") { XmlNodeList serNodes = node.ChildNodes; foreach (XmlNode subNode in serNodes) { switch (subNode.Name) { case "Genre": string[] genres = subNode.InnerText.Split('|'); foreach (string genre in genres) { if (!string.IsNullOrWhiteSpace(genre) && !show.DatabaseGenres.Contains(genre)) { show.DatabaseGenres.Add(genre); } } break; } } } else if (node.Name == "Episode") { TvEpisode ep = new TvEpisode(show); int season = -1; XmlNodeList subNodes = node.ChildNodes; foreach (XmlNode subNode in subNodes) { switch (subNode.Name) { case "EpisodeNumber": int epNumber = 0; int.TryParse(subNode.InnerText, out epNumber); ep.DatabaseNumber = epNumber; break; case "DVD_episodenumber": double dvdNumber = -1; if (double.TryParse(subNode.InnerText, out dvdNumber)) { ep.DatabaseDvdNumber = (int)dvdNumber; } break; case "EpisodeName": ep.DatabaseName = subNode.InnerText; break; case "SeasonNumber": season = Convert.ToInt32(subNode.InnerText); ep.Season = season; break; case "FirstAired": DateTime airData; DateTime.TryParse(subNode.InnerText, out airData); ep.DatabaseAirDate = airData; break; case "Overview": ep.DatabaseOverview = subNode.InnerText; break; } } ep.InDatabase = true; if (ep.DisplayNumber > -1 && season > -1) { // If episode already exists just update it, else add it TvEpisode existingMatch; if (show.FindEpisode(ep.Season, ep.DatabaseNumber, true, out existingMatch)) { existingMatch.DatabaseName = ep.DatabaseName; existingMatch.DatabaseAirDate = ep.DatabaseAirDate; existingMatch.DatabaseOverview = ep.DatabaseOverview; existingMatch.InDatabase = true; } else { show.Episodes.Add(ep); } } } } showDoc = null; } catch (Exception e) { Console.WriteLine("Exception caught on TvDb update: " + e.ToString()); success = false; } finally { if (Directory.Exists(tempPath)) { Directory.Delete(tempPath, true); } } return(success); }
/// <summary> /// Loads settings from XML. /// </summary> public static void Load() { string basePath = Organization.GetBasePath(false); if (!Directory.Exists(basePath)) { return; } // Initialize file types to defautls VideoFileTypes = new ObservableCollection <string>(); foreach (string type in DefaultVideoFileTypes) { VideoFileTypes.Add(type); } DeleteFileTypes = new ObservableCollection <string>(); foreach (string type in DefaultDeleteFileTypes) { DeleteFileTypes.Add(type); } IgnoreFileTypes = new ObservableCollection <string>(); foreach (string type in DefaultIgnoreFileTypes) { IgnoreFileTypes.Add(type); } // Load settings XML string path = Path.Combine(basePath, ROOT_XML + ".xml"); if (File.Exists(path)) { // Load XML XmlTextReader reader = new XmlTextReader(path); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(reader); foreach (XmlNode propNode in xmlDoc.DocumentElement.ChildNodes) { XmlElements element; if (!Enum.TryParse <XmlElements>(propNode.Name, out element)) { continue; } string value = propNode.InnerText; switch (element) { case XmlElements.ScanDirectories: ScanDirectories = new ObservableCollection <OrgFolder>(); foreach (XmlNode scanDirNode in propNode.ChildNodes) { OrgFolder folder = new OrgFolder(); folder.Load(scanDirNode); ScanDirectories.Add(folder); } break; case XmlElements.TvFileFormat: TvFileFormat.Load(propNode); break; case XmlElements.MovieFileFormat: MovieFileFormat.Load(propNode); break; case XmlElements.MovieFolderColletion: MovieFolders.Load(propNode); break; case XmlElements.TvFolderCollection: TvFolders.Load(propNode); break; case XmlElements.VideoFileTypes: VideoFileTypes = new ObservableCollection <string>(); foreach (XmlNode fileTypeNode in propNode.ChildNodes) { string videoType = fileTypeNode.InnerText; if (videoType.StartsWith(".")) { videoType = videoType.Substring(1, videoType.Length - 1); } VideoFileTypes.Add(videoType); } break; case XmlElements.DeleteFileTypes: DeleteFileTypes = new ObservableCollection <string>(); foreach (XmlNode fileTypeNode in propNode.ChildNodes) { string delType = fileTypeNode.InnerText; if (delType.StartsWith(".")) { delType = delType.Substring(1, delType.Length - 1); } DeleteFileTypes.Add(delType); } break; case XmlElements.IgnoreFileTypes: IgnoreFileTypes = new ObservableCollection <string>(); foreach (XmlNode fileTypeNode in propNode.ChildNodes) { string ignoreType = fileTypeNode.InnerText; if (ignoreType.StartsWith(".")) { ignoreType = ignoreType.Substring(1, ignoreType.Length - 1); } IgnoreFileTypes.Add(ignoreType); } break; case XmlElements.AutoMoveSetups: AutoMoveSetups = new ObservableCollection <AutoMoveFileSetup>(); foreach (XmlNode setupNode in propNode.ChildNodes) { AutoMoveFileSetup setup = new AutoMoveFileSetup(); setup.Load(setupNode); AutoMoveSetups.Add(setup); } break; case XmlElements.Gui: GuiControl.Load(propNode); break; case XmlElements.General: General.Load(propNode); break; case XmlElements.MovieFolders: MovieFolders.Clear(); foreach (XmlNode movieFolderNode in propNode.ChildNodes) { ContentRootFolder folder = new ContentRootFolder(ContentType.Movie); folder.Load(movieFolderNode); MovieFolders.Add(folder); } break; case XmlElements.TvFolders: TvFolders.Clear(); foreach (XmlNode tvFolderNode in propNode.ChildNodes) { ContentRootFolder folder = new ContentRootFolder(ContentType.TvShow); folder.Load(tvFolderNode); TvFolders.Add(folder); } break; } } } OnSettingsModified(true); }
/// <summary> /// Save settings to XML. /// </summary> public static void Save(bool triggerModifiedEvent = true) { string path = Path.Combine(Organization.GetBasePath(true), ROOT_XML + ".xml"); // Save data into temporary file, so that if application crashes in middle of saving XML is not corrupted! string tempPath = Path.Combine(Organization.GetBasePath(true), ROOT_XML + "_TEMP.xml"); using (XmlTextWriter xw = new XmlTextWriter(tempPath, Encoding.ASCII)) { xw.Formatting = Formatting.Indented; // Start season element xw.WriteStartElement(ROOT_XML); foreach (XmlElements element in Enum.GetValues(typeof(XmlElements))) { // Deprecated switch (element) { case XmlElements.MovieFolders: case XmlElements.TvFolders: continue; } xw.WriteStartElement(element.ToString()); switch (element) { case XmlElements.ScanDirectories: foreach (OrgFolder scanDir in ScanDirectories) { scanDir.Save(xw); } break; case XmlElements.TvFileFormat: TvFileFormat.Save(xw); break; case XmlElements.MovieFileFormat: MovieFileFormat.Save(xw); break; case XmlElements.MovieFolderColletion: MovieFolders.Save(xw); break; case XmlElements.TvFolderCollection: TvFolders.Save(xw); break; case XmlElements.VideoFileTypes: foreach (string fileType in VideoFileTypes) { xw.WriteElementString(FILE_TYPE_XML, fileType); } break; case XmlElements.DeleteFileTypes: foreach (string fileType in DeleteFileTypes) { xw.WriteElementString(FILE_TYPE_XML, fileType); } break; case XmlElements.IgnoreFileTypes: foreach (string fileType in IgnoreFileTypes) { xw.WriteElementString(FILE_TYPE_XML, fileType); } break; case XmlElements.AutoMoveSetups: foreach (AutoMoveFileSetup setup in AutoMoveSetups) { setup.Save(xw); } break; case XmlElements.Gui: GuiControl.Save(xw); break; case XmlElements.General: General.Save(xw); break; default: throw new Exception("Unkonw element!"); } xw.WriteEndElement(); } xw.WriteEndElement(); } // Delete previous save data if (File.Exists(path)) { File.Delete(path); } // Move tempoarary save file to default File.Move(tempPath, path); if (triggerModifiedEvent) { OnSettingsModified(false); } }