1919#include " docview.h"
2020#include " ../../crengine/include/crengine.h"
2121#include " ../../crengine/include/epubfmt.h"
22+ #include " ../../crengine/include/fb3fmt.h"
2223#include " ../../crengine/include/pdbfmt.h"
2324#include " ../../crengine/include/lvstream.h"
2425
3031#define XS_IMPLEMENT_SCHEME 1
3132#include < ../../crengine/include/fb2def.h>
3233#include < sys/stat.h>
34+ #include < lvopc.h>
3335
3436#if defined(__arm__) || defined(__aarch64__) || defined(__i386__) || defined(__mips__)
3537#define USE_COFFEECATCH 1
@@ -152,7 +154,7 @@ static bool GetEPUBBookProperties(const char *name, LVStreamRef stream, BookProp
152154{
153155 LVContainerRef m_arc = LVOpenArchieve ( stream );
154156 if ( m_arc.isNull () )
155- return false ; // not a ZIP archive
157+ return false ; // not a ZIP` archive
156158
157159 // check root media type
158160 lString16 rootfilePath = EpubGetRootFilePath (m_arc);
@@ -179,10 +181,22 @@ static bool GetEPUBBookProperties(const char *name, LVStreamRef stream, BookProp
179181 lString16 author = doc->textFromXPath ( lString16 (" package/metadata/creator" )).trim ();
180182 lString16 title = doc->textFromXPath ( lString16 (" package/metadata/title" )).trim ();
181183 lString16 language = doc->textFromXPath ( lString16 (" package/metadata/language" )).trim ();
184+ lString16 bookdate = doc->textFromXPath ( lString16 (" package/metadata/date" )).trim ();
185+ lString16 annotation = doc->textFromXPath ( lString16 (" package/metadata/description" )).trim ();
186+ lString16 publisher = doc->textFromXPath ( lString16 (" package/metadata/publisher" )).trim ();
187+ lString16 genre = doc->textFromXPath ( lString16 (" package/metadata/subject" )).trim ();
188+ lString16 docsrcurl = doc->textFromXPath ( lString16 (" package/metadata/identifier" )).trim ();
189+ lString16 docsrcocr = doc->textFromXPath ( lString16 (" package/metadata/source" )).trim ();
182190
183191 pBookProps->author = author;
184192 pBookProps->title = title;
185193 pBookProps->language = language;
194+ pBookProps->bookdate = bookdate;
195+ pBookProps->annotation = annotation;
196+ pBookProps->publisher = publisher;
197+ pBookProps->genre = genre;
198+ pBookProps->docsrcurl = docsrcurl;
199+ pBookProps->docsrcocr = docsrcocr;
186200
187201 for ( int i=1 ; i<20 ; i++ ) {
188202 ldomNode * item = doc->nodeFromXPath ( lString16 (" package/metadata/meta[" ) << fmt::decimal (i) << " ]" );
@@ -205,6 +219,110 @@ static bool GetEPUBBookProperties(const char *name, LVStreamRef stream, BookProp
205219 return true ;
206220}
207221
222+ static bool GetFB3BookProperties (const char *name, LVStreamRef stream, BookProperties * pBookProps)
223+ {
224+ ldomDocument * descDoc = NULL ;
225+ descDoc = Fb3GetDescDoc ( stream );
226+
227+ if ( !descDoc )
228+ return false ;
229+
230+ lString16 title = descDoc->textFromXPath ( lString16 (" title/main" ));
231+ lString16 authors;
232+ lString16 annotation = descDoc->textFromXPath ( lString16 (" annotation" ));
233+ lString16 language = descDoc->textFromXPath ( lString16 (" lang" ));
234+ lString16 translators;
235+ lString16 publishers;
236+ lString16 genres;
237+ lString16 srclang = descDoc->textFromXPath ( lString16 (" written/lang" ));
238+ lString16 bookdate = descDoc->textFromXPath ( lString16 (" written/date" ));
239+
240+ for ( int i=1 ; i<30 ; i++ ) {
241+ ldomNode * item = descDoc->nodeFromXPath (lString16 (" fb3-relations/subject[" ) << fmt::decimal (i) << " ]" );
242+ if ( !item ) break ;
243+ lString16 name = item->getAttributeValue (" link" );
244+ if (name == " author" ) {
245+ lString16 author = descDoc->textFromXPath ( lString16 (" fb3-relations/subject[" ) << fmt::decimal (i) << " ]/title/main" );
246+ if ( !authors.empty () ) {
247+ authors += " |" ;
248+ }
249+ authors += author;
250+ }
251+ if (name == " translator" ) {
252+ lString16 translator = descDoc->textFromXPath ( lString16 (" fb3-relations/subject[" ) << fmt::decimal (i) << " ]/title/main" );
253+ if ( !translators.empty () ) {
254+ translators += " | " ;
255+ }
256+ translators += translator;
257+ }
258+ if (name == " publisher" ) {
259+ lString16 publisher = descDoc->textFromXPath ( lString16 (" fb3-relations/subject[" ) << fmt::decimal (i) << " ]/title/main" );
260+ if ( !publishers.empty () ) {
261+ publishers += " | " ;
262+ }
263+ publishers += publisher;
264+ }
265+ }
266+ for ( int i=1 ; i<30 ; i++ ) {
267+ ldomNode * item = descDoc->nodeFromXPath (lString16 (" fb3-classification/subject[" ) << fmt::decimal (i) << " ]" );
268+ if ( !item ) break ;
269+ lString16 genre = descDoc->textFromXPath ( lString16 (" fb3-classification/subject[" ) << fmt::decimal (i) << " ]" );
270+ if ( !genres.empty () ) {
271+ genres += " | " ;
272+ }
273+ genres += genre;
274+ }
275+
276+ ldomNode * item = descDoc->nodeFromXPath (lString16 (" document-info" ));
277+ lString16 created = item->getAttributeValue (" created" );
278+ lString16 docprogram = item->getAttributeValue (" program-used" );
279+ lString16 docauthor = item->getAttributeValue (" editor" );
280+ lString16 docsrcurl = item->getAttributeValue (" src-url" );
281+ lString16 docsrcocr = item->getAttributeValue (" ocr" );
282+ lString16 series = descDoc->textFromXPath (lString16 (" fb3-description/sequence/title/main" ));
283+ ldomNode * item2 = descDoc->nodeFromXPath (lString16 (" paper-publish-info" ));
284+ lString16 publisher = item2->getAttributeValue (" publisher" );
285+ lString16 city = item2->getAttributeValue (" city" );
286+ lString16 year = item2->getAttributeValue (" year" );
287+ lString16 publisbn = descDoc->textFromXPath (lString16 (" paper-publish-info/isbn" ));
288+ lString16 publsequence = descDoc->textFromXPath (lString16 (" paper-publish-info/sequence" ));
289+
290+ pBookProps-> title = title;
291+ pBookProps-> author = authors;
292+ pBookProps-> annotation = annotation;
293+ pBookProps-> language = language;
294+ pBookProps-> translator = translators;
295+ pBookProps-> publisher = publishers;
296+ pBookProps-> genre = genres;
297+ pBookProps-> srclang = srclang;
298+ pBookProps-> bookdate = bookdate;
299+ pBookProps-> docdate = created;
300+ pBookProps->docprogram = docprogram;
301+ pBookProps->series = series;
302+ pBookProps->publisher = publisher;
303+ pBookProps->publcity = city;
304+ pBookProps->publyear = year;
305+ pBookProps->publisbn = publisbn;
306+ pBookProps->publseries = publsequence;
307+ pBookProps->docauthor = docauthor;
308+ pBookProps->docsrcurl = docsrcurl;
309+ pBookProps->docsrcocr = docsrcocr;
310+
311+ time_t t = (time_t )time (0 );
312+ struct stat fs;
313+ if ( !stat ( name, &fs ) ) {
314+ t = fs.st_mtime ;
315+ }
316+
317+ pBookProps->filesize = (long )stream->GetSize ();
318+ pBookProps->filename = lString16 (name);
319+ pBookProps->filedate = getDateTimeString ( t );
320+
321+ delete descDoc;
322+
323+ return true ;
324+ }
325+
208326static bool GetBookProperties (const char *name, BookProperties * pBookProps)
209327{
210328 CRLog::trace (" GetBookProperties( %s )" , name);
@@ -227,6 +345,11 @@ static bool GetBookProperties(const char *name, BookProperties * pBookProps)
227345 return GetEPUBBookProperties ( name, stream, pBookProps );
228346 }
229347
348+ if ( DetectFb3Format ( stream ) ) {
349+ CRLog::trace (" GetBookProperties() : fb3 format detected" );
350+ return GetFB3BookProperties ( name, stream, pBookProps );
351+ }
352+
230353 time_t t = (time_t )time (0 );
231354
232355 if ( isArchiveFile ) {
@@ -259,7 +382,7 @@ static bool GetBookProperties(const char *name, BookProperties * pBookProps)
259382 doc.setNameSpaceTypes ( fb2_ns_table );
260383 LVXMLParser parser ( stream, &writer );
261384 CRLog::trace ( " checking format..." );
262- if ( !parser.CheckFormat () ) {
385+ if ( !parser.CheckFormat () ) {
263386 return false ;
264387 }
265388 CRLog::trace ( " parsing..." );
0 commit comments