summaryrefslogtreecommitdiffstats
path: root/fbreader/src/migration
diff options
context:
space:
mode:
authorMichele Calgaro <[email protected]>2024-05-11 21:28:48 +0900
committerMichele Calgaro <[email protected]>2024-05-11 21:28:48 +0900
commit2462d03f322261bd616721c2b2065c4004b36c9c (patch)
tree239947a0737bb8386703a1497f12c09aebd3080a /fbreader/src/migration
downloadtde-ebook-reader-2462d03f322261bd616721c2b2065c4004b36c9c.tar.gz
tde-ebook-reader-2462d03f322261bd616721c2b2065c4004b36c9c.zip
Initial import (as is) from Debian Snapshot's 'fbreader' source code (https://snapshot.debian.org/package/fbreader/0.99.4%2Bdfsg-6).
The Debian code is provided under GPL2 license. Signed-off-by: Michele Calgaro <[email protected]>
Diffstat (limited to 'fbreader/src/migration')
-rw-r--r--fbreader/src/migration/BookInfo.cpp66
-rw-r--r--fbreader/src/migration/BookInfo.h49
-rw-r--r--fbreader/src/migration/FB2MigrationReader.cpp106
-rw-r--r--fbreader/src/migration/FB2MigrationReader.h57
-rw-r--r--fbreader/src/migration/HtmlDCTagsReader.cpp61
-rw-r--r--fbreader/src/migration/HtmlDCTagsReader.h47
-rw-r--r--fbreader/src/migration/Migration.cpp77
-rw-r--r--fbreader/src/migration/Migration.h119
-rw-r--r--fbreader/src/migration/Migration_0_10_4.cpp42
-rw-r--r--fbreader/src/migration/Migration_0_11_0.cpp544
-rw-r--r--fbreader/src/migration/Migration_0_8_11.cpp122
-rw-r--r--fbreader/src/migration/Migration_0_8_13.cpp43
-rw-r--r--fbreader/src/migration/Migration_0_8_16.cpp83
-rw-r--r--fbreader/src/migration/Migration_0_99_0.cpp91
-rw-r--r--fbreader/src/migration/Migration_0_99_1.cpp34
-rw-r--r--fbreader/src/migration/OEBMigrationReader.cpp81
-rw-r--r--fbreader/src/migration/OEBMigrationReader.h54
-rw-r--r--fbreader/src/migration/migrate.cpp45
-rw-r--r--fbreader/src/migration/migrate.h37
19 files changed, 1758 insertions, 0 deletions
diff --git a/fbreader/src/migration/BookInfo.cpp b/fbreader/src/migration/BookInfo.cpp
new file mode 100644
index 0000000..5a13647
--- /dev/null
+++ b/fbreader/src/migration/BookInfo.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2004-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include "BookInfo.h"
+
+#include "../options/FBCategoryKey.h"
+
+static const std::string EMPTY = "";
+
+BookInfo::BookInfo(const std::string &fileName) :
+ AuthorDisplayNameOption(FBCategoryKey::BOOKS, fileName, "AuthorDisplayName", EMPTY),
+ AuthorSortKeyOption(FBCategoryKey::BOOKS, fileName, "AuthorSortKey", EMPTY),
+ TitleOption(FBCategoryKey::BOOKS, fileName, "Title", EMPTY),
+ SeriesTitleOption(FBCategoryKey::BOOKS, fileName, "Sequence", EMPTY),
+ IndexInSeriesOption(FBCategoryKey::BOOKS, fileName, "Series Number in Sequence", EMPTY),
+ LanguageOption(FBCategoryKey::BOOKS, fileName, "Language", EMPTY),
+ EncodingOption(FBCategoryKey::BOOKS, fileName, "Encoding", EMPTY),
+ TagsOption(FBCategoryKey::BOOKS, fileName, "TagList", EMPTY) {
+}
+
+void BookInfo::reset() {
+ AuthorDisplayNameOption.setValue(EMPTY);
+ AuthorSortKeyOption.setValue(EMPTY);
+ TitleOption.setValue(EMPTY);
+ SeriesTitleOption.setValue(EMPTY);
+ IndexInSeriesOption.setValue(EMPTY);
+ LanguageOption.setValue(EMPTY);
+ EncodingOption.setValue(EMPTY);
+ TagsOption.setValue(EMPTY);
+}
+
+bool BookInfo::isFull() const {
+ return
+ !AuthorDisplayNameOption.value().empty() &&
+ !AuthorSortKeyOption.value().empty() &&
+ !TitleOption.value().empty() &&
+ !EncodingOption.value().empty();
+}
+
+const BookInfo &BookInfo::operator = (const BookInfo &bi) {
+ AuthorDisplayNameOption.setValue(bi.AuthorDisplayNameOption.value());
+ AuthorSortKeyOption.setValue(bi.AuthorSortKeyOption.value());
+ TitleOption.setValue(bi.TitleOption.value());
+ SeriesTitleOption.setValue(bi.SeriesTitleOption.value());
+ IndexInSeriesOption.setValue(bi.IndexInSeriesOption.value());
+ LanguageOption.setValue(bi.LanguageOption.value());
+ EncodingOption.setValue(bi.EncodingOption.value());
+ TagsOption.setValue(bi.TagsOption.value());
+ return bi;
+}
diff --git a/fbreader/src/migration/BookInfo.h b/fbreader/src/migration/BookInfo.h
new file mode 100644
index 0000000..997e9ea
--- /dev/null
+++ b/fbreader/src/migration/BookInfo.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2004-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef __BOOKINFO_H__
+#define __BOOKINFO_H__
+
+#include <string>
+
+#include <ZLOptions.h>
+
+
+struct BookInfo {
+ BookInfo(const std::string &fileName);
+ ~BookInfo();
+
+ bool isFull() const;
+ void reset();
+
+ ZLStringOption AuthorDisplayNameOption;
+ ZLStringOption AuthorSortKeyOption;
+ ZLStringOption TitleOption;
+ ZLStringOption SeriesTitleOption;
+ ZLStringOption IndexInSeriesOption;
+ ZLStringOption LanguageOption;
+ ZLStringOption EncodingOption;
+ ZLStringOption TagsOption;
+
+ const BookInfo &operator = (const BookInfo &bi);
+};
+
+inline BookInfo::~BookInfo() {}
+
+#endif /* __BOOKINFO_H__ */
diff --git a/fbreader/src/migration/FB2MigrationReader.cpp b/fbreader/src/migration/FB2MigrationReader.cpp
new file mode 100644
index 0000000..875c0a5
--- /dev/null
+++ b/fbreader/src/migration/FB2MigrationReader.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2004-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <cstdlib>
+
+#include <ZLInputStream.h>
+#include <ZLUnicodeUtil.h>
+
+#include "FB2MigrationReader.h"
+#include "../formats/fb2/FB2TagManager.h"
+
+FB2MigrationReader::FB2MigrationReader(BookInfo &info, bool updateSeries) : myInfo(info), myUpdateSeries(updateSeries), myUpdateTags(info.TagsOption.value().empty()) {
+}
+
+void FB2MigrationReader::characterDataHandler(const char *text, std::size_t len) {
+ if (myReadState == READ_GENRE) {
+ myGenreBuffer.append(text, len);
+ }
+}
+
+void FB2MigrationReader::startElementHandler(int tag, const char **attributes) {
+ switch (tag) {
+ case _BODY:
+ interrupt();
+ break;
+ case _TITLE_INFO:
+ myReadState = READ_SOMETHING;
+ break;
+ case _GENRE:
+ if ((myReadState == READ_SOMETHING) && myUpdateTags) {
+ myReadState = READ_GENRE;
+ }
+ break;
+ case _SEQUENCE:
+ if ((myReadState == READ_SOMETHING) && myUpdateSeries) {
+ const char *name = attributeValue(attributes, "name");
+ if (name != 0) {
+ std::string seriesTitle = name;
+ ZLUnicodeUtil::utf8Trim(seriesTitle);
+ myInfo.SeriesTitleOption.setValue(seriesTitle);
+ const char *number = attributeValue(attributes, "number");
+ myInfo.IndexInSeriesOption.setValue((number != 0) ? std::string(number) : std::string());
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void FB2MigrationReader::endElementHandler(int tag) {
+ switch (tag) {
+ case _TITLE_INFO:
+ myReadState = READ_NOTHING;
+ break;
+ case _GENRE:
+ if (myReadState == READ_GENRE) {
+ ZLUnicodeUtil::utf8Trim(myGenreBuffer);
+ if (!myGenreBuffer.empty()) {
+ const std::vector<std::string> &tags =
+ FB2TagManager::Instance().humanReadableTags(myGenreBuffer);
+ if (!tags.empty()) {
+ myTags.insert(tags.begin(), tags.end());
+ } else {
+ myTags.insert(myGenreBuffer);
+ }
+ myGenreBuffer.erase();
+ }
+ myReadState = READ_SOMETHING;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void FB2MigrationReader::doRead(const ZLFile &file) {
+ myReadState = READ_NOTHING;
+ readDocument(file);
+ if (myUpdateTags) {
+ std::string tagList;
+ for (std::set<std::string>::const_iterator it = myTags.begin(); it != myTags.end(); ++it) {
+ if (it != myTags.begin()) {
+ tagList += ",";
+ }
+ tagList += *it;
+ }
+ myInfo.TagsOption.setValue(tagList);
+ }
+}
diff --git a/fbreader/src/migration/FB2MigrationReader.h b/fbreader/src/migration/FB2MigrationReader.h
new file mode 100644
index 0000000..d8e7dd2
--- /dev/null
+++ b/fbreader/src/migration/FB2MigrationReader.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2004-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef __FB2MIGRATIONREADER_H__
+#define __FB2MIGRATIONREADER_H__
+
+#include <set>
+#include <string>
+
+#include "../formats/fb2/FB2Reader.h"
+
+#include "BookInfo.h"
+
+class FB2MigrationReader : public FB2Reader {
+
+public:
+ FB2MigrationReader(BookInfo &info, bool updateSeries);
+
+ void doRead(const ZLFile &file);
+
+ void startElementHandler(int tag, const char **attributes);
+ void endElementHandler(int tag);
+ void characterDataHandler(const char *text, std::size_t len);
+
+private:
+ BookInfo &myInfo;
+
+ enum {
+ READ_NOTHING,
+ READ_SOMETHING,
+ READ_GENRE
+ } myReadState;
+
+ bool myUpdateSeries;
+ bool myUpdateTags;
+
+ std::string myGenreBuffer;
+ std::set<std::string> myTags;
+};
+
+#endif /* __FB2MIGRATIONREADER_H__ */
diff --git a/fbreader/src/migration/HtmlDCTagsReader.cpp b/fbreader/src/migration/HtmlDCTagsReader.cpp
new file mode 100644
index 0000000..4929686
--- /dev/null
+++ b/fbreader/src/migration/HtmlDCTagsReader.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2004-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <ZLStringUtil.h>
+
+#include "HtmlDCTagsReader.h"
+
+HtmlDCTagsReader::HtmlDCTagsReader(BookInfo &info) : HtmlReader(info.EncodingOption.value()), myInfo(info) {
+}
+
+bool HtmlDCTagsReader::tagHandler(const HtmlReader::HtmlTag &tag) {
+ if (tag.Name == "BODY") {
+ return false;
+ } else if (tag.Name == "DC:SUBJECT") {
+ myReadTag = tag.Start;
+ ZLStringUtil::stripWhiteSpaces(myBuffer);
+ if (!tag.Start && !myBuffer.empty()) {
+ if (!myTagList.empty()) {
+ myTagList += ",";
+ }
+ myTagList += myBuffer;
+ myBuffer.erase();
+ }
+ }
+ return true;
+}
+
+void HtmlDCTagsReader::startDocumentHandler() {
+ myReadTag = false;
+}
+
+void HtmlDCTagsReader::endDocumentHandler() {
+ myInfo.TagsOption.setValue(myTagList);
+}
+
+bool HtmlDCTagsReader::characterDataHandler(const char *text, std::size_t len, bool convert) {
+ if (myReadTag) {
+ if (convert) {
+ myConverter->convert(myBuffer, text, text + len);
+ } else {
+ myBuffer.append(text, len);
+ }
+ }
+ return true;
+}
diff --git a/fbreader/src/migration/HtmlDCTagsReader.h b/fbreader/src/migration/HtmlDCTagsReader.h
new file mode 100644
index 0000000..5cd7f9a
--- /dev/null
+++ b/fbreader/src/migration/HtmlDCTagsReader.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2004-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef __HTMLDCTAGSREADER_H__
+#define __HTMLDCTAGSREADER_H__
+
+#include "../formats/html/HtmlReader.h"
+#include "BookInfo.h"
+
+class HtmlDCTagsReader : public HtmlReader {
+
+public:
+ HtmlDCTagsReader(BookInfo &info);
+
+private:
+ void startDocumentHandler();
+ void endDocumentHandler();
+
+ bool tagHandler(const HtmlTag &tag);
+ bool characterDataHandler(const char *text, std::size_t len, bool convert);
+
+private:
+ BookInfo &myInfo;
+
+ bool myReadTag;
+
+ std::string myBuffer;
+ std::string myTagList;
+};
+
+#endif /* __HTMLDCTAGSREADER_H__ */
diff --git a/fbreader/src/migration/Migration.cpp b/fbreader/src/migration/Migration.cpp
new file mode 100644
index 0000000..172209d
--- /dev/null
+++ b/fbreader/src/migration/Migration.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2008-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <cstdlib>
+
+#include <ZLStringUtil.h>
+
+#include "../options/FBCategoryKey.h"
+
+#include "Migration.h"
+
+void Migration::moveOption(
+ const ZLCategoryKey &oldCategory, const std::string &oldGroup, const std::string &oldName,
+ const ZLCategoryKey &newCategory, const std::string &newGroup, const std::string &newName,
+ const std::string &defaultValue
+) {
+ ZLStringOption newOption(newCategory, newGroup, newName, defaultValue);
+ const std::string newValue = newOption.value();
+ ZLStringOption oldOption(oldCategory, oldGroup, oldName, newValue);
+ const std::string oldValue = oldOption.value();
+ if (newValue != oldValue) {
+ newOption.setValue(oldValue);
+ oldOption.setValue(newValue);
+ }
+}
+
+bool Migration::isLikeToFileName(const std::string &str) {
+ return
+ ZLStringUtil::stringStartsWith(str, "/") ||
+ ZLStringUtil::stringStartsWith(str, "\\\\") ||
+ ((str.length() > 2) && (str.substr(1, 2) == ":\\"));
+}
+
+Migration::Migration(const std::string &version) : myVersion(version) {
+}
+
+Migration::~Migration() {
+}
+
+int Migration::extractVersionInformation(const std::string &name) {
+ int major = std::atoi(name.c_str());
+ int minor = 0;
+ int point = 0;
+ int index = name.find('.');
+ if (index > 0) {
+ minor = std::atoi(name.c_str() + index + 1);
+ index = name.find('.', index + 1);
+ if (index > 0) {
+ point = std::atoi(name.c_str() + index + 1);
+ }
+ }
+ return 10000 * major + 100 * minor + point;
+}
+
+void Migration::doMigration() {
+ ZLStringOption versionOption(FBCategoryKey::SYSTEM, "Version", "FBReaderVersion", "0");
+ if (extractVersionInformation(versionOption.value()) <
+ extractVersionInformation(myVersion)) {
+ doMigrationInternal();
+ }
+}
diff --git a/fbreader/src/migration/Migration.h b/fbreader/src/migration/Migration.h
new file mode 100644
index 0000000..507da79
--- /dev/null
+++ b/fbreader/src/migration/Migration.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2008-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef __MIGRATION_H__
+#define __MIGRATION_H__
+
+#include <string>
+#include <map>
+
+#include <shared_ptr.h>
+#include <ZLOptions.h>
+
+class Migration {
+
+public:
+ static int extractVersionInformation(const std::string &name);
+
+protected:
+ static void moveOption(
+ const ZLCategoryKey &oldCategory, const std::string &oldGroup, const std::string &oldName,
+ const ZLCategoryKey &newCategory, const std::string &newGroup, const std::string &newName,
+ const std::string &defaultValue
+ );
+ static bool isLikeToFileName(const std::string &str);
+
+public:
+ Migration(const std::string &version);
+ virtual ~Migration();
+ void doMigration();
+
+protected:
+ virtual void doMigrationInternal() = 0;
+
+private:
+ const std::string myVersion;
+
+friend class Migration_0_11_0_Runnable;
+};
+
+class Migration_0_8_11 : public Migration {
+
+public:
+ Migration_0_8_11();
+
+protected:
+ void doMigrationInternal();
+};
+
+class Migration_0_8_13 : public Migration {
+
+public:
+ Migration_0_8_13();
+
+protected:
+ void doMigrationInternal();
+};
+
+class Migration_0_8_16 : public Migration {
+
+public:
+ Migration_0_8_16();
+
+protected:
+ void doMigrationInternal();
+};
+
+class Migration_0_10_4 : public Migration {
+
+public:
+ Migration_0_10_4();
+
+protected:
+ void doMigrationInternal();
+};
+
+class Migration_0_11_0 : public Migration {
+
+public:
+ Migration_0_11_0();
+
+protected:
+ void doMigrationInternal();
+};
+
+class Migration_0_99_0 : public Migration {
+
+public:
+ Migration_0_99_0();
+
+protected:
+ void doMigrationInternal();
+};
+
+class Migration_0_99_1 : public Migration {
+
+public:
+ Migration_0_99_1();
+
+protected:
+ void doMigrationInternal();
+};
+
+#endif /* __MIGRATION_H__ */
diff --git a/fbreader/src/migration/Migration_0_10_4.cpp b/fbreader/src/migration/Migration_0_10_4.cpp
new file mode 100644
index 0000000..b4cedbf
--- /dev/null
+++ b/fbreader/src/migration/Migration_0_10_4.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <vector>
+
+#include <ZLStringUtil.h>
+#include <ZLUnicodeUtil.h>
+
+#include "Migration.h"
+#include "../options/FBCategoryKey.h"
+
+Migration_0_10_4::Migration_0_10_4() : Migration("0.10.4") {
+}
+
+void Migration_0_10_4::doMigrationInternal() {
+ std::vector<std::string> groups;
+ ZLOption::listOptionGroups(groups);
+ for (std::vector<std::string>::const_iterator it = groups.begin(); it != groups.end(); ++it) {
+ static const std::string zipPostfix = ".zip";
+ static const std::string sizeName = "Size";
+ if (ZLStringUtil::stringEndsWith(ZLUnicodeUtil::toLower(*it), zipPostfix)) {
+ ZLIntegerOption option(FBCategoryKey::BOOKS, *it, sizeName, -1);
+ option.setValue(-1);
+ }
+ }
+}
diff --git a/fbreader/src/migration/Migration_0_11_0.cpp b/fbreader/src/migration/Migration_0_11_0.cpp
new file mode 100644
index 0000000..144245e
--- /dev/null
+++ b/fbreader/src/migration/Migration_0_11_0.cpp
@@ -0,0 +1,544 @@
+/*
+ * Copyright (C) 2009-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <iostream>
+#include <iomanip>
+#include <ZLTime.h>
+
+#include <vector>
+#include <algorithm>
+
+#include <ZLFile.h>
+#include <ZLStringUtil.h>
+#include <ZLUnicodeUtil.h>
+
+#include "BookInfo.h"
+#include "Migration.h"
+#include "../options/FBCategoryKey.h"
+
+#include "../formats/FormatPlugin.h"
+
+#include "../database/booksdb/BooksDBUtil.h"
+#include "../database/booksdb/BooksDB.h"
+#include "../library/Book.h"
+#include "../library/Tag.h"
+
+static const std::string BOOK_LIST_GROUP = "BookList";
+static const std::string BOOK_LIST_SIZE = "Size";
+static const std::string BOOK_LIST_PREFIX = "Book";
+
+static const std::string CURRENT_STATE_GROUP = "State";
+
+static const std::string RECENT_BOOKS_GROUP = "LastOpenedBooks";
+static const std::string BOOK = "Book";
+static const std::size_t MaxXmlListSize = 10;
+
+static const std::string PARAGRAPH_OPTION_NAME = "Paragraph";
+static const std::string WORD_OPTION_NAME = "Word";
+static const std::string CHAR_OPTION_NAME = "Char";
+static const std::string POSITION_IN_BUFFER = "PositionInBuffer";
+static const std::string BUFFER_SIZE = "UndoBufferSize";
+static const char * const BUFFER_PARAGRAPH_PREFIX = "Paragraph_";
+static const char * const BUFFER_WORD_PREFIX = "Word_";
+static const int MaxXmlStackSize = 20;
+
+static const std::string SIZE = "Size";
+static const std::string ENTRIES_NUMBER = "EntriesNumber";
+static const std::string PALM_TYPE = "PalmType";
+
+static const std::string NET_FILES_GROUP = "Files";
+
+class Migration_0_11_0_Runnable : public DBRunnable {
+
+public:
+ bool run();
+
+private:
+ bool migrateBooks();
+ bool migrateBookList();
+ bool migrateState();
+ bool migrateNetwork();
+
+ bool migrateBook(const ZLFile &file);
+
+ std::string tags2string(const TagList &tags);
+
+ bool stringEquals(const std::string &tags1, const std::string &tags2);
+
+ bool migrateRecentBooks();
+
+ bool migrateBooksState();
+
+ bool migrateBookStateStack(const std::string &fileName, const Book &book);
+ bool migrateBookLastState(const std::string &fileName, const Book &book);
+
+ bool shouldReadDisk(const std::string &fileName);
+
+ bool clearBooksOptions();
+
+ static void moveOption(const ZLCategoryKey &category, const std::string &oldGroup, const std::string &newGroup, const std::string &name, const std::string &defaultValue);
+ static void moveOption(const ZLCategoryKey &category, const std::string &oldGroup, const std::string &newGroup, const std::string &name, int defaultValue);
+ static void movePercentGroups(std::vector<std::string> &optionGroups);
+ static void moveBookGroup(const std::string &oldgroup, const std::string &newgroup);
+
+private:
+ std::map<std::string, shared_ptr<Book> > myBooks;
+};
+
+
+inline bool Migration_0_11_0_Runnable::shouldReadDisk(const std::string &fileName) {
+ const std::string ext = ZLFile(fileName).extension();
+ return ext == "fb2" || ext == "epub" || ext == "mobi" || ext == "oebzip" || ext == "opf";
+ //return ext == "fb2";
+ //return true;
+}
+
+
+void Migration_0_11_0_Runnable::moveOption(const ZLCategoryKey &category, const std::string &oldGroup, const std::string &newGroup, const std::string &name, const std::string &defaultValue) {
+ ZLStringOption newOption(category, newGroup, name, defaultValue);
+ ZLStringOption oldOption(category, oldGroup, name, defaultValue);
+ newOption.setValue(oldOption.value());
+ oldOption.setValue(defaultValue);
+}
+
+void Migration_0_11_0_Runnable::moveOption(const ZLCategoryKey &category, const std::string &oldGroup, const std::string &newGroup, const std::string &name, int defaultValue) {
+ ZLIntegerOption newOption(category, newGroup, name, defaultValue);
+ ZLIntegerOption oldOption(category, oldGroup, name, defaultValue);
+ newOption.setValue(oldOption.value());
+ oldOption.setValue(defaultValue);
+}
+
+static bool percentPathPredicate(const std::string &path) {
+ static const std::string _start = "%APPLICATION_PATH%";
+ return ZLStringUtil::stringStartsWith(path, _start);
+}
+
+void Migration_0_11_0_Runnable::movePercentGroups(std::vector<std::string> &optionGroups) {
+ std::vector<std::string>::iterator it = optionGroups.begin();
+ while ((it = std::find_if(it, optionGroups.end(), percentPathPredicate)) != optionGroups.end()) {
+ const std::string oldgroup = *it;
+ const std::string newgroup = ZLFile(oldgroup).resolvedPath();
+ if (std::find(optionGroups.begin(), optionGroups.end(), newgroup) == optionGroups.end()) {
+ moveBookGroup(oldgroup, newgroup);
+ *it++ = newgroup;
+ } else {
+ if (BookInfo(newgroup).TitleOption.value().empty()) {
+ moveBookGroup(oldgroup, newgroup);
+ }
+ it = optionGroups.erase(it);
+ }
+ ZLOption::clearGroup(oldgroup);
+ }
+}
+
+void Migration_0_11_0_Runnable::moveBookGroup(const std::string &oldgroup, const std::string &newgroup) {
+ BookInfo oldbi(oldgroup);
+ BookInfo newbi(newgroup);
+ newbi = oldbi;
+ oldbi.reset();
+
+ moveOption(ZLCategoryKey::STATE, oldgroup, newgroup, PARAGRAPH_OPTION_NAME, 0);
+ moveOption(ZLCategoryKey::STATE, oldgroup, newgroup, WORD_OPTION_NAME, 0);
+ moveOption(ZLCategoryKey::STATE, oldgroup, newgroup, CHAR_OPTION_NAME, 0);
+ moveOption(ZLCategoryKey::STATE, oldgroup, newgroup, POSITION_IN_BUFFER, 0);
+
+ int stackSize = ZLIntegerOption(ZLCategoryKey::STATE, oldgroup, BUFFER_SIZE, 0).value();
+ for (int i = 0; i < stackSize; ++i) {
+ std::string bufferParagraph = BUFFER_PARAGRAPH_PREFIX;
+ std::string bufferWord = BUFFER_WORD_PREFIX;
+ ZLStringUtil::appendNumber(bufferParagraph, i);
+ ZLStringUtil::appendNumber(bufferWord, i);
+ moveOption(ZLCategoryKey::STATE, oldgroup, newgroup, bufferParagraph, -1);
+ moveOption(ZLCategoryKey::STATE, oldgroup, newgroup, bufferWord, -1);
+ }
+ moveOption(ZLCategoryKey::STATE, oldgroup, newgroup, BUFFER_SIZE, 0);
+}
+
+
+
+Migration_0_11_0::Migration_0_11_0() : Migration("0.11.0") {
+}
+
+void Migration_0_11_0::doMigrationInternal() {
+ Migration_0_11_0_Runnable r;
+ BooksDB::Instance().executeAsTransaction(r);
+ //r.run();
+}
+
+bool Migration_0_11_0_Runnable::run() {
+const ZLTime start;
+ if (!migrateBooks()) {
+ std::cerr << std::endl << "VERDICT: migrateBooks failed" << std::endl << std::endl;
+ }
+std::cerr << "migration total 0: " << ZLTime().millisecondsFrom(start) << "ms" << std::endl;
+ if (!migrateBookList()) {
+ std::cerr << std::endl << "VERDICT: migrateBookList failed" << std::endl << std::endl;
+ }
+std::cerr << "migration total 1: " << ZLTime().millisecondsFrom(start) << "ms" << std::endl;
+ if (!migrateState()) {
+ std::cerr << std::endl << "VERDICT: migrateState failed" << std::endl << std::endl;
+ }
+std::cerr << "migration total 2: " << ZLTime().millisecondsFrom(start) << "ms" << std::endl;
+ if (!migrateNetwork()) {
+ std::cerr << std::endl << "VERDICT: migrateNetwork failed" << std::endl << std::endl;
+ }
+std::cerr << "migration total 3: " << ZLTime().millisecondsFrom(start) << "ms" << std::endl;
+ if (!clearBooksOptions()) {
+ std::cerr << std::endl << "VERDICT: clearBooksOptions failed" << std::endl << std::endl;
+ }
+std::cerr << "migration total 4: " << ZLTime().millisecondsFrom(start) << "ms" << std::endl;
+ return true;
+}
+
+
+
+bool Migration_0_11_0_Runnable::migrateBooks() {
+ /*std::map<std::string, unsigned long> ext2time;
+ std::map<std::string, unsigned long> ext2num;
+ unsigned long totalTime = 0, totalNum = 0;*/
+
+ PluginCollection &collection = PluginCollection::Instance();
+ std::vector<std::string> optionGroups;
+ ZLOption::listOptionGroups(optionGroups);
+
+ movePercentGroups(optionGroups);
+
+ bool res = true;
+ for (std::vector<std::string>::const_iterator it = optionGroups.begin(); it != optionGroups.end(); ++it) {
+ const std::string &name = *it;
+ if (Migration::isLikeToFileName(name)) {
+ /* TODO: check correctness of migration order:
+ * 1) palmType
+ * 2) size
+ * 3) book (depends on palmType and size)
+ */
+ const std::string palmType = ZLStringOption(FBCategoryKey::BOOKS, name, PALM_TYPE, "").value();
+ if (!palmType.empty()) {
+ BooksDB::Instance().setPalmType(name, palmType);
+ }
+ ZLStringOption(FBCategoryKey::BOOKS, name, PALM_TYPE, "").setValue(""); // clean books.xml
+ ZLFile file(name);
+ if (file.physicalFilePath() == name) {
+ int size = ZLIntegerOption(FBCategoryKey::BOOKS, name, SIZE, -1).value();
+ if (size != -1) {
+ BooksDB::Instance().setFileSize(name, size);
+ }
+ }
+ if (collection.plugin(file, false) != 0) {
+ if (!BookInfo(name).TitleOption.value().empty()) {
+ //ZLTime start;
+ if (!migrateBook(ZLFile(name))) {
+ std::cerr << "ERROR(2): migrateBook failed" << std::endl;
+ res = false;
+ }
+ /*ZLTime end;
+ {
+ unsigned time = end.millisecondsFrom(start);
+ std::string ext = ZLFile(name).extension();
+ totalTime += time;
+ totalNum += 1;
+ ext2time[ext] += time;
+ ext2num[ext] += 1;
+ }*/
+ }
+ BookInfo(name).reset(); // clean books.xml
+ } else {
+ ZLOption::clearGroup(name); // clean books.xml
+ }
+ ZLIntegerOption(FBCategoryKey::BOOKS, name, SIZE, -1).setValue(-1); // clean books.xml
+ if (!ZLStringOption(FBCategoryKey::BOOKS, name, ENTRIES_NUMBER, "").value().empty()) {
+ ZLOption::clearGroup(name); // clean books.xml
+ }
+ }
+ }
+
+ /*std::cerr << " ext" << " time,ms" << " time/total,%" << " number of books" << " time for 1 book,ms" << std::endl;
+ std::cerr << "---------------------------------------------------------------------------" << std::endl;
+ for (std::map<std::string, unsigned long>::const_iterator it = ext2time.begin(); it != ext2time.end(); ++it) {
+ const std::string &ext = it->first;
+ unsigned long time = it->second;
+ unsigned long num = ext2num[ext];
+ std::cerr << std::setw(8) << ext << std::setw(10) << time << std::setw(15) << ((float) time) / totalTime * 100.0
+ << std::setw(18) << num << std::setw(22) << ((float) time) / num << std::endl;
+ }
+ std::cerr << "---------------------------------------------------------------------------" << std::endl;
+ std::cerr << "total:" << std::endl;
+ std::cerr << std::setw(8) << "" << std::setw(10) << totalTime << std::setw(15) << ""
+ << std::setw(20) << totalNum << std::setw(20) << "" << std::endl;*/
+
+ return res;
+}
+
+
+bool Migration_0_11_0_Runnable::migrateBook(const ZLFile &file) {
+ shared_ptr<Book> infoBook = Book::loadFromBookInfo(file);
+ if (infoBook.isNull()) {
+ std::cerr << "ERROR: loading book from BookInfo failed: " << file.path() << std::endl;
+ return false;
+ }
+ if (shouldReadDisk(file.path()) && BooksDBUtil::isBookFull(*infoBook)) {
+ shared_ptr<Book> fileBook = Book::loadFromFile(file);
+ //shared_ptr<Book> fileBook = infoBook;
+ //shared_ptr<Book> fileBook;
+ if (!fileBook.isNull()) {
+ std::string tagList1 = tags2string(infoBook->tags());
+ std::string tagList2 = tags2string(fileBook->tags());
+ if (stringEquals(tagList1, tagList2)) {
+ infoBook->removeAllTags();
+ const TagList &tList = fileBook->tags();
+ for (TagList::const_iterator it = tList.begin(); it != tList.end(); ++it) {
+ infoBook->addTag(*it);
+ }
+ }
+ }
+ }
+ myBooks.insert(std::make_pair(file.path(), infoBook));
+ const bool code = BooksDB::Instance().saveBook(infoBook);
+ if (!code) {
+ std::cerr << "ERROR: saving book to database failed: " << file.path() << std::endl;
+ }
+ return code;
+}
+
+std::string Migration_0_11_0_Runnable::tags2string(const TagList &tags) {
+ std::string tagList;
+ TagList::const_iterator it = tags.begin();
+ if (it != tags.end()) {
+ tagList += (*it++)->fullName();
+ while (it != tags.end()) {
+ tagList += ',';
+ tagList += (*it++)->fullName();
+ }
+ }
+ return tagList;
+}
+
+bool Migration_0_11_0_Runnable::stringEquals(const std::string &tags1, const std::string &tags2) {
+ std::size_t i1 = 0;
+ std::size_t i2 = 0;
+ while (i1 < tags1.size() && i2 < tags2.size()) {
+ if (std::isspace(tags1[i1])) {
+ ++i1;
+ continue;
+ }
+ if (std::isspace(tags2[i2])) {
+ ++i2;
+ continue;
+ }
+ if (tags1[i1++] != tags2[i2++]) {
+ return false;
+ }
+ }
+ if (i1 == tags1.size() && i2 < tags2.size()) {
+ while (i2 < tags2.size()) {
+ if (!std::isspace(tags2[i2++])) {
+ return false;
+ }
+ }
+ return true;
+ }
+ if (i1 < tags1.size() && i2 == tags2.size()) {
+ while (i1 < tags1.size()) {
+ if (!std::isspace(tags1[i1++])) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return true;
+}
+
+bool Migration_0_11_0_Runnable::migrateBookList() {
+ bool res = true;
+ int size = ZLIntegerOption(ZLCategoryKey::STATE, BOOK_LIST_GROUP, BOOK_LIST_SIZE, 0).value();
+ for (int i = 0; i < size; ++i) {
+ std::string optionName = BOOK_LIST_PREFIX;
+ ZLStringUtil::appendNumber(optionName, i);
+ const std::string &fileName = ZLStringOption(ZLCategoryKey::STATE, BOOK_LIST_GROUP, optionName, "").value();
+ if (!fileName.empty()) {
+ std::map<std::string, shared_ptr<Book> >::iterator it = myBooks.find(fileName);
+ if (it != myBooks.end()) {
+ shared_ptr<Book> book = it->second;
+ if (!book.isNull() && book->bookId() != 0) {
+ if (!BooksDB::Instance().insertIntoBookList(*book)) {
+ std::cerr << "ERROR: insert into BookList failed: " << fileName << std::endl;
+ res = false;
+ }
+ }
+ }
+ }
+ }
+ ZLOption::clearGroup(BOOK_LIST_GROUP); // clean state.xml
+ return res;
+}
+
+bool Migration_0_11_0_Runnable::migrateState() {
+ bool res = true;
+ if (!migrateRecentBooks()) {
+ std::cerr << "ERROR(2): migrateRecentBooks failed" << std::endl;
+ res = false;
+ }
+ if (!migrateBooksState()) {
+ std::cerr << "ERROR(2): migrateBooksState failed" << std::endl;
+ res = false;
+ }
+ ZLOption::clearGroup(RECENT_BOOKS_GROUP); // clean state.xml
+ ZLOption::clearGroup(CURRENT_STATE_GROUP); // clean state.xml
+ return res;
+}
+
+bool Migration_0_11_0_Runnable::migrateRecentBooks() {
+ BookList books;
+ for (std::size_t i = 0; i < MaxXmlListSize; ++i) {
+ std::string num = BOOK;
+ ZLStringUtil::appendNumber(num, i);
+ std::string name = ZLStringOption(ZLCategoryKey::STATE, RECENT_BOOKS_GROUP, num, "").value();
+ if (!name.empty()) {
+ //shared_ptr<Book> book = BooksDBUtil::getBook(name, false);
+ std::map<std::string, shared_ptr<Book> >::const_iterator it = myBooks.find(name);
+ if (it == myBooks.end()) {
+ if ((it = myBooks.find(ZLFile(name).resolvedPath())) == myBooks.end()) {
+ continue;
+ }
+ }
+ shared_ptr<Book> book = it->second;
+ if (!book.isNull() && book->bookId() != 0 && std::find(books.begin(), books.end(), book) == books.end()) {
+ books.push_back(book);
+ }
+ }
+ }
+ bool res = BooksDB::Instance().saveRecentBooks(books);
+ if (!res) {
+ std::cerr << "ERROR: saving recent books list failed (" << books.size() << " item[s])" << std::endl;
+ }
+ return res;
+}
+
+bool Migration_0_11_0_Runnable::migrateBooksState() {
+ bool res = true;
+
+ for (std::map<std::string, shared_ptr<Book> >::const_iterator it = myBooks.begin(); it != myBooks.end(); ++it) {
+ const std::string &fileName = it->first;
+ if (it->second.isNull()) {
+ std::cerr << "ERROR: book in map is null: " << fileName << std::endl;
+ res = false;
+ continue;
+ }
+ const Book &book = *it->second;
+ if (!migrateBookStateStack(fileName, book)) {
+ res = false;
+ }
+ if (!migrateBookLastState(fileName, book)) {
+ res = false;
+ }
+ }
+ return res;
+}
+
+
+bool Migration_0_11_0_Runnable::migrateBookStateStack(const std::string &fileName, const Book &book) {
+ std::deque<ReadingState> stack;
+ bool res = true;
+ int stackSize = ZLIntegerOption(ZLCategoryKey::STATE, fileName, BUFFER_SIZE, 0).value();
+ if (stackSize > 0) {
+ if (stackSize > MaxXmlStackSize) {
+ stackSize = MaxXmlStackSize;
+ }
+ for (int i = 0; i < stackSize; ++i) {
+ std::string bufferParagraph = BUFFER_PARAGRAPH_PREFIX;
+ std::string bufferWord = BUFFER_WORD_PREFIX;
+ ZLStringUtil::appendNumber(bufferParagraph, i);
+ ZLStringUtil::appendNumber(bufferWord, i);
+ ReadingState pos(
+ ZLIntegerOption(ZLCategoryKey::STATE, fileName, bufferParagraph, -1).value(),
+ ZLIntegerOption(ZLCategoryKey::STATE, fileName, bufferWord, -1).value(),
+ 0
+ );
+ stack.push_back(pos);
+ ZLIntegerOption(ZLCategoryKey::STATE, fileName, bufferParagraph, -1).setValue(-1); // clean state.xml
+ ZLIntegerOption(ZLCategoryKey::STATE, fileName, bufferWord, -1).setValue(-1); // clean state.xml
+ }
+ if (!BooksDB::Instance().saveBookStateStack(book, stack)) {
+ std::cerr << "ERROR: saving book state stack failed: " << fileName << std::endl;
+ res = false;
+ }
+ stack.clear();
+ }
+ ZLIntegerOption(ZLCategoryKey::STATE, fileName, BUFFER_SIZE, 0).setValue(0); // clean state.xml
+ return res;
+}
+
+bool Migration_0_11_0_Runnable::migrateBookLastState(const std::string &fileName, const Book &book) {
+ const ReadingState state(
+ ZLIntegerOption(ZLCategoryKey::STATE, fileName, PARAGRAPH_OPTION_NAME, 0).value(),
+ ZLIntegerOption(ZLCategoryKey::STATE, fileName, WORD_OPTION_NAME, 0).value(),
+ ZLIntegerOption(ZLCategoryKey::STATE, fileName, CHAR_OPTION_NAME, 0).value()
+ );
+ const int stackPos = ZLIntegerOption(ZLCategoryKey::STATE, fileName, POSITION_IN_BUFFER, 0).value();
+ if (state.Paragraph == 0 && state.Word == 0 && state.Character == 0 && stackPos == 0) {
+ return true;
+ }
+ ZLIntegerOption(ZLCategoryKey::STATE, fileName, PARAGRAPH_OPTION_NAME, 0).setValue(0);
+ ZLIntegerOption(ZLCategoryKey::STATE, fileName, WORD_OPTION_NAME, 0).setValue(0);
+ ZLIntegerOption(ZLCategoryKey::STATE, fileName, CHAR_OPTION_NAME, 0).setValue(0);
+ ZLIntegerOption(ZLCategoryKey::STATE, fileName, POSITION_IN_BUFFER, 0).setValue(0);
+ bool res1 = BooksDB::Instance().setBookState(book, state);
+ bool res2 = BooksDB::Instance().setStackPos(book, stackPos);
+ if (!res1) {
+ std::cerr << "ERROR: saving book last state failed: " << fileName << std::endl;
+ }
+ if (!res2) {
+ std::cerr << "ERROR: saving book state stack position failed: " << fileName << std::endl;
+ }
+ return res1 && res2;
+}
+
+bool Migration_0_11_0_Runnable::migrateNetwork() {
+ bool res = true;
+// FBReader desktop 0.99.1 deprecates NetFiles table, so don't fill it
+// std::vector<std::string> urls;
+// ZLOption::listOptionNames(NET_FILES_GROUP, urls);
+// for (std::vector<std::string>::const_iterator it = urls.begin(); it != urls.end(); ++it) {
+// const std::string &url = *it;
+// const std::string fileName = ZLStringOption(ZLCategoryKey::NETWORK, NET_FILES_GROUP, url, "").value();
+// if (!BooksDB::Instance().setNetFile(url, fileName)) {
+// std::cerr << "ERROR: saving file's URL failed: " << std::endl
+// << "\tURL = " << url << std::endl
+// << "\tfileName = " << fileName << std::endl;
+// res = false;
+// }
+// }
+ ZLOption::clearGroup(NET_FILES_GROUP); // clean state.xml
+ return res;
+}
+
+bool Migration_0_11_0_Runnable::clearBooksOptions() {
+ bool res = true;
+ for (std::map<std::string, shared_ptr<Book> >::const_iterator it = myBooks.begin(); it != myBooks.end(); ++it) {
+ const std::string &fileName = it->first;
+ if (it->second.isNull()) {
+ std::cerr << "ERROR: book in map is null in clearBooksOptions: " << fileName << std::endl;
+ res = false;
+ continue;
+ }
+ ZLOption::clearGroup(fileName); // clear books.xml & state.xml
+ }
+ return res;
+}
+
diff --git a/fbreader/src/migration/Migration_0_8_11.cpp b/fbreader/src/migration/Migration_0_8_11.cpp
new file mode 100644
index 0000000..d4fd2f3
--- /dev/null
+++ b/fbreader/src/migration/Migration_0_8_11.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2008-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <map>
+
+#include <ZLStringUtil.h>
+
+#include "Migration.h"
+#include "../fbreader/FBReaderActions.h"
+
+static void changeActionNames(const std::map<std::string,std::string> map, const std::string &group) {
+ const int length = ZLIntegerOption(ZLCategoryKey::CONFIG, group, "Number", 0).value();
+ for (int i = 0; i < length; ++i) {
+ std::string optionName = "Action";
+ ZLStringUtil::appendNumber(optionName, i);
+ ZLStringOption option(ZLCategoryKey::CONFIG, group, optionName, "");
+ std::string value = option.value();
+ std::map<std::string,std::string>::const_iterator it = map.find(value);
+ if (it != map.end()) {
+ option.setValue(it->second);
+ }
+ }
+}
+
+static void changeActionNames() {
+ std::map<std::string,std::string> oldToNewNames;
+ oldToNewNames["0"] = "none";
+ oldToNewNames["1"] = ActionCode::SHOW_LIBRARY;
+ oldToNewNames["30"] = ActionCode::OPEN_PREVIOUS_BOOK;
+ oldToNewNames["5"] = ActionCode::SHOW_TOC;
+ oldToNewNames["15"] = ActionCode::SCROLL_TO_HOME;
+ oldToNewNames["16"] = ActionCode::SCROLL_TO_START_OF_TEXT;
+ oldToNewNames["17"] = ActionCode::SCROLL_TO_END_OF_TEXT;
+ oldToNewNames["33"] = ActionCode::GOTO_NEXT_TOC_SECTION;
+ oldToNewNames["34"] = ActionCode::GOTO_PREVIOUS_TOC_SECTION;
+ oldToNewNames["9"] = ActionCode::PAGE_SCROLL_FORWARD;
+ oldToNewNames["10"] = ActionCode::PAGE_SCROLL_BACKWARD;
+ oldToNewNames["11"] = ActionCode::LINE_SCROLL_FORWARD;
+ oldToNewNames["12"] = ActionCode::LINE_SCROLL_BACKWARD;
+ oldToNewNames["3"] = ActionCode::UNDO;
+ oldToNewNames["4"] = ActionCode::REDO;
+ oldToNewNames["35"] = ActionCode::COPY_SELECTED_TEXT_TO_CLIPBOARD;
+ oldToNewNames["37"] = ActionCode::OPEN_SELECTED_TEXT_IN_DICTIONARY;
+ oldToNewNames["36"] = ActionCode::CLEAR_SELECTION;
+ oldToNewNames["6"] = ActionCode::SEARCH;
+ oldToNewNames["7"] = ActionCode::FIND_PREVIOUS;
+ oldToNewNames["8"] = ActionCode::FIND_NEXT;
+ oldToNewNames["19"] = ActionCode::INCREASE_FONT;
+ oldToNewNames["20"] = ActionCode::DECREASE_FONT;
+ oldToNewNames["21"] = ActionCode::SHOW_HIDE_POSITION_INDICATOR;
+ oldToNewNames["22"] = ActionCode::TOGGLE_FULLSCREEN;
+ oldToNewNames["23"] = ActionCode::FULLSCREEN_ON;
+ oldToNewNames["27"] = ActionCode::ROTATE_SCREEN;
+ oldToNewNames["2"] = ActionCode::SHOW_OPTIONS_DIALOG;
+ oldToNewNames["25"] = ActionCode::SHOW_BOOK_INFO_DIALOG;
+ oldToNewNames["24"] = ActionCode::ADD_BOOK;
+ oldToNewNames["18"] = ActionCode::CANCEL;
+ oldToNewNames["29"] = ActionCode::QUIT;
+
+ changeActionNames(oldToNewNames, "Keys");
+ changeActionNames(oldToNewNames, "Keys90");
+ changeActionNames(oldToNewNames, "Keys180");
+ changeActionNames(oldToNewNames, "Keys270");
+}
+
+Migration_0_8_11::Migration_0_8_11() : Migration("0.8.11") {
+}
+
+void Migration_0_8_11::doMigrationInternal() {
+ moveOption(
+ ZLCategoryKey::CONFIG, "FingerTapScrolling", "ScrollingDelay",
+ ZLCategoryKey::CONFIG, "TapScrolling", "ScrollingDelay",
+ "0"
+ );
+ moveOption(
+ ZLCategoryKey::CONFIG, "FingerTapScrolling", "Mode",
+ ZLCategoryKey::CONFIG, "TapScrolling", "Mode",
+ "0"
+ );
+ moveOption(
+ ZLCategoryKey::CONFIG, "FingerTapScrolling", "LinesToKeep",
+ ZLCategoryKey::CONFIG, "TapScrolling", "LinesToKeep",
+ "1"
+ );
+ moveOption(
+ ZLCategoryKey::CONFIG, "FingerTapScrolling", "LinesToScroll",
+ ZLCategoryKey::CONFIG, "TapScrolling", "LinesToScroll",
+ "1"
+ );
+ moveOption(
+ ZLCategoryKey::CONFIG, "FingerTapScrolling", "PercentToScroll",
+ ZLCategoryKey::CONFIG, "TapScrolling", "PercentToScroll",
+ "50"
+ );
+ moveOption(
+ ZLCategoryKey::CONFIG, "FingerTapScrolling", "Enabled",
+ ZLCategoryKey::CONFIG, "TapScrolling", "Enabled",
+ "true"
+ );
+ moveOption(
+ ZLCategoryKey::CONFIG, "Options", "ScrollingDelay",
+ ZLCategoryKey::CONFIG, "LargeScrolling", "ScrollingDelay",
+ "250"
+ );
+ changeActionNames();
+}
diff --git a/fbreader/src/migration/Migration_0_8_13.cpp b/fbreader/src/migration/Migration_0_8_13.cpp
new file mode 100644
index 0000000..ff86fed
--- /dev/null
+++ b/fbreader/src/migration/Migration_0_8_13.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <vector>
+
+#include <ZLStringUtil.h>
+
+#include "Migration.h"
+
+Migration_0_8_13::Migration_0_8_13() : Migration("0.8.13") {
+}
+
+void Migration_0_8_13::doMigrationInternal() {
+ std::vector<std::string> optionNames;
+ ZLOption::listOptionNames("Style", optionNames);
+ for (std::vector<std::string>::const_iterator it = optionNames.begin(); it != optionNames.end(); ++it) {
+ if (ZLStringUtil::stringEndsWith(*it, ":lineSpacing") ||
+ ZLStringUtil::stringEndsWith(*it, ":lineSpace")) {
+ ZLDoubleOption doubleOption(ZLCategoryKey::LOOK_AND_FEEL, "Style", *it, 0.0);
+ ZLIntegerOption intOption(ZLCategoryKey::LOOK_AND_FEEL, "Style", *it + "Percent", -1);
+ const double doubleValue = doubleOption.value();
+ const int intValue = intOption.value();
+ doubleOption.setValue((intValue == -1) ? 0.0 : (intValue / 100.0));
+ intOption.setValue((int)(doubleValue * 100));
+ }
+ }
+}
diff --git a/fbreader/src/migration/Migration_0_8_16.cpp b/fbreader/src/migration/Migration_0_8_16.cpp
new file mode 100644
index 0000000..d08fc49
--- /dev/null
+++ b/fbreader/src/migration/Migration_0_8_16.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2008-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <ZLFile.h>
+#include <ZLLanguageUtil.h>
+
+#include "Migration.h"
+#include "FB2MigrationReader.h"
+#include "OEBMigrationReader.h"
+#include "HtmlDCTagsReader.h"
+#include "BookInfo.h"
+
+#include "../options/FBCategoryKey.h"
+#include "../formats/oeb/OEBPlugin.h"
+#include "../formats/pdb/PdbPlugin.h"
+#include "../formats/pdb/PalmDocStream.h"
+
+Migration_0_8_16::Migration_0_8_16() : Migration("0.8.16") {
+}
+
+void Migration_0_8_16::doMigrationInternal() {
+ PluginCollection &collection = PluginCollection::Instance();
+
+ std::vector<std::string> optionGroups;
+ ZLOption::listOptionGroups(optionGroups);
+
+ for (std::vector<std::string>::const_iterator it = optionGroups.begin(); it != optionGroups.end(); ++it) {
+ if (isLikeToFileName(*it)) {
+ ZLFile file(*it);
+ if (collection.plugin(file, false) != 0) {
+ BookInfo info(*it);
+ ZLStringOption &languageOption = info.LanguageOption;
+ const std::string &language = languageOption.value();
+ if (language == "") {
+ languageOption.setValue(collection.DefaultLanguageOption.value());
+ } else if (language == "cz") {
+ languageOption.setValue("cs");
+ } else if (language == "none") {
+ languageOption.setValue(ZLLanguageUtil::OtherLanguageCode);
+ } else if ((language == "chinese") || (language == "anycharacter")) {
+ languageOption.setValue("zh");
+ }
+
+ const std::string extension = file.extension();
+ if (extension == "fb2") {
+ ZLBooleanOption seriesOption(FBCategoryKey::BOOKS, *it, "SequenceDefined", false);
+ if (!seriesOption.value() || info.TagsOption.value().empty()) {
+ FB2MigrationReader(info, !seriesOption.value()).doRead(ZLFile(*it));
+ }
+ seriesOption.setValue(true);
+ } else if ((extension == "opf") || (extension == "oebzip") || (extension == "epub")) {
+ if (info.TagsOption.value().empty()) {
+ OEBMigrationReader(info).doRead(OEBPlugin::opfFile(ZLFile(*it)));
+ }
+ } else if ((extension == "prc") || (extension == "pdb") || (extension == "mobi")) {
+ const std::string fileType = PdbPlugin::fileType(file);
+ if (info.TagsOption.value().empty() && ((fileType == "BOOKMOBI") || (fileType == "TEXtREAd"))) {
+ shared_ptr<ZLInputStream> stream = new PalmDocStream(file);
+ if (!stream.isNull()) {
+ HtmlDCTagsReader(info).readDocument(*stream);
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/fbreader/src/migration/Migration_0_99_0.cpp b/fbreader/src/migration/Migration_0_99_0.cpp
new file mode 100644
index 0000000..6a1d253
--- /dev/null
+++ b/fbreader/src/migration/Migration_0_99_0.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2009-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <string>
+
+#include <ZLLogger.h>
+
+#include "../database/booksdb/BooksDB.h"
+#include "../library/Number.h"
+
+#include "Migration.h"
+
+static const std::string RENAME_TABLE_TO_OBSOLETE = "ALTER TABLE BookSeries RENAME TO BookSeries_Obsolete";
+static const std::string CREATE_NEW_TABLE = \
+ "CREATE TABLE IF NOT EXISTS BookSeries ( " \
+ " book_id INTEGER UNIQUE NOT NULL REFERENCES Books (book_id), " \
+ " series_id INTEGER NOT NULL REFERENCES Series (series_id), " \
+ " book_index TEXT " \
+ "); ";
+static const std::string DROP_OBSOLETE_TABLE = "DROP TABLE BookSeries_Obsolete";
+static const std::string LOAD_OBSOLETE_SERIES_QUERY =
+ "SELECT book_id, series_id, book_index" \
+ " FROM BookSeries_Obsolete;";
+
+class Migration_0_99_0_Runnable : public DBRunnable {
+public:
+ bool run();
+
+};
+
+bool Migration_0_99_0_Runnable::run() {
+ DBConnection &connection = BooksDB::Instance().connection();
+
+ shared_ptr<DBCommand> renameTable = SQLiteFactory::createCommand(RENAME_TABLE_TO_OBSOLETE, connection);
+ shared_ptr<DBCommand> createNewTable = SQLiteFactory::createCommand(CREATE_NEW_TABLE, connection);
+ shared_ptr<DBCommand> dropObsoleteTable = SQLiteFactory::createCommand(DROP_OBSOLETE_TABLE, connection);
+ shared_ptr<DBCommand> loadObsoleteSeries = SQLiteFactory::createCommand(LOAD_OBSOLETE_SERIES_QUERY, connection);
+ shared_ptr<DBCommand> insertBookSeries = SQLiteFactory::createCommand(BooksDBQuery::SET_BOOKSERIES, connection, "@book_id", DBValue::DBINT, "@series_id", DBValue::DBINT, "@book_index", DBValue::DBTEXT);
+
+ if (!renameTable->execute()) {
+ return false;
+ }
+ if (!createNewTable->execute()) {
+ return false;
+ }
+
+ shared_ptr<DBDataReader> reader = loadObsoleteSeries->executeReader();
+ while (reader->next()) {
+ ((DBIntValue &) *insertBookSeries->parameter("@book_id").value()) = reader->intValue(0);
+ ((DBIntValue &) *insertBookSeries->parameter("@series_id").value()) = reader->intValue(1);
+ Number seriesIndex;
+ if (reader->type(2) == DBValue::DBREAL){
+ seriesIndex = Number((int)reader->realValue(2));
+ } else {
+ seriesIndex = Number(reader->intValue(2));
+ }
+ ((DBTextValue &) *insertBookSeries->parameter("@book_index").value()) = seriesIndex.value();
+ if (!insertBookSeries->execute()) {
+ ZLLogger::Instance().println("Migration", "problems with inserting series & book index");
+ }
+ }
+ dropObsoleteTable->execute();
+ return true;
+}
+
+
+Migration_0_99_0::Migration_0_99_0() : Migration("0.99.0") {
+
+}
+
+void Migration_0_99_0::doMigrationInternal() {
+ Migration_0_99_0_Runnable r;
+ BooksDB::Instance().executeAsTransaction(r);
+}
+
diff --git a/fbreader/src/migration/Migration_0_99_1.cpp b/fbreader/src/migration/Migration_0_99_1.cpp
new file mode 100644
index 0000000..970f4fc
--- /dev/null
+++ b/fbreader/src/migration/Migration_0_99_1.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <map>
+
+#include <ZLStringUtil.h>
+
+#include "Migration.h"
+#include "../fbreader/FBReaderActions.h"
+#include "../database/networkdb/NetworkDB.h"
+
+Migration_0_99_1::Migration_0_99_1() : Migration("0.99.1") {
+}
+
+void Migration_0_99_1::doMigrationInternal() {
+ shared_ptr<DBCommand> cmd = SQLiteFactory::createCommand("DROP TABLE IF EXISTS NetFiles", NetworkDB::Instance().connection());
+ cmd->execute();
+}
diff --git a/fbreader/src/migration/OEBMigrationReader.cpp b/fbreader/src/migration/OEBMigrationReader.cpp
new file mode 100644
index 0000000..735e0df
--- /dev/null
+++ b/fbreader/src/migration/OEBMigrationReader.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2004-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <ZLUnicodeUtil.h>
+#include <ZLXMLNamespace.h>
+
+#include "OEBMigrationReader.h"
+
+OEBMigrationReader::OEBMigrationReader(BookInfo &info) : myInfo(info) {
+}
+
+static const std::string METADATA = "metadata";
+static const std::string DC_METADATA = "dc-metadata";
+
+void OEBMigrationReader::characterDataHandler(const char *text, std::size_t len) {
+ if (myReadSubject) {
+ myBuffer.append(text, len);
+ }
+}
+
+bool OEBMigrationReader::testDCTag(const std::string &name, const std::string &tag) const {
+ return
+ testTag(ZLXMLNamespace::DublinCore, name, tag) ||
+ testTag(ZLXMLNamespace::DublinCoreLegacy, name, tag);
+}
+
+void OEBMigrationReader::startElementHandler(const char *tag, const char**) {
+ const std::string tagString = ZLUnicodeUtil::toLower(tag);
+ if ((METADATA == tagString) || (DC_METADATA == tagString)) {
+ myDCMetadataTag = tagString;
+ myReadMetaData = true;
+ } else if (myReadMetaData) {
+ if (testDCTag("subject", tagString)) {
+ myReadSubject = true;
+ }
+ }
+}
+
+void OEBMigrationReader::endElementHandler(const char *tag) {
+ const std::string tagString = ZLUnicodeUtil::toLower(tag);
+ if (myDCMetadataTag == tagString) {
+ interrupt();
+ } else if (myReadSubject) {
+ ZLUnicodeUtil::utf8Trim(myBuffer);
+ if (!myBuffer.empty()) {
+ if (!myTagList.empty()) {
+ myTagList += ',';
+ }
+ myTagList += myBuffer;
+ myBuffer.erase();
+ }
+ myReadSubject = false;
+ }
+}
+
+bool OEBMigrationReader::processNamespaces() const {
+ return true;
+}
+
+void OEBMigrationReader::doRead(const ZLFile &file) {
+ myReadMetaData = false;
+ myReadSubject = false;
+ readDocument(file);
+ myInfo.TagsOption.setValue(myTagList);
+}
diff --git a/fbreader/src/migration/OEBMigrationReader.h b/fbreader/src/migration/OEBMigrationReader.h
new file mode 100644
index 0000000..2ce6690
--- /dev/null
+++ b/fbreader/src/migration/OEBMigrationReader.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2004-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef __OEBMIGRATIONREADER_H__
+#define __OEBMIGRATIONREADER_H__
+
+#include <vector>
+
+#include <ZLXMLReader.h>
+
+#include "BookInfo.h"
+
+class OEBMigrationReader : public ZLXMLReader {
+
+public:
+ OEBMigrationReader(BookInfo &info);
+ void doRead(const ZLFile &file);
+
+ void startElementHandler(const char *tag, const char **attributes);
+ void endElementHandler(const char *tag);
+ void characterDataHandler(const char *text, std::size_t len);
+ bool processNamespaces() const;
+
+private:
+ bool testDCTag(const std::string &name, const std::string &tag) const;
+
+private:
+ BookInfo &myInfo;
+
+ bool myReadMetaData;
+ bool myReadSubject;
+
+ std::string myDCMetadataTag;
+ std::string myBuffer;
+ std::string myTagList;
+};
+
+#endif /* __OEBMIGRATIONREADER_H__ */
diff --git a/fbreader/src/migration/migrate.cpp b/fbreader/src/migration/migrate.cpp
new file mode 100644
index 0000000..4fefbf7
--- /dev/null
+++ b/fbreader/src/migration/migrate.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2008-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include "../options/FBCategoryKey.h"
+
+#include "Migration.h"
+#include "migrate.h"
+
+MigrationRunnable::MigrationRunnable() :
+ myVersionOption(FBCategoryKey::SYSTEM, "Version", "FBReaderVersion", "0") {
+}
+
+bool MigrationRunnable::shouldMigrate() const {
+ return
+ Migration::extractVersionInformation(myVersionOption.value()) <
+ Migration::extractVersionInformation(VERSION);
+}
+
+void MigrationRunnable::run() {
+ Migration_0_8_11().doMigration();
+ Migration_0_8_13().doMigration();
+ Migration_0_8_16().doMigration();
+ Migration_0_10_4().doMigration();
+ Migration_0_11_0().doMigration();
+ Migration_0_99_0().doMigration();
+ Migration_0_99_1().doMigration();
+
+ myVersionOption.setValue(VERSION);
+}
diff --git a/fbreader/src/migration/migrate.h b/fbreader/src/migration/migrate.h
new file mode 100644
index 0000000..e833d28
--- /dev/null
+++ b/fbreader/src/migration/migrate.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2008-2012 Geometer Plus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef __MIGRATE_H__
+#define __MIGRATE_H__
+
+#include <ZLOptions.h>
+#include <ZLRunnable.h>
+
+class MigrationRunnable : public ZLRunnable {
+
+public:
+ MigrationRunnable();
+ bool shouldMigrate() const;
+ void run();
+
+private:
+ ZLStringOption myVersionOption;
+};
+
+#endif /* __MIGRATE_H__ */