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