} // ----------------------------------------- /// <summary> /// Take a crushed archive and extract only the info file, Returns a customized object with some info /// </summary> /// <param name="arcFile"></param> /// <param name="onComplete">(null) on error, /// OBJECT = /// cd:CueReader, /// cover:Path of image cover or null /// sizeArc:Size of ARC in bytes /// /// </param> /// <returns>Success</returns> public static bool loadQuickInfo(string arcFile, Action <Object> onComplete) { if (LOCKED) { ERROR = "LOCKED"; return(false); } if (!check_file_(arcFile, CDCRUSH_EXTENSION)) { return(false); } LOCKED = true; // Delete old files from previous quickInfos, IF ANY FileTools.tryDelete(Path.Combine(TEMP_FOLDER, CDCRUSH_SETTINGS)); FileTools.tryDelete(Path.Combine(TEMP_FOLDER, CDCRUSH_COVER)); var arc = new FreeArc(TOOLS_PATH); // -- arc.onComplete = (success) => { LOCKED = false; if (success) // OK { // Continue var cd = new CueReader(); if (!cd.loadJson(Path.Combine(TEMP_FOLDER, CDCRUSH_SETTINGS))) { ERROR = cd.ERROR; onComplete(null); return; } // This is the object with the info returned to user var info = new { cd, sizeArc = (int)new FileInfo(arcFile).Length, cover = Path.Combine(TEMP_FOLDER, CDCRUSH_COVER) }; LOG.log("= QuickLoaded `{0}` - [OK]", arcFile); onComplete(info); } else { ERROR = arc.ERROR; onComplete(null); } }; // : Actually extract arc.extractFiles(arcFile, new[] { CDCRUSH_SETTINGS, CDCRUSH_COVER }, TEMP_FOLDER); return(true); } // -----------------------------------------
// -- public JobRestore(RestoreParams p) : base("Restore CD") { // Check for input files // -------------------- if (!CDCRUSH.check_file_(p.inputFile, CDCRUSH.CDCRUSH_EXTENSION)) { fail(msg: CDCRUSH.ERROR); return; } if (string.IsNullOrEmpty(p.outputDir)) { p.outputDir = Path.GetDirectoryName(p.inputFile); } // -- Output folder check if (p.flag_folder) { p.outputDir = CDCRUSH.checkCreateUniqueOutput(p.outputDir, Path.GetFileNameWithoutExtension(p.inputFile)); if (p.outputDir == null) { fail("Output Dir Error " + p.outputDir); return; } } else { if (!FileTools.createDirectory(p.outputDir)) { fail(msg: "Can't create Output Dir " + p.outputDir); return; } } // -- p.tempDir = Path.Combine(CDCRUSH.TEMP_FOLDER, Guid.NewGuid().ToString().Substring(0, 12)); if (!FileTools.createDirectory(p.tempDir)) { fail(msg: "Can't create TEMP dir"); return; } // Safeguard, even if the GUI doesn't allow it if (p.flag_encCue) { p.flag_forceSingle = false; } // IMPORTANT!! sharedData gets set by value, NOT A POINTER, do not make changes to p after this jobData = p; // -- hack_setExpectedProgTracks(p.expectedTracks + 3); // - Extract the Archive // ----------------------- add(new CTask((t) => { var arc = new FreeArc(CDCRUSH.TOOLS_PATH); t.handleCliReport(arc); arc.extractAll(p.inputFile, p.tempDir); arc.onProgress = (pr) => t.PROGRESS = pr; // In case the operation is aborted t.killExtra = () => { arc.kill(); }; }, "Extracting", "Extracting the archive to temp folder")); // - Read JSON data // - Restore tracks // - JOIN if it has to // ----------------------- add(new CTask((t) => { var cd = new CueReader(); jobData.cd = cd; // -- if (!cd.loadJson(Path.Combine(p.tempDir, CDCRUSH.CDCRUSH_SETTINGS))) { t.fail(msg: cd.ERROR); return; } LOG.log("== Detailed CD INFOS =="); LOG.log(cd.getDetailedInfo()); // - Push TASK RESTORE tasks right after this one foreach (CueTrack tr in cd.tracks) { addNextAsync(new TaskRestoreTrack(tr)); // Note: Task will take care of encoded cue case } //-- t.complete(); }, "-Preparing to Restore", "Reading stored CD info and preparing track restore tasks")); // - Join Tracks, but only when not creating .Cue/Enc Audio // ----------------------- if (!p.flag_encCue) { add(new CTask((t) => { CueReader cd = jobData.cd; // -- Join tracks if (p.flag_forceSingle || !cd.MULTIFILE) { // The task will read data from the shared job data var // Will join all tracks in place into track01.bin // Note: Sets track.workingFile to null to moved track addNext(new TaskJoinTrackFiles()); } //-- t.complete(); }, "-Preparing to Join")); } // - Prepare tracks `trackfile` which is the track written to the CUE // - Convert tracks // - Move files to final destination // - Create CUE files // - Delete Temp Files // ----------------------- add(new CTask((t) => { CueReader cd = jobData.cd; int progressStep = (int)Math.Round(100.0f / cd.tracks.Count); // -- foreach (var track in cd.tracks) { if (p.flag_encCue) { string ext = Path.GetExtension(track.workingFile); if (cd.tracks.Count == 1) { track.trackFile = $"{cd.CD_TITLE}{ext}"; } else { track.trackFile = $"{cd.CD_TITLE} (track {track.trackNo}){ext}"; } if (!cd.MULTIFILE) { track.setNewTimesReset(); // :: CONVERTS SINGLE TO MULTI } } else { if (p.flag_forceSingle && cd.MULTIFILE) // :: CONVERT MULTI TO SINGLE { track.setNewTimesBasedOnSector(); } if (cd.MULTIFILE && !p.flag_forceSingle) { track.trackFile = cd.CD_TITLE + " " + track.getFilenameRaw(); } if (!cd.MULTIFILE || p.flag_forceSingle) { if (track.trackNo == 1) { track.trackFile = cd.CD_TITLE + ".bin"; } else { track.trackFile = null; } } } // -- // Move ALL files to final output folder // NULL workingFile means that is has been deleted if (track.workingFile != null) { FileTools.tryMove(track.workingFile, Path.Combine(p.outputDir, track.trackFile)); t.PROGRESS += progressStep; } } // -- end track processing // -- // Create CUE File if (!cd.saveCUE(Path.Combine(p.outputDir, cd.CD_TITLE + ".cue"))) { t.fail(cd.ERROR); return; } t.complete(); }, "Moving, Finalizing", "Calculating track data and creating .CUE")); // - Complete - }// -----------------------------------------
} // ----------------------------------------- /// <summary> /// Take a crushed archive and extract only the info file, Returns a customized object with some info /// </summary> /// <param name="arcFile"></param> /// <param name="onComplete">(null) if error</param> public static bool loadQuickInfo(string arcFile, Action <Object> onComplete) { if (LOCKED) { ERROR = "LOCKED"; return(false); } if (!check_file_(arcFile, CDCRUSH_EXTENSION)) { return(false); } LOCKED = true; // Delete old files from previous quickInfos FileTools.tryDelete(Path.Combine(TEMP_FOLDER, CDCRUSH_SETTINGS)); FileTools.tryDelete(Path.Combine(TEMP_FOLDER, CDCRUSH_COVER)); var arc = new FreeArc(TOOLS_PATH); // -- arc.onComplete = (success) => { LOCKED = false; if (success) // OK { // Continue var cd = new CueReader(); if (!cd.loadJson(Path.Combine(TEMP_FOLDER, CDCRUSH_SETTINGS))) { ERROR = cd.ERROR; onComplete(null); return; } var info = new { title = cd.CD_TITLE, size0 = (int)new FileInfo(arcFile).Length, size1 = cd.CD_TOTAL_SIZE, audio = cd.CD_AUDIO_QUALITY, tracks = cd.tracks.Count, md5 = cd.getFirstDataTrackMD5(), cover = Path.Combine(TEMP_FOLDER, CDCRUSH_COVER) }; onComplete(info); } else { ERROR = arc.ERROR; onComplete(null); } }; // : Actually extract arc.extractFiles(arcFile, new[] { CDCRUSH_SETTINGS, CDCRUSH_COVER }, TEMP_FOLDER); return(true); } // -----------------------------------------
// -- public JobRestore(RestoreParams p) : base("Restore CD") { // Check for input files // :: -------------------- if (!CDCRUSH.check_file_(p.inputFile, CDCRUSH.CDCRUSH_EXTENSION)) { fail(msg: CDCRUSH.ERROR); return; } if (string.IsNullOrEmpty(p.outputDir)) { p.outputDir = Path.GetDirectoryName(p.inputFile); } if (p.flag_folder) { try { p.outputDir = Path.Combine(p.outputDir, Path.GetFileNameWithoutExtension(p.inputFile)); } catch (ArgumentException) { fail("Output Dir Error " + p.outputDir); return; } } if (!FileTools.createDirectory(p.outputDir)) { fail(msg: "Can't create Output Dir " + p.outputDir); return; } p.tempDir = Path.Combine(CDCRUSH.TEMP_FOLDER, Guid.NewGuid().ToString().Substring(0, 12)); if (!FileTools.createDirectory(p.tempDir)) { fail(msg: "Can't create TEMP dir"); return; } // IMPORTANT!! sharedData gets set by value, NOT A POINTER, do not make changes to p after this jobData = p; // - Extract the Archive // ----------------------- add(new CTask((t) => { var arc = new FreeArc(CDCRUSH.TOOLS_PATH); t.handleCliReport(arc); arc.extractAll(p.inputFile, p.tempDir); // In case the operation is aborted t.killExtra = () => { arc.kill(); }; }, "Extracting", true)); // - Read JSON data // - Restore tracks // - JOIN if it has to // ----------------------- add(new CTask((t) => { var cd = new CueReader(); jobData.cd = cd; // This runs in sync: if (!cd.loadJson(Path.Combine(p.tempDir, CDCRUSH.CDCRUSH_SETTINGS))) { t.fail(msg: cd.ERROR); return; } //-- #if DEBUG cd.debugInfo(); #endif // - Push TASK RESTORE tasks right after this one foreach (CueTrack tr in cd.tracks) { addNextAsync(new TaskRestoreTrack(tr)); } //-- t.complete(); }, "Preparing to Restore")); // - Join Tracks // ----------------------- add(new CTask((t) => { CueReader cd = jobData.cd; // -- Join tracks if (p.flag_forceSingle || !cd.MULTIFILE) { // The task will read data from the shared job data var // Will join all tracks in place into track01.bin // Note: Sets track.workingFile to null to moved track addNext(new TaskJoinTrackFiles()); } //-- t.complete(); }, "Preparing to Join")); // - Prepare tracks `trackfile` which is the track written to the CUE // - Convert tracks // - Move files to final destination // - Create CUE files // - Delete Temp Files // ----------------------- add(new CTask((t) => { CueReader cd = jobData.cd; // -- foreach (var track in cd.tracks) { if (p.flag_forceSingle && cd.MULTIFILE) // :: CONVERT MULTI TO SINGLE { track.setNewTimesBasedOnSector(); } if (cd.MULTIFILE && !p.flag_forceSingle) { track.trackFile = cd.CD_TITLE + " " + track.getFilenameRaw(); } if (!cd.MULTIFILE || p.flag_forceSingle) { if (track.trackNo == 1) { track.trackFile = cd.CD_TITLE + ".bin"; } else { track.trackFile = null; } } // -- // Move ALL files to final output folder // NULL workingFile means that is has been deleted if (track.workingFile != null) { FileTools.tryMove(track.workingFile, Path.Combine(p.outputDir, track.trackFile)); } } // -- end track processing // -- // Create CUE File if (!cd.saveCUE(Path.Combine(p.outputDir, cd.CD_TITLE + ".cue"))) { t.fail(cd.ERROR); return; } t.complete(); }, "Moving, Finalizing")); // - Complete - }// -----------------------------------------