File indexing completed on 2025-03-16 12:49:36
0001 /* 0002 SPDX-FileCopyrightText: 2018 Stefan BrĂ¼ns <stefan.bruens@rwth-aachen.de> 0003 0004 SPDX-License-Identifier: LGPL-2.1-or-later 0005 */ 0006 0007 0008 #include "postscriptdscextractor.h" 0009 #include "kfilemetadata_debug.h" 0010 0011 #include <QFile> 0012 0013 namespace KFileMetaData 0014 { 0015 0016 DscExtractor::DscExtractor(QObject* parent) 0017 : ExtractorPlugin(parent) 0018 { 0019 0020 } 0021 0022 QStringList DscExtractor::mimetypes() const 0023 { 0024 QStringList list; 0025 list << QStringLiteral("application/postscript") 0026 << QStringLiteral("image/x-eps"); 0027 0028 return list; 0029 } 0030 0031 void DscExtractor::extract(ExtractionResult* result) 0032 { 0033 QFile file(result->inputUrl()); 0034 if (!file.open(QIODevice::ReadOnly)) { 0035 qCWarning(KFILEMETADATA_LOG) << "Document is not a valid file"; 0036 return; 0037 } 0038 0039 // A little bit heuristic - assume EPS files are images, PS complete documents 0040 if (result->inputMimetype() == QLatin1String("application/postscript")) { 0041 result->addType(Type::Document); 0042 } else { 0043 result->addType(Type::Image); 0044 } 0045 0046 if (!(result->inputFlags() & ExtractionResult::ExtractMetaData)) { 0047 return; 0048 } 0049 // Try to find some DSC (PostScript Language Document Structuring Conventions) conforming data 0050 QTextStream stream(&file); 0051 QString line; 0052 0053 while (stream.readLineInto(&line)) { 0054 if (!line.startsWith(QLatin1String("%%"))) { 0055 continue; 0056 } 0057 0058 if (const auto tag = QLatin1String("%%Pages:"); line.startsWith(tag)) { 0059 bool ok = false; 0060 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 0061 int pages = QStringView(line).mid(tag.size()).toInt(&ok, 10); 0062 #else 0063 int pages = line.midRef(tag.size()).toInt(&ok, 10); 0064 #endif 0065 if (ok) { 0066 result->add(Property::PageCount, pages); 0067 } 0068 0069 } else if (const auto tag = QLatin1String("%%Title:"); line.startsWith(tag)) { 0070 QStringView title = QStringView(line).mid(tag.size()).trimmed(); 0071 if (title.startsWith(QLatin1Char('(')) && title.endsWith(QLatin1Char(')'))) { 0072 title = title.mid(1, title.size() - 2); 0073 } 0074 if (!title.isEmpty()) { 0075 result->add(Property::Title, title.toString()); 0076 } 0077 0078 } else if (const auto tag = QLatin1String("%%CreationDate:"); line.startsWith(tag)) { 0079 // "Neither the date nor time need be in any standard format." 0080 QStringView date = QStringView(line).mid(tag.size()).trimmed(); 0081 if (date.startsWith(QLatin1Char('(')) && date.endsWith(QLatin1Char(')'))) { 0082 date = date.mid(1, date.size() - 2); 0083 date = date.trimmed(); 0084 } 0085 if (date.startsWith(QLatin1String("D:")) && date.size() >= 23) { 0086 // Standard PDF date format, ASN.1 like - (D:YYYYMMDDHHmmSSOHH'mm') 0087 auto dt = QDateTime::fromString(date.mid(2, 14).toString(), QLatin1String("yyyyMMddhhmmss")); 0088 auto offset = QTime::fromString(date.mid(17, 5).toString(), QLatin1String("hh'\\''mm")); 0089 if (date.at(16) == QLatin1Char('+')) { 0090 dt.setOffsetFromUtc(QTime(0, 0).secsTo(offset)); 0091 } else { 0092 dt.setOffsetFromUtc(-1 * QTime(0, 0).secsTo(offset)); 0093 } 0094 result->add(Property::CreationDate, dt); 0095 } else { 0096 auto dt = QDateTime::fromString(date.toString()); 0097 if (dt.isValid()) { 0098 result->add(Property::CreationDate, dt); 0099 } 0100 } 0101 0102 } else if (line.startsWith(QLatin1String("%%EndComments"))) { 0103 break; 0104 } 0105 } 0106 } 0107 0108 } // namespace KFileMetaData 0109 0110 #include "moc_postscriptdscextractor.cpp"