2 * Copyright (C) 2004-2008 Geometer Plus <contact@geometerplus.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 #include <ZLOptions.h>
22 #include <ZLUnicodeUtil.h>
23 #include <ZLStringUtil.h>
25 #include "BookDescription.h"
26 #include "BookDescriptionUtil.h"
29 #include "../formats/FormatPlugin.h"
30 #include "../options/FBOptions.h"
32 std::map
<std::string
,BookDescriptionPtr
> BookDescription::ourDescriptions
;
34 static const std::string EMPTY
= "";
36 BookInfo::BookInfo(const std::string
&fileName
) :
37 AuthorDisplayNameOption(FBCategoryKey::BOOKS
, fileName
, "AuthorDisplayName", EMPTY
),
38 AuthorSortKeyOption(FBCategoryKey::BOOKS
, fileName
, "AuthorSortKey", EMPTY
),
39 TitleOption(FBCategoryKey::BOOKS
, fileName
, "Title", EMPTY
),
40 SequenceNameOption(FBCategoryKey::BOOKS
, fileName
, "Sequence", EMPTY
),
41 NumberInSequenceOption(FBCategoryKey::BOOKS
, fileName
, "Number in seq", 0, 100, 0),
42 LanguageOption(FBCategoryKey::BOOKS
, fileName
, "Language", PluginCollection::instance().DefaultLanguageOption
.value()),
43 EncodingOption(FBCategoryKey::BOOKS
, fileName
, "Encoding", EMPTY
),
44 IsSequenceDefinedOption(FBCategoryKey::BOOKS
, fileName
, "SequenceDefined", ZLFile(fileName
).extension() != "fb2") {
45 // this is just hack for compatibility with versions < 0.8.8
46 std::string language
= LanguageOption
.value();
48 LanguageOption
.setValue(PluginCollection::instance().DefaultLanguageOption
.value());
49 } else if (language
== "cz") {
50 LanguageOption
.setValue("cs");
51 } else if (language
== "none") {
52 LanguageOption
.setValue("other");
53 } else if ((language
== "chinese") || (language
== "anycharacter")) {
54 LanguageOption
.setValue("zh");
58 void BookInfo::reset() {
59 AuthorDisplayNameOption
.setValue(EMPTY
);
60 AuthorSortKeyOption
.setValue(EMPTY
);
61 TitleOption
.setValue(EMPTY
);
62 SequenceNameOption
.setValue(EMPTY
);
63 NumberInSequenceOption
.setValue(0);
64 LanguageOption
.setValue(PluginCollection::instance().DefaultLanguageOption
.value());
65 EncodingOption
.setValue(EMPTY
);
68 bool BookInfo::isFull() const {
70 !AuthorDisplayNameOption
.value().empty() &&
71 !AuthorSortKeyOption
.value().empty() &&
72 !TitleOption
.value().empty() &&
73 !EncodingOption
.value().empty() &&
74 IsSequenceDefinedOption
.value();
77 BookDescriptionPtr
BookDescription::getDescription(const std::string
&fileName
, bool checkFile
) {
78 const std::string physicalFileName
= ZLFile(fileName
).physicalFilePath();
79 ZLFile
file(physicalFileName
);
80 if (checkFile
&& !file
.exists()) {
84 BookDescriptionPtr description
= ourDescriptions
[fileName
];
85 if (description
.isNull()) {
86 description
= new BookDescription(fileName
);
87 ourDescriptions
[fileName
] = description
;
90 if (!checkFile
|| BookDescriptionUtil::checkInfo(file
)) {
91 BookInfo
info(fileName
);
92 description
->myAuthor
= SingleAuthor::create(info
.AuthorDisplayNameOption
.value(), info
.AuthorSortKeyOption
.value());
93 description
->myTitle
= info
.TitleOption
.value();
94 description
->mySequenceName
= info
.SequenceNameOption
.value();
95 description
->myNumberInSequence
= info
.NumberInSequenceOption
.value();
96 description
->myLanguage
= info
.LanguageOption
.value();
97 description
->myEncoding
= info
.EncodingOption
.value();
102 if (physicalFileName
!= fileName
) {
103 BookDescriptionUtil::resetZipInfo(file
);
105 BookDescriptionUtil::saveInfo(file
);
108 ZLFile
bookFile(fileName
);
109 FormatPlugin
*plugin
= PluginCollection::instance().plugin(bookFile
, false);
110 if ((plugin
== 0) || !plugin
->readDescription(fileName
, *description
)) {
114 if (description
->myTitle
.empty()) {
115 description
->myTitle
= ZLFile::fileNameToUtf8(bookFile
.name(true));
117 AuthorPtr author
= description
->myAuthor
;
118 if (author
.isNull() || author
->displayName().empty()) {
119 description
->myAuthor
= SingleAuthor::create();
121 if (description
->myEncoding
.empty()) {
122 description
->myEncoding
= "auto";
124 if (description
->myLanguage
.empty()) {
125 description
->myLanguage
= PluginCollection::instance().DefaultLanguageOption
.value();
128 BookInfo
info(fileName
);
129 info
.AuthorDisplayNameOption
.setValue(description
->myAuthor
->displayName());
130 info
.AuthorSortKeyOption
.setValue(description
->myAuthor
->sortKey());
131 info
.TitleOption
.setValue(description
->myTitle
);
132 info
.SequenceNameOption
.setValue(description
->mySequenceName
);
133 info
.NumberInSequenceOption
.setValue(description
->myNumberInSequence
);
134 info
.LanguageOption
.setValue(description
->myLanguage
);
135 info
.EncodingOption
.setValue(description
->myEncoding
);
136 info
.IsSequenceDefinedOption
.setValue(true);
141 BookDescription::BookDescription(const std::string
&fileName
) {
142 myFileName
= fileName
;
144 myNumberInSequence
= 0;
147 void WritableBookDescription::clearAuthor() {
148 myDescription
.myAuthor
= 0;
151 void WritableBookDescription::addAuthor(const std::string
&name
, const std::string
&sortKey
) {
152 std::string strippedName
= name
;
153 ZLStringUtil::stripWhiteSpaces(strippedName
);
154 if (strippedName
.empty()) {
158 std::string strippedKey
= sortKey
;
159 ZLStringUtil::stripWhiteSpaces(strippedKey
);
160 if (strippedKey
.empty()) {
161 int index
= strippedName
.rfind(' ');
163 strippedKey
= strippedName
;
165 strippedKey
= strippedName
.substr(index
+ 1);
166 while ((index
>= 0) && (strippedName
[index
] == ' ')) {
169 strippedName
= strippedName
.substr(0, index
+ 1) + ' ' + strippedKey
;
172 AuthorPtr author
= SingleAuthor::create(strippedName
, ZLUnicodeUtil::toLower(strippedKey
));
173 if (myDescription
.myAuthor
.isNull()) {
174 myDescription
.myAuthor
= author
;
176 if (myDescription
.myAuthor
->isSingle()) {
177 myDescription
.myAuthor
= MultiAuthor::create(myDescription
.myAuthor
);
179 ((MultiAuthor
&)*myDescription
.myAuthor
).addAuthor(author
);