/* This file is part of the KDE project * Copyright (C) 2001, 2002 Rolf Magnus * Copyright (C) 2007 Matthias Lechner * * 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 version 2. * * 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; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #define STRIGI_IMPORT_API #include #include #include #include #include // poppler includes #include #include #include #include #include using namespace Strigi; using namespace std; class PDFThroughAnalyzerFactory; class PDFThroughAnalyzer : public StreamThroughAnalyzer { private: const PDFThroughAnalyzerFactory* factory; AnalysisResult* idx; void setIndexable( AnalysisResult *i ) { idx = i; } jstreams::InputStream* connectInputStream( jstreams::InputStream *in ); bool isReadyWithStream() { return true; } PDFDoc *m_pdfDocument; std::string info( const std::string& key ); public: PDFThroughAnalyzer( const PDFThroughAnalyzerFactory* f ) : factory( f ) {} }; class PDFThroughAnalyzerFactory : public StreamThroughAnalyzerFactory { private: const char* getName() const { return "PDFThroughAnalyzer"; } StreamThroughAnalyzer* newInstance() const { return new PDFThroughAnalyzer(this); } void registerFields( FieldRegister& ); static const cnstr titleFieldName; static const cnstr subjectFieldName; static const cnstr authorFieldName; static const cnstr keywordsFieldName; static const cnstr creatorFieldName; static const cnstr producerFieldName; static const cnstr creationDateFieldName; static const cnstr modificationDateFieldName; static const cnstr pagesFieldName; static const cnstr protectedFieldName; static const cnstr linearizedFieldName; static const cnstr versionFieldName; public: const RegisteredField* titleField; const RegisteredField* subjectField; const RegisteredField* authorField; const RegisteredField* keywordsField; const RegisteredField* creatorField; const RegisteredField* producerField; const RegisteredField* creationDateField; const RegisteredField* modificationDateField; const RegisteredField* pagesField; const RegisteredField* protectedField; const RegisteredField* linearizedField; const RegisteredField* versionField; }; const cnstr PDFThroughAnalyzerFactory::titleFieldName( "title" ); const cnstr PDFThroughAnalyzerFactory::subjectFieldName( "subject" ); const cnstr PDFThroughAnalyzerFactory::authorFieldName( "author" ); const cnstr PDFThroughAnalyzerFactory::keywordsFieldName( "keywords" ); const cnstr PDFThroughAnalyzerFactory::creatorFieldName( "creator" ); const cnstr PDFThroughAnalyzerFactory::producerFieldName( "producer" ); const cnstr PDFThroughAnalyzerFactory::creationDateFieldName( "creationdate" ); const cnstr PDFThroughAnalyzerFactory::modificationDateFieldName( "modificationdate" ); const cnstr PDFThroughAnalyzerFactory::pagesFieldName( "pages" ); const cnstr PDFThroughAnalyzerFactory::protectedFieldName( "protected" ); const cnstr PDFThroughAnalyzerFactory::linearizedFieldName( "linearized" ); const cnstr PDFThroughAnalyzerFactory::versionFieldName( "version" ); void PDFThroughAnalyzerFactory::registerFields( FieldRegister& reg ) { titleField = reg.registerField( titleFieldName, FieldRegister::stringType, 1, 0 ); subjectField = reg.registerField( subjectFieldName, FieldRegister::stringType, 1, 0 ); authorField = reg.registerField( authorFieldName, FieldRegister::stringType, 1, 0 ); keywordsField = reg.registerField( keywordsFieldName, FieldRegister::stringType, 1, 0 ); creatorField = reg.registerField( creatorFieldName, FieldRegister::stringType, 1, 0 ); producerField = reg.registerField( producerFieldName, FieldRegister::stringType, 1, 0 ); creationDateField = reg.registerField( creationDateFieldName, FieldRegister::integerType, 1, 0 ); modificationDateField = reg.registerField( modificationDateFieldName, FieldRegister::integerType, 1, 0 ); pagesField = reg.registerField( pagesFieldName, FieldRegister::integerType, 1, 0 ); protectedField = reg.registerField( protectedFieldName, FieldRegister::stringType, 1, 0 ); linearizedField = reg.registerField( linearizedFieldName, FieldRegister::stringType, 1, 0 ); versionField = reg.registerField( versionFieldName, FieldRegister::stringType, 1, 0 ); } jstreams::InputStream* PDFThroughAnalyzer::connectInputStream( jstreams::InputStream* in ) { // load document m_pdfDocument = new PDFDoc( new GooString( idx->path().c_str() ) ); if( !(m_pdfDocument->isOk() || m_pdfDocument->getErrorCode() == errEncrypted) ) { // could not open pdf document delete m_pdfDocument; return in; } QString enc; if( m_pdfDocument->isEncrypted() ) { enc = i18n( "Yes (Can Print:%1 Can Copy:%2 Can Change:%3 Can Add notes:%4)", m_pdfDocument->okToPrint() ? i18n("Yes") : i18n("No"), m_pdfDocument->okToCopy() ? i18n("Yes") : i18n("No"), m_pdfDocument->okToChange() ? i18n("Yes") : i18n("No"), m_pdfDocument->okToAddNotes() ? i18n("Yes") : i18n("No")); } else enc = i18n( "No" ); idx->setField( factory->protectedField, (const char*) enc.toUtf8() ); idx->setField( factory->titleField, info( "Title" ) ); idx->setField( factory->subjectField, info( "Subject" ) ); idx->setField( factory->authorField, info( "Author" ) ); idx->setField( factory->keywordsField, info( "Keywords" ) ); idx->setField( factory->creatorField, info( "Creator" ) ); idx->setField( factory->producerField, info( "Producer" ) ); idx->setField( factory->creationDateField, info( "CreationDate" ) ); idx->setField( factory->modificationDateField, info( "ModDate") ); idx->setField( factory->pagesField, m_pdfDocument->getNumPages() ); QString linearized; if( m_pdfDocument->isLinearized() ) linearized = i18n( "Yes" ); else linearized = i18n( "No" ); idx->setField( factory->linearizedField, (const char*) linearized.toUtf8() ); idx->setField( factory->versionField, m_pdfDocument->getPDFVersion() ); return in; } std::string PDFThroughAnalyzer::info( const std::string& key ) { Object info; m_pdfDocument->getDocInfo( &info ); if ( !info.isDict() ) return std::string(); Object obj; Dict *infoDict = info.getDict(); std::string result; if ( infoDict->lookup( key.c_str(), &obj )->isString() ) { UGooString gooInformation( *obj.getString() ); result = std::string( gooInformation.getCString() ); obj.free(); info.free(); return result; } return std::string(); } class Factory : public AnalyzerFactoryFactory { public: list getStreamThroughAnalyzerFactories() const { list af; af.push_back(new PDFThroughAnalyzerFactory()); return af; } }; STRIGI_ANALYZER_FACTORY(Factory)