KFileMetaData

postscriptdscextractor.cpp
1 /*
2  SPDX-FileCopyrightText: 2018 Stefan BrĂ¼ns <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.1-or-later
5 */
6 
7 
8 #include "postscriptdscextractor.h"
9 #include "kfilemetadata_debug.h"
10 
11 #include <QFile>
12 
13 namespace KFileMetaData
14 {
15 
16 DscExtractor::DscExtractor(QObject* parent)
17  : ExtractorPlugin(parent)
18 {
19 
20 }
21 
22 QStringList DscExtractor::mimetypes() const
23 {
25  list << QStringLiteral("application/postscript")
26  << QStringLiteral("image/x-eps");
27 
28  return list;
29 }
30 
31 void DscExtractor::extract(ExtractionResult* result)
32 {
33  QFile file(result->inputUrl());
34  if (!file.open(QIODevice::ReadOnly)) {
35  qCWarning(KFILEMETADATA_LOG) << "Document is not a valid file";
36  return;
37  }
38 
39  // A little bit heuristic - assume EPS files are images, PS complete documents
40  if (result->inputMimetype() == QLatin1String("application/postscript")) {
41  result->addType(Type::Document);
42  } else {
43  result->addType(Type::Image);
44  }
45 
46  if (!(result->inputFlags() & ExtractionResult::ExtractMetaData)) {
47  return;
48  }
49  // Try to find some DSC (PostScript Language Document Structuring Conventions) conforming data
50  QTextStream stream(&file);
51  QString line;
52 
53  while (stream.readLineInto(&line)) {
54  if (!line.startsWith(QLatin1String("%%"))) {
55  continue;
56  }
57 
58  if (const auto tag = QLatin1String("%%Pages:"); line.startsWith(tag)) {
59  bool ok = false;
60 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
61  int pages = QStringView(line).mid(tag.size()).toInt(&ok, 10);
62 #else
63  int pages = line.midRef(tag.size()).toInt(&ok, 10);
64 #endif
65  if (ok) {
66  result->add(Property::PageCount, pages);
67  }
68 
69  } else if (const auto tag = QLatin1String("%%Title:"); line.startsWith(tag)) {
70  QStringView title = QStringView(line).mid(tag.size()).trimmed();
71  if (title.startsWith(QLatin1Char('(')) && title.endsWith(QLatin1Char(')'))) {
72  title = title.mid(1, title.size() - 2);
73  }
74  if (!title.isEmpty()) {
75  result->add(Property::Title, title.toString());
76  }
77 
78  } else if (const auto tag = QLatin1String("%%CreationDate:"); line.startsWith(tag)) {
79  // "Neither the date nor time need be in any standard format."
80  QStringView date = QStringView(line).mid(tag.size()).trimmed();
81  if (date.startsWith(QLatin1Char('(')) && date.endsWith(QLatin1Char(')'))) {
82  date = date.mid(1, date.size() - 2);
83  date = date.trimmed();
84  }
85  if (date.startsWith(QLatin1String("D:")) && date.size() >= 23) {
86  // Standard PDF date format, ASN.1 like - (D:YYYYMMDDHHmmSSOHH'mm')
87  auto dt = QDateTime::fromString(date.mid(2, 14).toString(), QLatin1String("yyyyMMddhhmmss"));
88  auto offset = QTime::fromString(date.mid(17, 5).toString(), QLatin1String("hh'\\''mm"));
89  if (date.at(16) == QLatin1Char('+')) {
90  dt.setOffsetFromUtc(QTime(0, 0).secsTo(offset));
91  } else {
92  dt.setOffsetFromUtc(-1 * QTime(0, 0).secsTo(offset));
93  }
94  result->add(Property::CreationDate, dt);
95  } else {
96  auto dt = QDateTime::fromString(date.toString());
97  if (dt.isValid()) {
98  result->add(Property::CreationDate, dt);
99  }
100  }
101 
102  } else if (line.startsWith(QLatin1String("%%EndComments"))) {
103  break;
104  }
105  }
106 }
107 
108 } // namespace KFileMetaData
QChar at(qsizetype n) const const
int toInt(bool *ok, int base) const const
QTime fromString(const QString &string, Qt::DateFormat format)
QStringRef midRef(int position, int n) const const
QStringView mid(qsizetype start) const const
KIOFILEWIDGETS_EXPORT QStringList list(const QString &fileClass)
qsizetype size() const const
QString toString() const const
QDateTime fromString(const QString &string, Qt::DateFormat format)
QStringView trimmed() const const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
bool endsWith(QStringView str, Qt::CaseSensitivity cs) const const
bool startsWith(QStringView str, Qt::CaseSensitivity cs) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri May 27 2022 03:47:54 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.