private static void CleanupFiles(List <string> removeFiles, bool archive) { string appDataPath = DirectoryUtilities.GetUserStoragePath(HandBrakeVersionHelper.IsNightly()); // Cleanup old/unused queue files for now. foreach (string file in removeFiles) { Match m = Regex.Match(file, @"([0-9]+).json"); if (m.Success) { int processId = int.Parse(m.Groups[1].ToString()); if (GeneralUtilities.IsPidACurrentHandBrakeInstance(processId)) { continue; } } string fullPath = Path.Combine(appDataPath, file); if (archive) { File.Move(fullPath, fullPath + ".archive"); } else { File.Delete(fullPath); } } TidyArchiveFiles(); }
public void BackupQueue(string exportPath) { lock (this.queueFileLock) { string appDataPath = DirectoryUtilities.GetUserStoragePath(HandBrakeVersionHelper.IsNightly()); string tempPath = !string.IsNullOrEmpty(exportPath) ? exportPath : Path.Combine(appDataPath, string.Format(this.queueFile, string.Empty)); // Make a copy of the file before we replace it. This way, if we crash we can recover. if (File.Exists(tempPath)) { File.Copy(tempPath, tempPath + ".last"); } using (StreamWriter writer = new StreamWriter(tempPath)) { List <QueueTask> tasks = this.queue.Where(item => item.Status != QueueItemStatus.Completed).ToList(); string queueJson = JsonSerializer.Serialize(tasks, JsonSettings.Options); writer.Write(queueJson); } if (File.Exists(tempPath + ".last")) { File.Delete(tempPath + ".last"); } } }
/// <summary> /// Recover a queue from file. /// </summary> /// <param name="encodeQueue"> /// The encode Queue. /// </param> /// <param name="errorService"> /// The error Service. /// </param> /// <param name="silentRecovery"> /// The silent Recovery. /// </param> /// <param name="queueFilter"> /// The queue Filter. /// </param> /// <returns> /// The <see cref="bool"/>. /// </returns> public static bool RecoverQueue(IQueueService encodeQueue, IErrorService errorService, bool silentRecovery, List <string> queueFilter) { string appDataPath = DirectoryUtilities.GetUserStoragePath(HandBrakeVersionHelper.IsNightly()); List <string> queueFiles = CheckQueueRecovery(queueFilter); MessageBoxResult result = MessageBoxResult.None; if (!silentRecovery) { if (queueFiles.Count == 1) { result = errorService.ShowMessageBox( Properties.Resources.Queue_RecoverQueueQuestionSingular, Properties.Resources.Queue_RecoveryPossible, MessageBoxButton.YesNo, MessageBoxImage.Question); } else if (queueFiles.Count > 1) { result = errorService.ShowMessageBox( Properties.Resources.Queue_RecoverQueueQuestionPlural, Properties.Resources.Queue_RecoveryPossible, MessageBoxButton.YesNo, MessageBoxImage.Question); } } else { result = MessageBoxResult.Yes; } if (result == MessageBoxResult.Yes) { bool isRecovered = false; foreach (string file in queueFiles) { // Recover the Queue encodeQueue.RestoreQueue(Path.Combine(appDataPath, file)); isRecovered = true; // Cleanup CleanupFiles(new List <string> { file }, false); } return(isRecovered); } CleanupFiles(queueFiles, true); return(false); }
public void RestoreQueue(string importPath) { string appDataPath = DirectoryUtilities.GetUserStoragePath(HandBrakeVersionHelper.IsNightly()); string tempPath = !string.IsNullOrEmpty(importPath) ? importPath : (appDataPath + string.Format(this.queueFile, string.Empty)); if (File.Exists(tempPath)) { bool invokeUpdate = false; using (StreamReader stream = new StreamReader(!string.IsNullOrEmpty(importPath) ? importPath : tempPath)) { string queueJson = stream.ReadToEnd(); List <QueueTask> list; try { list = JsonSerializer.Deserialize <List <QueueTask> >(queueJson); } catch (Exception exc) { throw new GeneralApplicationException(Resources.Queue_UnableToRestoreFile, Resources.Queue_UnableToRestoreFileExtended, exc); } if (list != null) { foreach (QueueTask item in list) { if (item.Status != QueueItemStatus.Completed && item.TaskType != QueueTaskType.Breakpoint) { // Reset InProgress/Error to Waiting so it can be processed if (item.Status == QueueItemStatus.InProgress || item.Status == QueueItemStatus.Paused) { item.Status = QueueItemStatus.Error; } this.queue.Add(item); } } } invokeUpdate = true; } if (invokeUpdate) { this.InvokeQueueChanged(EventArgs.Empty); } } }
/// <summary> /// The reset to defaults. /// </summary> public static void ResetToDefaults() { string appDataFolder = DirectoryUtilities.GetUserStoragePath(HandBrakeVersionHelper.IsNightly()); DeleteFile(Path.Combine(appDataFolder, "presets.json")); DeleteFile(Path.Combine(appDataFolder, "settings.json")); DirectoryInfo info = new DirectoryInfo(appDataFolder); IEnumerable <FileInfo> logFiles = info.GetFiles("*.json").Where(f => f.Name.StartsWith("hb_queue_recovery")); foreach (FileInfo file in logFiles) { DeleteFile(Path.Combine(appDataFolder, file.Name)); } }
/// <summary> /// Check if the queue recovery file contains records. /// If it does, it means the last queue did not complete before HandBrake closed. /// So, return a boolean if true. /// </summary> /// <param name="filterQueueFiles"> /// The filter Queue Files. /// </param> /// <returns> /// True if there is a queue to recover. /// </returns> public static List <string> CheckQueueRecovery(List <string> filterQueueFiles) { try { // Check for any Corrupted Backup Files and try recover them RecoverFromBackupFailure(); // Now check for all available recovery files. (There may be more than 1 for multi-instance support) string tempPath = DirectoryUtilities.GetUserStoragePath(HandBrakeVersionHelper.IsNightly()); DirectoryInfo info = new DirectoryInfo(tempPath); IEnumerable <FileInfo> foundFiles = info.GetFiles("*.json").Where(f => f.Name.StartsWith(QueueFileName)); var queueFiles = GetFilesExcludingActiveProcesses(foundFiles, filterQueueFiles); if (!queueFiles.Any()) { return(queueFiles); } List <string> removeFiles = new List <string>(); List <string> acceptedFiles = new List <string>(); foreach (string file in queueFiles) { try { using (StreamReader stream = new StreamReader(file)) { List <QueueTask> list = list = JsonSerializer.Deserialize <List <QueueTask> >(stream.ReadToEnd(), JsonSettings.Options); if (list != null && list.Count == 0) { removeFiles.Add(file); } if (list != null && list.Count != 0) { List <QueueTask> tasks = list.Where(l => l.Status != QueueItemStatus.Completed).ToList(); if (tasks.Count != 0) { acceptedFiles.Add(Path.GetFileName(file)); } else { removeFiles.Add(file); } } } } catch (Exception exc) { Debug.WriteLine(exc); } } CleanupFiles(removeFiles, false); return(acceptedFiles); } catch (Exception exc) { Debug.WriteLine(exc); return(new List <string>()); // Keep quiet about the error. } }
public static void ResetArchives() { string appDataPath = DirectoryUtilities.GetUserStoragePath(HandBrakeVersionHelper.IsNightly()); DirectoryInfo info = new DirectoryInfo(appDataPath); IEnumerable <FileInfo> foundFiles = info.GetFiles("*.archive").Where(f => f.Name.StartsWith(QueueFileName)); foreach (FileInfo file in foundFiles) { string fullPath = Path.Combine(appDataPath, file.Name); File.Move(fullPath, fullPath.Replace(".archive", string.Empty)); } }
/// <summary> /// Tidy up archive files older than 7 days. /// Gives the user an opportunity to recover a queue file they accidentally chose not to import. /// </summary> private static void TidyArchiveFiles() { string appDataPath = DirectoryUtilities.GetUserStoragePath(HandBrakeVersionHelper.IsNightly()); DirectoryInfo info = new DirectoryInfo(appDataPath); IEnumerable <FileInfo> foundFiles = info.GetFiles("*.archive").Where(f => f.Name.StartsWith(QueueFileName)); DateTime lastWeek = DateTime.Now.AddDays(-7); foreach (FileInfo file in foundFiles) { if (file.CreationTime < lastWeek) { string fullPath = Path.Combine(appDataPath, file.Name); File.Delete(fullPath); } } }
private static void RecoverFromBackupFailure() { string appDataPath = DirectoryUtilities.GetUserStoragePath(HandBrakeVersionHelper.IsNightly()); DirectoryInfo info = new DirectoryInfo(appDataPath); IEnumerable <FileInfo> foundFiles = info.GetFiles("*.last"); foreach (FileInfo file in foundFiles) { string corruptedFile = file.FullName.Replace(".last", string.Empty); if (File.Exists(corruptedFile)) { File.Delete(corruptedFile); } File.Move(file.FullName, corruptedFile); } }
public static bool ArchivesExist() { string appDataPath = DirectoryUtilities.GetUserStoragePath(HandBrakeVersionHelper.IsNightly()); DirectoryInfo info = new DirectoryInfo(appDataPath); IEnumerable <FileInfo> foundFiles = info.GetFiles("*.archive").Where(f => f.Name.StartsWith(QueueFileName)); return(foundFiles.Any()); }
/// <summary> /// Load the User Settings /// </summary> private void Load() { try { // Load up the users current settings file. if (File.Exists(this.settingsFile)) { using (StreamReader reader = new StreamReader(this.settingsFile)) { string appSettings = reader.ReadToEnd(); Dictionary <string, object> deserialisedSettings = JsonSerializer.Deserialize <Dictionary <string, object> >(appSettings, JsonSettings.Options); this.userSettings = deserialisedSettings; } } else if (HandBrakeVersionHelper.IsNightly() && File.Exists(this.releaseSettingsFile)) { // Port the release versions config to the nightly. if (!Directory.Exists(DirectoryUtilities.GetUserStoragePath(true))) { Directory.CreateDirectory(DirectoryUtilities.GetUserStoragePath(true)); } File.Copy(this.releaseSettingsFile, this.nightlySettingsFile); using (StreamReader reader = new StreamReader(this.settingsFile)) { string appSettings = reader.ReadToEnd(); Dictionary <string, object> deserialisedSettings = JsonSerializer.Deserialize <Dictionary <string, object> >(appSettings, JsonSettings.Options); this.userSettings = deserialisedSettings; } } else { this.userSettings = new Dictionary <string, object>(); } // Add any missing / new settings Dictionary <string, object> defaults = this.GetDefaults(); foreach (var item in defaults.Where(item => !this.userSettings.Keys.Contains(item.Key))) { this.userSettings.Add(item.Key, item.Value); this.Save(); } this.ResetUnsupportedSettings(); } catch (Exception exc) { try { this.userSettings = this.GetDefaults(); if (File.Exists(this.settingsFile)) { File.Delete(this.settingsFile); } this.Save(); throw new GeneralApplicationException(Resources.UserSettings_YourSettingsHaveBeenReset, Resources.UserSettings_YourSettingsAreCorrupt, exc); } catch (Exception) { throw new GeneralApplicationException(string.Format(Resources.UserSettings_UnableToLoad, this.settingsFile), Resources.UserSettings_UnableToLoadSolution, exc); } } }
/// <summary> /// Check for Updates /// </summary> /// <param name="callback"> /// The callback. /// </param> public void CheckForUpdates(Action <UpdateCheckInformation> callback) { ThreadPool.QueueUserWorkItem( delegate { try { // Figure out which appcast we want to read. string url = SystemInfo.IsArmDevice ? Constants.Appcast64Arm : Constants.Appcast64; if (HandBrakeVersionHelper.IsNightly()) { url = SystemInfo.IsArmDevice ? Constants.AppcastUnstable64Arm : Constants.AppcastUnstable64; } // Fetch the Appcast from our server. HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.AllowAutoRedirect = false; // We will never do this. request.UserAgent = string.Format("HandBrake Win Upd {0}", HandBrakeVersionHelper.GetVersionShort()); WebResponse response = request.GetResponse(); // Parse the data with the AppcastReader var reader = new AppcastReader(); reader.GetUpdateInfo(new StreamReader(response.GetResponseStream()).ReadToEnd()); // Further parse the information string build = reader.Build; int latest = int.Parse(build); // Security Check // Verify the download URL is for handbrake.fr and served over https. // This prevents a compromised appcast download tricking the GUI into downloading a file, or accessing another website or local network resource. // The download itself will also be checked against a signature later. Uri uriResult; bool result = Uri.TryCreate(reader.DownloadFile, UriKind.Absolute, out uriResult) && uriResult.Scheme == Uri.UriSchemeHttps; if (!result || (uriResult.Host != "handbrake.fr" && uriResult.Host != "download.handbrake.fr" && uriResult.Host != "github.com")) { this.userSettingService.SetUserSetting(UserSettingConstants.IsUpdateAvailableBuild, 0); callback(new UpdateCheckInformation { NewVersionAvailable = false, Error = new Exception("The HandBrake update service is currently unavailable.") }); return; } // Validate the URL from the appcast is ours. var info2 = new UpdateCheckInformation { NewVersionAvailable = latest > HandBrakeVersionHelper.Build, DescriptionUrl = reader.DescriptionUrl, DownloadFile = reader.DownloadFile, Build = reader.Build, Version = reader.Version, Signature = reader.Hash }; this.userSettingService.SetUserSetting(UserSettingConstants.IsUpdateAvailableBuild, latest); callback(info2); } catch (Exception exc) { this.userSettingService.SetUserSetting(UserSettingConstants.IsUpdateAvailableBuild, 0); callback(new UpdateCheckInformation { NewVersionAvailable = false, Error = exc }); } }); }
/// <summary> /// Generate the header for the log file. /// </summary> /// <returns> /// The generatedlog header. /// </returns> public static StringBuilder CreateLogHeader() { var logHeader = new StringBuilder(); StringBuilder gpuBuilder = new StringBuilder(); foreach (var item in SystemInfo.GetGPUInfo) { gpuBuilder.AppendLine(string.Format(" {0}", item)); } if (string.IsNullOrEmpty(gpuBuilder.ToString().Trim())) { gpuBuilder.Append("GPU Information is unavailable"); } logHeader.AppendLine(string.Format("HandBrake {0}", HandBrakeVersionHelper.GetVersion())); logHeader.AppendLine(string.Format("OS: {0}", Environment.OSVersion)); logHeader.AppendLine(string.Format("CPU: {0}", SystemInfo.GetCpu)); logHeader.AppendLine(string.Format("Ram: {0} MB, ", SystemInfo.TotalPhysicalMemory)); logHeader.AppendLine(string.Format("GPU Information:{0}{1}", Environment.NewLine, gpuBuilder.ToString().TrimEnd())); logHeader.AppendLine(string.Format("Screen: {0}x{1}", SystemInfo.ScreenBounds.Bounds.Width, SystemInfo.ScreenBounds.Bounds.Height)); logHeader.AppendLine(string.Format("Temp Dir: {0}", Path.GetTempPath())); logHeader.AppendLine(string.Format("Install Dir: {0}", Application.StartupPath)); logHeader.AppendLine(string.Format("Data Dir: {0}\n", DirectoryUtilities.GetUserStoragePath(HandBrakeVersionHelper.IsNightly()))); logHeader.AppendLine("-------------------------------------------"); return(logHeader); }