/*************************************************************************** copyright : (C) 2003-2007 by Robby Stephenson email : robby@periapsis.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of version 2 of the GNU General Public License as * * published by the Free Software Foundation; * * * ***************************************************************************/ #include "alexandriaexporter.h" #include "../document.h" #include "../collection.h" #include "../tellico_kernel.h" #include "../imagefactory.h" #include "../image.h" #include "../tellico_utils.h" #include "../tellico_debug.h" #include "../progressmanager.h" #include #include #include #include namespace { static const int ALEXANDRIA_MAX_SIZE_SMALL = 60; static const int ALEXANDRIA_MAX_SIZE_MEDIUM = 140; } using Tellico::Export::AlexandriaExporter; TQString& AlexandriaExporter::escapeText(TQString& str_) { str_.replace('"', TQString::fromLatin1("\\\"")); return str_; } TQString AlexandriaExporter::formatString() const { return i18n("Alexandria"); } bool AlexandriaExporter::exec() { Data::CollPtr coll = collection(); if(!coll || (coll->type() != Data::Collection::Book && coll->type() != Data::Collection::Bibtex)) { myLog() << "AlexandriaExporter::exec() - bad collection" << endl; return false; } const TQString alexDirName = TQString::fromLatin1(".alexandria"); // create if necessary TQDir libraryDir = TQDir::home(); if(!libraryDir.cd(alexDirName)) { if(!libraryDir.mkdir(alexDirName) || !libraryDir.cd(alexDirName)) { myLog() << "AlexandriaExporter::exec() - can't locate directory" << endl; return false; } } // the collection title is the name of the directory to create if(libraryDir.cd(coll->title())) { int ret = KMessageBox::warningContinueCancel(Kernel::self()->widget(), i18n("An Alexandria library called %1 already exists. " "Any existing books in that library could be overwritten.") .arg(coll->title())); if(ret == KMessageBox::Cancel) { return false; } } else if(!libraryDir.mkdir(coll->title()) || !libraryDir.cd(coll->title())) { return false; // could not create and cd to the dir } ProgressItem& item = ProgressManager::self()->newProgressItem(this, TQString(), false); item.setTotalSteps(entries().count()); ProgressItem::Done done(this); const uint stepSize = TQMAX(1, entries().count()/100); const bool showProgress = options() & ExportProgress; GUI::CursorSaver cs; bool success = true; uint j = 0; for(Data::EntryVec::ConstIterator entryIt = entries().begin(); entryIt != entries().end(); ++entryIt, ++j) { success &= writeFile(libraryDir, entryIt.data()); if(showProgress && j%stepSize == 0) { item.setProgress(j); kapp->processEvents(); } } return success; } // this isn't true YAML export, of course // everything is put between quotes except for the rating, just to be sure it's interpreted as a string bool AlexandriaExporter::writeFile(const TQDir& dir_, Data::ConstEntryPtr entry_) { // the filename is the isbn without dashes, followed by .yaml TQString isbn = entry_->field(TQString::fromLatin1("isbn")); if(isbn.isEmpty()) { return false; // can't write it since Alexandria uses isbn as name of file } isbn.remove('-'); // remove dashes TQFile file(dir_.absPath() + TQDir::separator() + isbn + TQString::fromLatin1(".yaml")); if(!file.open(IO_WriteOnly)) { return false; } // do we format? bool format = options() & Export::ExportFormatted; TQTextStream ts(&file); // alexandria uses utf-8 all the time ts.setEncoding(TQTextStream::UnicodeUTF8); ts << "--- !ruby/object:Alexandria::Book\n"; ts << "authors:\n"; TQStringList authors = entry_->fields(TQString::fromLatin1("author"), format); for(TQStringList::Iterator it = authors.begin(); it != authors.end(); ++it) { ts << " - " << escapeText(*it) << "\n"; } // Alexandria crashes when no authors, and uses n/a when none if(authors.count() == 0) { ts << " - n/a\n"; } TQString tmp = entry_->field(TQString::fromLatin1("title"), format); ts << "title: \"" << escapeText(tmp) << "\"\n"; // Alexandria refers to the binding as the edition tmp = entry_->field(TQString::fromLatin1("binding"), format); ts << "edition: \"" << escapeText(tmp) << "\"\n"; // sometimes Alexandria interprets the isbn as a number instead of a string // I have no idea how to debug ruby, so err on safe side and add quotes ts << "isbn: \"" << isbn << "\"\n"; tmp = entry_->field(TQString::fromLatin1("comments"), format); ts << "notes: \"" << escapeText(tmp) << "\"\n"; tmp = entry_->field(TQString::fromLatin1("publisher"), format); // publisher uses n/a when empty ts << "publisher: \"" << (tmp.isEmpty() ? TQString::fromLatin1("n/a") : escapeText(tmp)) << "\"\n"; tmp = entry_->field(TQString::fromLatin1("pub_year"), format); if(!tmp.isEmpty()) { ts << "publishing_year: \"" << escapeText(tmp) << "\"\n"; } tmp = entry_->field(TQString::fromLatin1("rating")); bool ok; int rating = Tellico::toUInt(tmp, &ok); if(ok) { ts << "rating: " << rating << "\n"; } file.close(); TQString cover = entry_->field(TQString::fromLatin1("cover")); if(cover.isEmpty() || !(options() & Export::ExportImages)) { return true; // all done } TQImage img1(ImageFactory::imageById(cover)); TQImage img2; TQString filename = dir_.absPath() + TQDir::separator() + isbn; if(img1.height() > ALEXANDRIA_MAX_SIZE_SMALL) { if(img1.height() > ALEXANDRIA_MAX_SIZE_MEDIUM) { // limit maximum size img1 = img1.scale(ALEXANDRIA_MAX_SIZE_MEDIUM, ALEXANDRIA_MAX_SIZE_MEDIUM, TQ_ScaleMin); } img2 = img1.scale(ALEXANDRIA_MAX_SIZE_SMALL, ALEXANDRIA_MAX_SIZE_SMALL, TQ_ScaleMin); } else { img2 = img1.smoothScale(ALEXANDRIA_MAX_SIZE_MEDIUM, ALEXANDRIA_MAX_SIZE_MEDIUM, TQ_ScaleMin); // scale up } if(!img1.save(filename + TQString::fromLatin1("_medium.jpg"), "JPEG") || !img2.save(filename + TQString::fromLatin1("_small.jpg"), "JPEG")) { return false; } return true; } #include "alexandriaexporter.moc"