KFileMetaData

postscriptdscextractor.cpp
1 /*
2  Copyright (C) 2018 Stefan Brüns <[email protected]>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 
20 #include "postscriptdscextractor.h"
21 #include "kfilemetadata_debug.h"
22 
23 #include <QFile>
24 
25 namespace KFileMetaData
26 {
27 
28 DscExtractor::DscExtractor(QObject* parent)
29  : ExtractorPlugin(parent)
30 {
31 
32 }
33 
34 QStringList DscExtractor::mimetypes() const
35 {
37  list << QStringLiteral("application/postscript")
38  << QStringLiteral("image/x-eps");
39 
40  return list;
41 }
42 
43 void DscExtractor::extract(ExtractionResult* result)
44 {
45  QFile file(result->inputUrl());
46  if (!file.open(QIODevice::ReadOnly)) {
47  qCWarning(KFILEMETADATA_LOG) << "Document is not a valid file";
48  return;
49  }
50 
51  // A little bit heuristic - assume EPS files are images, PS complete documents
52  if (result->inputMimetype() == QLatin1String("application/postscript")) {
53  result->addType(Type::Document);
54  } else {
55  result->addType(Type::Image);
56  }
57 
58  if (!(result->inputFlags() & ExtractionResult::ExtractMetaData)) {
59  return;
60  }
61  // Try to find some DSC (PostScript Language Document Structuring Conventions) conforming data
62  QTextStream stream(&file);
63  QString line;
64 
65  while (stream.readLineInto(&line)) {
66  if (!line.startsWith(QLatin1String("%%"))) {
67  continue;
68  }
69 
70  if (line.startsWith(QLatin1String("%%Pages:"))) {
71  bool ok = false;
72  int pages = line.midRef(8).toInt(&ok, 10);
73  if (ok) {
74  result->add(Property::PageCount, pages);
75  }
76 
77  } else if (line.startsWith(QLatin1String("%%Title:"))) {
78  QStringRef title = line.midRef(8);
79  title = title.trimmed();
80  if (title.startsWith(QLatin1Char('(')) && title.endsWith(QLatin1Char(')'))) {
81  title = title.mid(1, title.size() - 2);
82  }
83  if (!title.isEmpty()) {
84  result->add(Property::Title, title.toString());
85  }
86 
87  } else if (line.startsWith(QLatin1String("%%CreationDate:"))) {
88  // "Neither the date nor time need be in any standard format."
89  QStringRef date = line.midRef(15);
90  date = date.trimmed();
91  if (date.startsWith(QLatin1Char('(')) && date.endsWith(QLatin1Char(')'))) {
92  date = date.mid(1, date.size() - 2);
93  date = date.trimmed();
94  }
95  if (date.startsWith(QLatin1String("D:")) && date.size() >= 23) {
96  // Standard PDF date format, ASN.1 like - (D:YYYYMMDDHHmmSSOHH'mm')
97  auto dt = QDateTime::fromString(date.mid(2, 14).toString(), QLatin1String("yyyyMMddhhmmss"));
98  auto offset = QTime::fromString(date.mid(17, 5).toString(), QLatin1String("hh'\\''mm"));
99  if (date.mid(16,1) == QLatin1String("+")) {
100  dt.setOffsetFromUtc(QTime(0, 0).secsTo(offset));
101  } else {
102  dt.setOffsetFromUtc(-1 * QTime(0, 0).secsTo(offset));
103  }
104  result->add(Property::CreationDate, dt);
105  } else {
106  auto dt = QDateTime::fromString(date.toString());
107  if (dt.isValid()) {
108  result->add(Property::CreationDate, dt);
109  }
110  }
111 
112  } else if (line.startsWith(QLatin1String("%%EndComments"))) {
113  break;
114  }
115  }
116 }
117 
118 } // namespace KFileMetaData
int toInt(bool *ok, int base) const const
int size() const const
time_t date() const
QString toString() const const
QTime fromString(const QString &string, Qt::DateFormat format)
QStringRef trimmed() const const
bool endsWith(QStringView str, Qt::CaseSensitivity cs) const const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
QDateTime fromString(const QString &string, Qt::DateFormat format)
QStringRef midRef(int position, int n) const const
bool isEmpty() const const
QStringRef mid(int position, int n) const const
bool startsWith(QStringView str, Qt::CaseSensitivity cs) const const
KIOFILEWIDGETS_EXPORT QStringList list(const QString &fileClass)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Fri Jun 5 2020 22:55:38 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.