Changeset View
Changeset View
Standalone View
Standalone View
src/qtquick/ArchiveBookModel.cpp
Show All 23 Lines | |||||
24 | 24 | | |||
25 | #include <AcbfAuthor.h> | 25 | #include <AcbfAuthor.h> | ||
26 | #include <AcbfBody.h> | 26 | #include <AcbfBody.h> | ||
27 | #include <AcbfBookinfo.h> | 27 | #include <AcbfBookinfo.h> | ||
28 | #include <AcbfDocument.h> | 28 | #include <AcbfDocument.h> | ||
29 | #include <AcbfMetadata.h> | 29 | #include <AcbfMetadata.h> | ||
30 | #include <AcbfPage.h> | 30 | #include <AcbfPage.h> | ||
31 | #include <AcbfPublishinfo.h> | 31 | #include <AcbfPublishinfo.h> | ||
32 | #include <AcbfDocumentinfo.h> | ||||
32 | 33 | | |||
33 | #include <QCoreApplication> | 34 | #include <QCoreApplication> | ||
34 | #include <QDebug> | 35 | #include <QDebug> | ||
35 | #include <QDir> | 36 | #include <QDir> | ||
36 | #include <QMimeDatabase> | 37 | #include <QMimeDatabase> | ||
37 | #include <QQmlEngine> | 38 | #include <QQmlEngine> | ||
38 | #include <QTemporaryFile> | 39 | #include <QTemporaryFile> | ||
40 | #include <QXmlStreamReader> | ||||
39 | 41 | | |||
40 | #include <KFileMetaData/UserMetaData> | 42 | #include <KFileMetaData/UserMetaData> | ||
41 | #include <karchive.h> | 43 | #include <karchive.h> | ||
42 | #include <kzip.h> | 44 | #include <kzip.h> | ||
43 | #include "KRar.h" // "" because it's a custom thing for now | 45 | #include "KRar.h" // "" because it's a custom thing for now | ||
44 | 46 | | |||
45 | class ArchiveBookModel::Private | 47 | class ArchiveBookModel::Private | ||
46 | { | 48 | { | ||
▲ Show 20 Lines • Show All 146 Lines • ▼ Show 20 Line(s) | 191 | { | |||
193 | if(d->engine) { | 195 | if(d->engine) { | ||
194 | d->engine->addImageProvider(prefix, d->imageProvider); | 196 | d->engine->addImageProvider(prefix, d->imageProvider); | ||
195 | } | 197 | } | ||
196 | 198 | | |||
197 | QStringList entries = recursiveEntries(d->archive->directory()); | 199 | QStringList entries = recursiveEntries(d->archive->directory()); | ||
198 | 200 | | |||
199 | // First check and see if we've got an ACBF document in there... | 201 | // First check and see if we've got an ACBF document in there... | ||
200 | QString acbfEntry; | 202 | QString acbfEntry; | ||
203 | QString comicInfoEntry; | ||||
204 | QStringList xmlFiles; | ||||
201 | QLatin1String acbfSuffix(".acbf"); | 205 | QLatin1String acbfSuffix(".acbf"); | ||
206 | QLatin1String ComicInfoXML("comicinfo.xml"); | ||||
207 | QLatin1String xmlSuffix(".xml"); | ||||
208 | QStringList images; | ||||
202 | Q_FOREACH(const QString& entry, entries) | 209 | Q_FOREACH(const QString& entry, entries) | ||
203 | { | 210 | { | ||
204 | if(entry.toLower().endsWith(acbfSuffix)) | 211 | if(entry.toLower().endsWith(acbfSuffix)) | ||
205 | { | 212 | { | ||
206 | acbfEntry = entry; | 213 | acbfEntry = entry; | ||
207 | break; | 214 | break; | ||
208 | } | 215 | } | ||
216 | if(entry.toLower().endsWith(xmlSuffix)) { | ||||
217 | if(entry.toLower().endsWith(ComicInfoXML)) { | ||||
218 | comicInfoEntry = entry; | ||||
219 | } else { | ||||
220 | xmlFiles.append(entry); | ||||
209 | } | 221 | } | ||
222 | } | ||||
223 | if (entry.toLower().endsWith(".jpg") || entry.toLower().endsWith(".jpeg") | ||||
224 | || entry.toLower().endsWith(".gif") || entry.toLower().endsWith(".png")) { | ||||
225 | images.append(entry); | ||||
226 | } | ||||
227 | } | ||||
228 | images.sort(); | ||||
210 | if(!acbfEntry.isEmpty()) | 229 | if(!acbfEntry.isEmpty()) | ||
211 | { | 230 | { | ||
212 | AdvancedComicBookFormat::Document* acbfDocument = new AdvancedComicBookFormat::Document(this); | 231 | AdvancedComicBookFormat::Document* acbfDocument = new AdvancedComicBookFormat::Document(this); | ||
213 | const KArchiveFile* archFile = d->archive->directory()->file(acbfEntry); | 232 | const KArchiveFile* archFile = d->archive->directory()->file(acbfEntry); | ||
214 | if(acbfDocument->fromXml(QString(archFile->data()))) | 233 | if(acbfDocument->fromXml(QString(archFile->data()))) | ||
215 | { | 234 | { | ||
216 | setAcbfData(acbfDocument); | 235 | setAcbfData(acbfDocument); | ||
217 | addPage(QString("image://%1/%2").arg(prefix).arg(acbfDocument->metaData()->bookInfo()->coverpage()->imageHref()), acbfDocument->metaData()->bookInfo()->coverpage()->title()); | 236 | addPage(QString("image://%1/%2").arg(prefix).arg(acbfDocument->metaData()->bookInfo()->coverpage()->imageHref()), acbfDocument->metaData()->bookInfo()->coverpage()->title()); | ||
218 | Q_FOREACH(AdvancedComicBookFormat::Page* page, acbfDocument->body()->pages()) | 237 | Q_FOREACH(AdvancedComicBookFormat::Page* page, acbfDocument->body()->pages()) | ||
219 | { | 238 | { | ||
220 | addPage(QString("image://%1/%2").arg(prefix).arg(page->imageHref()), page->title()); | 239 | addPage(QString("image://%1/%2").arg(prefix).arg(page->imageHref()), page->title()); | ||
221 | } | 240 | } | ||
222 | } | 241 | } | ||
223 | else | 242 | else | ||
224 | { | 243 | { | ||
225 | // just in case this is, for whatever reason, being reused... | 244 | // just in case this is, for whatever reason, being reused... | ||
226 | setAcbfData(nullptr); | 245 | setAcbfData(nullptr); | ||
227 | } | 246 | } | ||
228 | } | 247 | } | ||
248 | if (!comicInfoEntry.isEmpty() || !xmlFiles.isEmpty()) { | ||||
249 | AdvancedComicBookFormat::Document* acbfDocument = new AdvancedComicBookFormat::Document(this); | ||||
250 | const KArchiveFile* archFile = d->archive->directory()->file(comicInfoEntry); | ||||
251 | bool loadData = false; | ||||
252 | | ||||
253 | if (!comicInfoEntry.isEmpty()) { | ||||
254 | loadData = loadComicInfoXML(archFile->data(), acbfDocument, images, newFilename); | ||||
255 | } else { | ||||
256 | loadData = loadCoMet(xmlFiles, acbfDocument, images, newFilename); | ||||
257 | } | ||||
258 | | ||||
259 | if (loadData) { | ||||
260 | setAcbfData(acbfDocument); | ||||
261 | QString undesired = QString("%1").arg("/").append("Thumbs.db"); | ||||
262 | addPage(QString("image://%1/%2").arg(prefix).arg(acbfDocument->metaData()->bookInfo()->coverpage()->imageHref()), acbfDocument->metaData()->bookInfo()->coverpage()->title()); | ||||
263 | Q_FOREACH(AdvancedComicBookFormat::Page* page, acbfDocument->body()->pages()) | ||||
264 | { | ||||
265 | addPage(QString("image://%1/%2").arg(prefix).arg(page->imageHref()), page->title()); | ||||
266 | } | ||||
267 | } | ||||
268 | } | ||||
229 | if(!acbfData()) | 269 | if(!acbfData()) | ||
230 | { | 270 | { | ||
231 | // fall back to just handling the files directly if there's no ACBF document... | 271 | // fall back to just handling the files directly if there's no ACBF document... | ||
232 | entries.sort(); | 272 | entries.sort(); | ||
233 | QString undesired = QString("%1").arg("/").append("Thumbs.db"); | 273 | QString undesired = QString("%1").arg("/").append("Thumbs.db"); | ||
234 | Q_FOREACH(const QString& entry, entries) | 274 | Q_FOREACH(const QString& entry, entries) | ||
235 | { | 275 | { | ||
236 | const KArchiveEntry* archEntry = d->archive->directory()->entry(entry); | 276 | const KArchiveEntry* archEntry = d->archive->directory()->entry(entry); | ||
▲ Show 20 Lines • Show All 390 Lines • ▼ Show 20 Line(s) | |||||
627 | const KArchiveFile * ArchiveBookModel::archiveFile(const QString& filePath) | 667 | const KArchiveFile * ArchiveBookModel::archiveFile(const QString& filePath) | ||
628 | { | 668 | { | ||
629 | if(d->archive) | 669 | if(d->archive) | ||
630 | { | 670 | { | ||
631 | return d->archive->directory()->file(filePath); | 671 | return d->archive->directory()->file(filePath); | ||
632 | } | 672 | } | ||
633 | return nullptr; | 673 | return nullptr; | ||
634 | } | 674 | } | ||
675 | | ||||
676 | bool ArchiveBookModel::loadComicInfoXML(QString xmlDocument, QObject *acbfData, QStringList entries, QString filename) | ||||
677 | { | ||||
678 | KFileMetaData::UserMetaData filedata(filename); | ||||
679 | AdvancedComicBookFormat::Document* acbfDocument = qobject_cast<AdvancedComicBookFormat::Document*>(acbfData); | ||||
680 | QXmlStreamReader xmlReader(xmlDocument); | ||||
681 | if(xmlReader.readNextStartElement()) | ||||
682 | { | ||||
683 | if(xmlReader.name() == QStringLiteral("ComicInfo")) | ||||
684 | { | ||||
685 | // We'll need to collect several items to generate a series. Thankfully, comicinfo only has two types of series. | ||||
686 | QString series; | ||||
687 | int number = -1; | ||||
688 | int volume = 0; | ||||
689 | | ||||
690 | QString seriesAlt; | ||||
691 | int numberAlt = -1; | ||||
692 | int volumeAlt = 0; | ||||
693 | | ||||
694 | // Also publishing date. | ||||
695 | int year = 0; | ||||
696 | int month = 0; | ||||
697 | int day = 0; | ||||
698 | | ||||
699 | QStringList publisher; | ||||
700 | QStringList keywords; | ||||
701 | QStringList empty; | ||||
702 | | ||||
703 | while(xmlReader.readNextStartElement()) | ||||
704 | { | ||||
705 | if(xmlReader.name() == QStringLiteral("Title")) | ||||
706 | { | ||||
707 | acbfDocument->metaData()->bookInfo()->setTitle(xmlReader.readElementText(),""); | ||||
708 | } | ||||
709 | | ||||
710 | //Summary/annotation. | ||||
711 | else if(xmlReader.name() == QStringLiteral("Summary")) | ||||
712 | { | ||||
713 | acbfDocument->metaData()->bookInfo()->setAnnotation(xmlReader.readElementText().split("\n\n"), ""); | ||||
714 | } | ||||
715 | | ||||
716 | /* | ||||
717 | * This ought to go into the kfile metadata. | ||||
718 | */ | ||||
719 | else if(xmlReader.name() == QStringLiteral("Notes")) | ||||
720 | { | ||||
721 | filedata.setUserComment(xmlReader.readElementText()); | ||||
722 | } | ||||
723 | else if(xmlReader.name() == QStringLiteral("Tags")) | ||||
724 | { | ||||
725 | filedata.setTags(xmlReader.readElementText().split(",")); | ||||
726 | } | ||||
727 | else if(xmlReader.name() == QStringLiteral("PageCount")) | ||||
728 | { | ||||
729 | filedata.setAttribute("Peruse.totalPages", xmlReader.readElementText()); | ||||
730 | } | ||||
731 | else if(xmlReader.name() == QStringLiteral("ScanInformation")) | ||||
732 | { | ||||
733 | QString userComment = filedata.userComment(); | ||||
734 | userComment.append("\n"+xmlReader.readElementText()); | ||||
735 | filedata.setUserComment(userComment); | ||||
736 | } | ||||
737 | | ||||
738 | //Series | ||||
739 | | ||||
740 | else if(xmlReader.name() == QStringLiteral("Series")) | ||||
741 | { | ||||
742 | series = xmlReader.readElementText(); | ||||
743 | } | ||||
744 | else if(xmlReader.name() == QStringLiteral("Number")) | ||||
745 | { | ||||
746 | number = xmlReader.readElementText().toInt(); | ||||
747 | } | ||||
748 | else if(xmlReader.name() == QStringLiteral("Volume")) | ||||
749 | { | ||||
750 | volume = xmlReader.readElementText().toInt(); | ||||
751 | } | ||||
752 | | ||||
753 | // Series alt | ||||
754 | | ||||
755 | else if(xmlReader.name() == QStringLiteral("AlternateSeries")) | ||||
756 | { | ||||
757 | seriesAlt = xmlReader.readElementText(); | ||||
758 | } | ||||
759 | else if(xmlReader.name() == QStringLiteral("AlternateNumber")) | ||||
760 | { | ||||
761 | numberAlt = xmlReader.readElementText().toInt(); | ||||
762 | } | ||||
763 | else if(xmlReader.name() == QStringLiteral("AlternateVolume")) | ||||
764 | { | ||||
765 | volumeAlt = xmlReader.readElementText().toInt(); | ||||
766 | } | ||||
767 | | ||||
768 | // Publishing date. | ||||
769 | | ||||
770 | else if(xmlReader.name() == QStringLiteral("Year")) | ||||
771 | { | ||||
772 | year = xmlReader.readElementText().toInt(); | ||||
773 | } | ||||
774 | else if(xmlReader.name() == QStringLiteral("Month")) | ||||
775 | { | ||||
776 | month = xmlReader.readElementText().toInt(); | ||||
777 | } | ||||
778 | else if(xmlReader.name() == QStringLiteral("Day")) | ||||
779 | { | ||||
780 | day = xmlReader.readElementText().toInt(); | ||||
781 | } | ||||
782 | | ||||
783 | //Publisher | ||||
784 | | ||||
785 | else if(xmlReader.name() == QStringLiteral("Publisher")) | ||||
786 | { | ||||
787 | publisher.append(xmlReader.readElementText()); | ||||
788 | } | ||||
789 | else if(xmlReader.name() == QStringLiteral("Imprint")) | ||||
790 | { | ||||
791 | publisher.append(xmlReader.readElementText()); | ||||
792 | } | ||||
793 | | ||||
794 | //Genre | ||||
795 | else if(xmlReader.name() == QStringLiteral("Genre")) | ||||
796 | { | ||||
797 | QString key = xmlReader.readElementText(); | ||||
798 | QString genreKey = key.toLower().replace(" ", "_"); | ||||
799 | if (acbfDocument->metaData()->bookInfo()->availableGenres().contains(genreKey)) { | ||||
800 | acbfDocument->metaData()->bookInfo()->setGenre(genreKey); | ||||
801 | } else { | ||||
802 | //There must always be a genre in a proper acbf file... | ||||
803 | acbfDocument->metaData()->bookInfo()->setGenre("other"); | ||||
804 | keywords.append(key); | ||||
805 | } | ||||
806 | } | ||||
807 | | ||||
808 | //Language | ||||
809 | | ||||
810 | else if(xmlReader.name() == QStringLiteral("LanguageISO")) | ||||
811 | { | ||||
812 | acbfDocument->metaData()->bookInfo()->addLanguage(xmlReader.readElementText()); | ||||
813 | } | ||||
814 | | ||||
815 | //Sources/Weblink | ||||
816 | else if(xmlReader.name() == QStringLiteral("Web")) | ||||
817 | { | ||||
818 | acbfDocument->metaData()->documentInfo()->setSource(QStringList(xmlReader.readElementText())); | ||||
819 | } | ||||
820 | | ||||
821 | //One short, trade, etc. | ||||
822 | else if(xmlReader.name() == QStringLiteral("Format")) | ||||
823 | { | ||||
824 | keywords.append(xmlReader.readElementText()); | ||||
825 | } | ||||
826 | | ||||
827 | //Is this a manga? | ||||
828 | else if(xmlReader.name() == QStringLiteral("Manga")) | ||||
829 | { | ||||
830 | if (xmlReader.readElementText() == "Yes") { | ||||
831 | acbfDocument->metaData()->bookInfo()->setGenre("manga"); | ||||
832 | acbfDocument->metaData()->bookInfo()->setRightToLeft(true); | ||||
833 | } | ||||
834 | } | ||||
835 | //Content rating... | ||||
836 | else if(xmlReader.name() == QStringLiteral("AgeRating")) | ||||
837 | { | ||||
838 | acbfDocument->metaData()->bookInfo()->addContentRating(xmlReader.readElementText()); | ||||
839 | } | ||||
840 | | ||||
841 | //Authors... | ||||
842 | else if(xmlReader.name() == QStringLiteral("Writer")) | ||||
843 | { | ||||
844 | QStringList people = xmlReader.readElementText().split(",", QString::SkipEmptyParts); | ||||
845 | for (int i=0; i < people.size(); i++) { | ||||
846 | acbfDocument->metaData()->bookInfo()->addAuthor("Writer", "", "", "", "", people.at(i).trimmed(), empty, empty); | ||||
847 | } | ||||
848 | } | ||||
849 | else if(xmlReader.name() == QStringLiteral("Plotter")) | ||||
850 | { | ||||
851 | QStringList people = xmlReader.readElementText().split(",", QString::SkipEmptyParts); | ||||
852 | for (int i=0; i < people.size(); i++) { | ||||
853 | acbfDocument->metaData()->bookInfo()->addAuthor("Writer", "", "", "", "", people.at(i).trimmed(), empty, empty); | ||||
854 | } | ||||
855 | } | ||||
856 | else if(xmlReader.name() == QStringLiteral("Scripter")) | ||||
857 | { | ||||
858 | QStringList people = xmlReader.readElementText().split(",", QString::SkipEmptyParts); | ||||
859 | for (int i=0; i < people.size(); i++) { | ||||
860 | acbfDocument->metaData()->bookInfo()->addAuthor("Writer", "", "", "", "", people.at(i).trimmed(), empty, empty); | ||||
861 | } | ||||
862 | } | ||||
863 | else if(xmlReader.name() == QStringLiteral("Penciller")) | ||||
864 | { | ||||
865 | QStringList people = xmlReader.readElementText().split(",", QString::SkipEmptyParts); | ||||
866 | for (int i=0; i < people.size(); i++) { | ||||
867 | acbfDocument->metaData()->bookInfo()->addAuthor("Penciller", "", "", "", "", people.at(i).trimmed(), empty, empty); | ||||
868 | } | ||||
869 | } | ||||
870 | else if(xmlReader.name() == QStringLiteral("Inker")) | ||||
871 | { | ||||
872 | QStringList people = xmlReader.readElementText().split(",", QString::SkipEmptyParts); | ||||
873 | for (int i=0; i < people.size(); i++) { | ||||
874 | acbfDocument->metaData()->bookInfo()->addAuthor("Inker", "", "", "", "", people.at(i).trimmed(), empty, empty); | ||||
875 | } | ||||
876 | } | ||||
877 | else if(xmlReader.name() == QStringLiteral("Colorist")) | ||||
878 | { | ||||
879 | QStringList people = xmlReader.readElementText().split(",", QString::SkipEmptyParts); | ||||
880 | for (int i=0; i < people.size(); i++) { | ||||
881 | acbfDocument->metaData()->bookInfo()->addAuthor("Colorist", "", "", "", "", people.at(i).trimmed(), empty, empty); | ||||
882 | } | ||||
883 | } | ||||
884 | else if(xmlReader.name() == QStringLiteral("CoverArtist")) | ||||
885 | { | ||||
886 | QStringList people = xmlReader.readElementText().split(",", QString::SkipEmptyParts); | ||||
887 | for (int i=0; i < people.size(); i++) { | ||||
888 | acbfDocument->metaData()->bookInfo()->addAuthor("CoverArtist", "", "", "", "", people.at(i).trimmed(), empty, empty); | ||||
889 | } | ||||
890 | } | ||||
891 | else if(xmlReader.name() == QStringLiteral("Letterer")) | ||||
892 | { | ||||
893 | QStringList people = xmlReader.readElementText().split(",", QString::SkipEmptyParts); | ||||
894 | for (int i=0; i < people.size(); i++) { | ||||
895 | acbfDocument->metaData()->bookInfo()->addAuthor("Letterer", "", "", "", "", people.at(i).trimmed(), empty, empty); | ||||
896 | } | ||||
897 | } | ||||
898 | else if(xmlReader.name() == QStringLiteral("Editor")) | ||||
899 | { | ||||
900 | QStringList people = xmlReader.readElementText().split(",", QString::SkipEmptyParts); | ||||
901 | for (int i=0; i < people.size(); i++) { | ||||
902 | acbfDocument->metaData()->bookInfo()->addAuthor("Editor", "", "", "", "", people.at(i).trimmed(), empty, empty); | ||||
903 | } | ||||
904 | } | ||||
905 | else if(xmlReader.name() == QStringLiteral("Other")) | ||||
906 | { | ||||
907 | QStringList people = xmlReader.readElementText().split(",", QString::SkipEmptyParts); | ||||
908 | for (int i=0; i < people.size(); i++) { | ||||
909 | acbfDocument->metaData()->bookInfo()->addAuthor("Other", "", "", "", "", people.at(i).trimmed(), empty, empty); | ||||
910 | } | ||||
911 | } | ||||
912 | //Characters... | ||||
913 | else if(xmlReader.name() == QStringLiteral("Characters")) | ||||
914 | { | ||||
915 | QStringList people = xmlReader.readElementText().split(",", QString::SkipEmptyParts); | ||||
916 | for (int i=0; i < people.size(); i++) { | ||||
917 | acbfDocument->metaData()->bookInfo()->addCharacter(people.at(i).trimmed()); | ||||
918 | } | ||||
919 | } | ||||
920 | //Throw the rest into the keywords. | ||||
921 | else if(xmlReader.name() == QStringLiteral("Teams")) | ||||
922 | { | ||||
923 | QStringList teams = xmlReader.readElementText().split(",", QString::SkipEmptyParts); | ||||
924 | for (int i=0; i < teams.size(); i++) { | ||||
925 | keywords.append(teams.at(i).trimmed()); | ||||
926 | } | ||||
927 | } | ||||
928 | else if(xmlReader.name() == QStringLiteral("Locations")) | ||||
929 | { | ||||
930 | QStringList locations = xmlReader.readElementText().split(",", QString::SkipEmptyParts); | ||||
931 | for (int i=0; i < locations.size(); i++) { | ||||
932 | keywords.append(locations.at(i).trimmed()); | ||||
933 | } | ||||
934 | } | ||||
935 | else if(xmlReader.name() == QStringLiteral("StoryArc")) | ||||
936 | { | ||||
937 | QStringList arc = xmlReader.readElementText().split(",", QString::SkipEmptyParts); | ||||
938 | for (int i=0; i < arc.size(); i++) { | ||||
939 | keywords.append(arc.at(i).trimmed()); | ||||
940 | } | ||||
941 | } | ||||
942 | else if(xmlReader.name() == QStringLiteral("SeriesGroup")) | ||||
943 | { | ||||
944 | QStringList group = xmlReader.readElementText().split(",", QString::SkipEmptyParts); | ||||
945 | for (int i=0; i < group.size(); i++) { | ||||
946 | keywords.append(group.at(i).trimmed()); | ||||
947 | } | ||||
948 | } | ||||
949 | | ||||
950 | //Pages... | ||||
951 | else if(xmlReader.name() == QStringLiteral("Pages")) { | ||||
952 | while(xmlReader.readNextStartElement()) { | ||||
953 | if(xmlReader.name() == QStringLiteral("Page")) | ||||
954 | { | ||||
955 | int index = xmlReader.attributes().value(QStringLiteral("Image")).toInt(); | ||||
956 | QString type = xmlReader.attributes().value(QStringLiteral("Type")).toString(); | ||||
957 | QString bookmark = xmlReader.attributes().value(QStringLiteral("Bookmark")).toString(); | ||||
958 | AdvancedComicBookFormat::Page* page = new AdvancedComicBookFormat::Page(acbfDocument); | ||||
959 | page->setImageHref(entries.at(index)); | ||||
960 | if (type == QStringLiteral("FrontCover")) { | ||||
961 | acbfDocument->metaData()->bookInfo()->setCoverpage(page); | ||||
962 | } else { | ||||
963 | if (bookmark.isEmpty()) { | ||||
964 | page->setTitle(type.append(QString::number(index))); | ||||
965 | } else { | ||||
966 | page->setTitle(bookmark); | ||||
967 | } | ||||
968 | acbfDocument->body()->addPage(page, index-1); | ||||
969 | } | ||||
970 | xmlReader.readNext(); | ||||
971 | } | ||||
972 | } | ||||
973 | } | ||||
974 | | ||||
975 | else | ||||
976 | { | ||||
977 | qWarning() << Q_FUNC_INFO << "currently unsupported subsection:" << xmlReader.name(); | ||||
978 | xmlReader.skipCurrentElement(); | ||||
979 | } | ||||
980 | } | ||||
981 | | ||||
982 | if (!series.isEmpty() && number>-1) { | ||||
983 | acbfDocument->metaData()->bookInfo()->addSequence(number, series, volume); | ||||
984 | } | ||||
985 | if (!seriesAlt.isEmpty() && numberAlt>-1) { | ||||
986 | acbfDocument->metaData()->bookInfo()->addSequence(numberAlt, seriesAlt, volumeAlt); | ||||
987 | } | ||||
988 | | ||||
989 | if (year > 0 || month > 0 || day > 0) { | ||||
990 | //acbfDocument->metaData()->publishInfo()->setPublishDateFromInts(year, month, day); | ||||
991 | } | ||||
992 | | ||||
993 | if (publisher.size()>0) { | ||||
994 | acbfDocument->metaData()->publishInfo()->setPublisher(publisher.join(", ")); | ||||
995 | } | ||||
996 | | ||||
997 | if (keywords.size()>0) { | ||||
998 | acbfDocument->metaData()->bookInfo()->setKeywords(keywords, ""); | ||||
999 | } | ||||
1000 | | ||||
1001 | if (acbfDocument->metaData()->bookInfo()->languages().size()>0) { | ||||
1002 | QString lang = acbfDocument->metaData()->bookInfo()->languageEntryList().at(0); | ||||
1003 | acbfDocument->metaData()->bookInfo()->setTitle(acbfDocument->metaData()->bookInfo()->title(""), lang); | ||||
1004 | acbfDocument->metaData()->bookInfo()->setAnnotation(acbfDocument->metaData()->bookInfo()->annotation(""), lang); | ||||
1005 | acbfDocument->metaData()->bookInfo()->setKeywords(acbfDocument->metaData()->bookInfo()->keywords(""), lang); | ||||
1006 | } | ||||
1007 | } | ||||
1008 | } | ||||
1009 | | ||||
1010 | if (xmlReader.hasError()) { | ||||
1011 | qWarning() << Q_FUNC_INFO << "Failed to read Comic Info XML document at token" << xmlReader.name() << "(" << xmlReader.lineNumber() << ":" << xmlReader.columnNumber() << ") The reported error was:" << xmlReader.errorString(); | ||||
1012 | } | ||||
1013 | qDebug() << Q_FUNC_INFO << "Completed ACBF document creation from ComicInfo.xml for" << acbfDocument->metaData()->bookInfo()->title(); | ||||
1014 | acbfData = acbfDocument; | ||||
1015 | return !xmlReader.hasError(); | ||||
1016 | } | ||||
1017 | | ||||
1018 | bool ArchiveBookModel::loadCoMet(QStringList xmlDocuments, QObject *acbfData, QStringList entries, QString filename) | ||||
1019 | { | ||||
1020 | KFileMetaData::UserMetaData filedata(filename); | ||||
1021 | AdvancedComicBookFormat::Document* acbfDocument = qobject_cast<AdvancedComicBookFormat::Document*>(acbfData); | ||||
1022 | Q_FOREACH(const QString xmlDocument, xmlDocuments) { | ||||
1023 | const KArchiveFile* archFile = d->archive->directory()->file(xmlDocument); | ||||
1024 | QXmlStreamReader xmlReader(archFile->data()); | ||||
1025 | if(xmlReader.readNextStartElement()) | ||||
1026 | { | ||||
1027 | if(xmlReader.name() == QStringLiteral("comet")) | ||||
1028 | { | ||||
1029 | // We'll need to collect several items to generate a series. Thankfully, comicinfo only has two types of series. | ||||
1030 | QString series; | ||||
1031 | int number = -1; | ||||
1032 | int volume = 0; | ||||
1033 | | ||||
1034 | QStringList keywords; | ||||
1035 | QStringList empty; | ||||
1036 | | ||||
1037 | while(xmlReader.readNextStartElement()) | ||||
1038 | { | ||||
1039 | if(xmlReader.name() == QStringLiteral("title")) | ||||
1040 | { | ||||
1041 | acbfDocument->metaData()->bookInfo()->setTitle(xmlReader.readElementText(),""); | ||||
1042 | } | ||||
1043 | | ||||
1044 | //Summary/annotation. | ||||
1045 | else if(xmlReader.name() == QStringLiteral("description")) | ||||
1046 | { | ||||
1047 | acbfDocument->metaData()->bookInfo()->setAnnotation(xmlReader.readElementText().split("\n\n"), ""); | ||||
1048 | } | ||||
1049 | | ||||
1050 | /* | ||||
1051 | * This ought to go into the kfile metadata. | ||||
1052 | */ | ||||
1053 | //pages | ||||
1054 | else if(xmlReader.name() == QStringLiteral("pages")) | ||||
1055 | { | ||||
1056 | filedata.setAttribute("Peruse.totalPages", xmlReader.readElementText()); | ||||
1057 | } | ||||
1058 | //curentpage -- only read this when there's no such entry. | ||||
1059 | else if(xmlReader.name() == QStringLiteral("lastMark")) | ||||
1060 | { | ||||
1061 | if (!filedata.hasAttribute("Peruse.currentPage")) { | ||||
1062 | filedata.setAttribute("Peruse.currentPage", xmlReader.readElementText()); | ||||
1063 | } | ||||
1064 | } | ||||
1065 | | ||||
1066 | //Series | ||||
1067 | | ||||
1068 | else if(xmlReader.name() == QStringLiteral("series")) | ||||
1069 | { | ||||
1070 | series = xmlReader.readElementText(); | ||||
1071 | } | ||||
1072 | else if(xmlReader.name() == QStringLiteral("issue")) | ||||
1073 | { | ||||
1074 | number = xmlReader.readElementText().toInt(); | ||||
1075 | } | ||||
1076 | else if(xmlReader.name() == QStringLiteral("volume")) | ||||
1077 | { | ||||
1078 | volume = xmlReader.readElementText().toInt(); | ||||
1079 | } | ||||
1080 | | ||||
1081 | // Publishing date. | ||||
1082 | | ||||
1083 | else if(xmlReader.name() == QStringLiteral("date")) | ||||
1084 | { | ||||
1085 | acbfDocument->metaData()->publishInfo()->setPublishDate(QDate::fromString(xmlReader.readElementText(), Qt::ISODate)); | ||||
1086 | } | ||||
1087 | | ||||
1088 | //Publisher | ||||
1089 | | ||||
1090 | else if(xmlReader.name() == QStringLiteral("publisher")) | ||||
1091 | { | ||||
1092 | acbfDocument->metaData()->publishInfo()->setPublisher(xmlReader.readElementText()); | ||||
1093 | } | ||||
1094 | else if(xmlReader.name() == QStringLiteral("rights")) | ||||
1095 | { | ||||
1096 | acbfDocument->metaData()->publishInfo()->setLicense(xmlReader.readElementText()); | ||||
1097 | } | ||||
1098 | else if(xmlReader.name() == QStringLiteral("identifier")) | ||||
1099 | { | ||||
1100 | acbfDocument->metaData()->publishInfo()->setIsbn(xmlReader.readElementText()); | ||||
1101 | } | ||||
1102 | | ||||
1103 | //Genre | ||||
1104 | else if(xmlReader.name() == QStringLiteral("genre")) | ||||
1105 | { | ||||
1106 | QString key = xmlReader.readElementText(); | ||||
1107 | QString genreKey = key.toLower().replace(" ", "_"); | ||||
1108 | if (acbfDocument->metaData()->bookInfo()->availableGenres().contains(genreKey)) { | ||||
1109 | acbfDocument->metaData()->bookInfo()->setGenre(genreKey); | ||||
1110 | } else { | ||||
1111 | keywords.append(key); | ||||
1112 | } | ||||
1113 | } | ||||
1114 | | ||||
1115 | //Language | ||||
1116 | | ||||
1117 | else if(xmlReader.name() == QStringLiteral("language")) | ||||
1118 | { | ||||
1119 | acbfDocument->metaData()->bookInfo()->addLanguage(xmlReader.readElementText()); | ||||
1120 | } | ||||
1121 | | ||||
1122 | //Sources/Weblink | ||||
1123 | else if(xmlReader.name() == QStringLiteral("isVersionOf")) | ||||
1124 | { | ||||
1125 | acbfDocument->metaData()->documentInfo()->setSource(QStringList(xmlReader.readElementText())); | ||||
1126 | } | ||||
1127 | | ||||
1128 | //One short, trade, etc. | ||||
1129 | else if(xmlReader.name() == QStringLiteral("format")) | ||||
1130 | { | ||||
1131 | keywords.append(xmlReader.readElementText()); | ||||
1132 | } | ||||
1133 | | ||||
1134 | //Is this a manga? | ||||
1135 | else if(xmlReader.name() == QStringLiteral("readingDirection")) | ||||
1136 | { | ||||
1137 | if (xmlReader.readElementText() == "rtl") { | ||||
1138 | acbfDocument->metaData()->bookInfo()->setRightToLeft(true); | ||||
1139 | } | ||||
1140 | } | ||||
1141 | //Content rating... | ||||
1142 | else if(xmlReader.name() == QStringLiteral("rating")) | ||||
1143 | { | ||||
1144 | acbfDocument->metaData()->bookInfo()->addContentRating(xmlReader.readElementText()); | ||||
1145 | } | ||||
1146 | | ||||
1147 | //Authors... | ||||
1148 | else if(xmlReader.name() == QStringLiteral("writer")) | ||||
1149 | { | ||||
1150 | QString person = xmlReader.readElementText(); | ||||
1151 | acbfDocument->metaData()->bookInfo()->addAuthor("Writer", "", "", "", "", person, empty, empty); | ||||
1152 | } | ||||
1153 | else if(xmlReader.name() == QStringLiteral("creator")) | ||||
1154 | { | ||||
1155 | QString person = xmlReader.readElementText(); | ||||
1156 | acbfDocument->metaData()->bookInfo()->addAuthor("Writer", "", "", "", "", person, empty, empty); | ||||
1157 | } | ||||
1158 | else if(xmlReader.name() == QStringLiteral("penciller")) | ||||
1159 | { | ||||
1160 | QString person = xmlReader.readElementText(); | ||||
1161 | acbfDocument->metaData()->bookInfo()->addAuthor("Penciller", "", "", "", "", person, empty, empty); | ||||
1162 | } | ||||
1163 | else if(xmlReader.name() == QStringLiteral("editor")) | ||||
1164 | { | ||||
1165 | QString person = xmlReader.readElementText(); | ||||
1166 | acbfDocument->metaData()->bookInfo()->addAuthor("Editor", "", "", "", "", person, empty, empty); | ||||
1167 | } | ||||
1168 | else if(xmlReader.name() == QStringLiteral("coverDesigner")) | ||||
1169 | { | ||||
1170 | QString person = xmlReader.readElementText(); | ||||
1171 | acbfDocument->metaData()->bookInfo()->addAuthor("CoverArtist", "", "", "", "", person, empty, empty); | ||||
1172 | } | ||||
1173 | else if(xmlReader.name() == QStringLiteral("letterer")) | ||||
1174 | { | ||||
1175 | QString person = xmlReader.readElementText(); | ||||
1176 | acbfDocument->metaData()->bookInfo()->addAuthor("Letterer", "", "", "", "", person, empty, empty); | ||||
1177 | } | ||||
1178 | else if(xmlReader.name() == QStringLiteral("inker")) | ||||
1179 | { | ||||
1180 | QString person = xmlReader.readElementText(); | ||||
1181 | acbfDocument->metaData()->bookInfo()->addAuthor("Inker", "", "", "", "", person, empty, empty); | ||||
1182 | } | ||||
1183 | else if(xmlReader.name() == QStringLiteral("colorist")) | ||||
1184 | { | ||||
1185 | QString person = xmlReader.readElementText(); | ||||
1186 | acbfDocument->metaData()->bookInfo()->addAuthor("Colorist", "", "", "", "", person, empty, empty); | ||||
1187 | } | ||||
1188 | | ||||
1189 | //Characters | ||||
1190 | else if(xmlReader.name() == QStringLiteral("character")) | ||||
1191 | { | ||||
1192 | QString person = xmlReader.readElementText(); | ||||
1193 | acbfDocument->metaData()->bookInfo()->addCharacter(person); | ||||
1194 | } | ||||
1195 | | ||||
1196 | | ||||
1197 | //Get the cover image, set it, remove it from entries, then remove all other entries. | ||||
1198 | else if(xmlReader.name() == QStringLiteral("coverImage")) | ||||
1199 | { | ||||
1200 | QString url = xmlReader.readElementText(); | ||||
1201 | AdvancedComicBookFormat::Page* cover = new AdvancedComicBookFormat::Page(acbfDocument); | ||||
1202 | cover->setImageHref(url); | ||||
1203 | acbfDocument->metaData()->bookInfo()->setCoverpage(cover); | ||||
1204 | entries.removeAll(url); | ||||
1205 | Q_FOREACH(QString entry, entries) { | ||||
1206 | AdvancedComicBookFormat::Page* page = new AdvancedComicBookFormat::Page(acbfDocument); | ||||
1207 | page->setImageHref(entry); | ||||
1208 | acbfDocument->body()->addPage(page); | ||||
1209 | } | ||||
1210 | xmlReader.readNext(); | ||||
1211 | } | ||||
1212 | | ||||
1213 | else | ||||
1214 | { | ||||
1215 | qWarning() << Q_FUNC_INFO << "currently unsupported subsection:" << xmlReader.name(); | ||||
1216 | xmlReader.skipCurrentElement(); | ||||
1217 | } | ||||
1218 | } | ||||
1219 | | ||||
1220 | if (!series.isEmpty() && number>-1) { | ||||
1221 | acbfDocument->metaData()->bookInfo()->addSequence(number, series, volume); | ||||
1222 | } | ||||
1223 | | ||||
1224 | if (acbfDocument->metaData()->bookInfo()->genres().size()==0) { | ||||
1225 | //There must always be a genre in a proper acbf file... | ||||
1226 | acbfDocument->metaData()->bookInfo()->setGenre("other"); | ||||
1227 | } | ||||
1228 | | ||||
1229 | if (keywords.size()>0) { | ||||
1230 | acbfDocument->metaData()->bookInfo()->setKeywords(keywords, ""); | ||||
1231 | } | ||||
1232 | | ||||
1233 | if (acbfDocument->metaData()->bookInfo()->languages().size()>0) { | ||||
1234 | QString lang = acbfDocument->metaData()->bookInfo()->languageEntryList().at(0); | ||||
1235 | acbfDocument->metaData()->bookInfo()->setTitle(acbfDocument->metaData()->bookInfo()->title(""), lang); | ||||
1236 | acbfDocument->metaData()->bookInfo()->setAnnotation(acbfDocument->metaData()->bookInfo()->annotation(""), lang); | ||||
1237 | acbfDocument->metaData()->bookInfo()->setKeywords(acbfDocument->metaData()->bookInfo()->keywords(""), lang); | ||||
1238 | } | ||||
1239 | } | ||||
1240 | if (xmlReader.hasError()) { | ||||
1241 | qWarning() << Q_FUNC_INFO << "Failed to read CoMet document at token" << xmlReader.name() | ||||
1242 | << "(" << xmlReader.lineNumber() << ":" | ||||
1243 | << xmlReader.columnNumber() << ") The reported error was:" << xmlReader.errorString(); | ||||
1244 | } | ||||
1245 | qDebug() << Q_FUNC_INFO << "Completed ACBF document creation from CoMet for" << acbfDocument->metaData()->bookInfo()->title(); | ||||
1246 | acbfData = acbfDocument; | ||||
1247 | return !xmlReader.hasError(); | ||||
1248 | } else { | ||||
1249 | xmlReader.skipCurrentElement(); | ||||
1250 | } | ||||
1251 | } | ||||
1252 | return false; | ||||
1253 | } |