//0 = asin, 1 = uniqid, 2 = databasename, 3 = rawML, 4 = author, 5 = title public static Unpack.Metadata GetMetaDataInternal(string mobiFile, string outDir, bool saveRawML, string randomFile = "") { List <string> output = new List <string>(); FileStream fs = new FileStream(mobiFile, FileMode.Open, FileAccess.Read); if (fs == null) { throw new Exception("Unable to open mobi file."); } Unpack.Metadata md = new Unpack.Metadata(fs); if (md.mobiHeader.exthHeader == null) { throw new Exception("No EXT Header found. Ensure this book was processed with Calibre then try again."); } if (md.mobiHeader.exthHeader.CDEType != "EBOK") { if (md.mobiHeader.exthHeader.CDEType.Length == 4 && DialogResult.Yes == MessageBox.Show("The document type is not set to EBOK. Would you like this to be updated?\r\n" + "Caution: This feature is experimental and could potentially ruin your book file.", "Incorrect Content Type", MessageBoxButtons.YesNo)) { fs.Close(); fs = new FileStream(mobiFile, FileMode.Open, FileAccess.ReadWrite); if (fs == null) { throw new Exception("Unable to re-open mobi file for writing."); } md.mobiHeader.exthHeader.UpdateCDEContentType(fs); } else { fs.Close(); throw new Exception("The document type is not set to EBOK; Kindle will not display an X-Ray for this book.\r\n" + "You must either use Calibre's convert feature (Personal Doc tag under MOBI Output) or a MOBI editor (exth 501) to change this."); } } string ASIN = md.ASIN; Match match = Regex.Match(ASIN, "(^B[A-Z0-9]{9})"); if (!match.Success && DialogResult.No == MessageBox.Show(String.Format("Incorrect ASIN detected: {0}!\n" + "Kindle may not display an X-Ray for this book.\n" + "Do you wish to continue?", ASIN), "Incorrect ASIN", MessageBoxButtons.YesNo)) { fs.Close(); throw new Exception(String.Format("Incorrect ASIN detected: {0}!\r\n" + "Kindle may not display an X-Ray for this book.\r\n" + "You must either use Calibre's Quality Check plugin (Fix ASIN for Kindle Fire) " + "or a MOBI editor (exth 113 and optionally 504) to change this.", ASIN)); } if (!Properties.Settings.Default.useNewVersion && md.DBName.Length == 31) { MessageBox.Show(String.Format( "WARNING: Database Name is the maximum length. If \"{0}\" is the full book title, this should not be an issue.\r\n" + "If the title is supposed to be longer than that, you may get an error on your Kindle (WG on firmware < 5.6).\r\n" + "This can be resolved by either shortening the title in Calibre or manually changing the database name.\r\n", md.DBName)); } if (saveRawML) { // Everything else checked out, grab rawml and write to the temp file md.rawMLPath = randomFile + "\\" + Path.GetFileNameWithoutExtension(mobiFile) + ".rawml"; byte[] rawML = md.getRawML(fs); using (FileStream rawMLFile = new FileStream(md.rawMLPath, FileMode.Create, FileAccess.Write)) { rawMLFile.Write(rawML, 0, rawML.Length); } } fs.Close(); return(md); }
private void btnKindleExtras_Click(object sender, EventArgs e) { //Check current settings if (!File.Exists(txtMobi.Text)) { MessageBox.Show("Specified book was not found.", "Book Not Found"); return; } if (rdoShelfari.Checked && txtShelfari.Text == "") { MessageBox.Show("No Shelfari link was specified.", "Missing Shelfari Link"); return; } if (!File.Exists(settings.mobi_unpack)) { MessageBox.Show("Kindleunpack was not found. Please review the settings page.", "Kindleunpack Not Found"); return; } if (Properties.Settings.Default.realName.Trim().Length == 0 | Properties.Settings.Default.penName.Trim().Length == 0) { MessageBox.Show( "Both Real and Pen names are required for End Action\r\n" + "file creation. This information allows you to rate this\r\n" + "book on Amazon. Please review the settings page.", "Amazon Customer Details Not found"); return; } //Create temp dir and ensure it exists string randomFile = Functions.GetTempDirectory(); if (!Directory.Exists(randomFile)) { MessageBox.Show("Temporary path not accessible for some reason.", "Temporary Directory Error"); return; } //0 = asin, 1 = uniqid, 2 = databasename, 3 = rawML, 4 = author, 5 = title List <string> results; long rawMLSize = 0; if (settings.useKindleUnpack) { Log("Running Kindleunpack to get metadata..."); results = Functions.GetMetaData(txtMobi.Text, settings.outDir, randomFile, settings.mobi_unpack); if (!File.Exists(results[3])) { Log("Error: RawML could not be found, aborting.\r\nPath: " + results[3]); return; } rawMLSize = new FileInfo(results[3]).Length; } else { Log("Extracting metadata..."); try { Unpack.Metadata md = Functions.GetMetaDataInternal(txtMobi.Text, settings.outDir, false); rawMLSize = md.PDH.TextLength; results = md.getResults(); } catch (Exception ex) { Log("Error getting metadata: " + ex.Message); return; } } if (results.Count != 6) { Log(results[0]); return; } if (settings.saverawml && settings.useKindleUnpack) { Log("Saving rawML to dmp directory..."); File.Copy(results[3], Path.Combine(Environment.CurrentDirectory + @"\dmp", Path.GetFileName(results[3])), true); } // Added author name to log output Log(String.Format("Got metadata!\r\nDatabase Name: {0}\r\nASIN: {1}\r\nAuthor: {2}\r\nTitle: {3}\r\nUniqueID: {4}", results[2], results[0], results[4], results[5], results[1])); try { BookInfo bookInfo = new BookInfo(results[5], results[4], results[0], results[1], results[2], randomFile, Functions.RemoveInvalidFileChars(results[5]), txtShelfari.Text); Log("Attempting to build Author Profile..."); AuthorProfile ap = new AuthorProfile(bookInfo, this); if (!ap.complete) { return; } Log("Attempting to build Start Actions and End Actions..."); EndActions ea = new EndActions(ap, bookInfo, rawMLSize, this); if (!ea.complete) { return; } if (settings.useNewVersion) { ea.GenerateNew(); Log("Attempting to build Start Actions..."); ea.GenerateStartActions(); } else { ea.GenerateOld(); } if (Properties.Settings.Default.playSound) { System.Media.SoundPlayer player = new System.Media.SoundPlayer(Environment.CurrentDirectory + @"\done.wav"); player.Play(); } try { PopulateAPEAPreviews(ap, ea); } catch (Exception ex) { Log("Error populating extras preview windows: " + ex.Message); } } catch (Exception ex) { Log("An error occurred while creating the new Author Profile, Start Actions, and/or End Actions files: " + ex.Message); } }