File indexing completed on 2024-05-19 15:11:00

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"