Commit b40dec18 authored by Volker Krause's avatar Volker Krause
Browse files

Initial commit of the pkpass file support

parents
*.kdev4
*~
*.rej
*.orig
*.out
CMakeLists.txt.user
callgrind.*
heaptrack.*
*.qmlc
// kate: space-indent on; indent-width 4; remove-trailing-spaces modified;
cmake_minimum_required(VERSION 3.0)
project(itinerary VERSION 0.0.1)
find_package(ECM 5.38 REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_SOURCE_DIR}/cmake)
include(KDECompilerSettings NO_POLICY_SCOPE)
include(ECMAddTests)
include(ECMGenerateHeaders)
include(ECMQtDeclareLoggingCategory)
include(ECMSetupVersion)
include(FeatureSummary)
include(KDEInstallDirs)
include(KDECMakeSettings)
include(GenerateExportHeader)
set(CMAKE_AUTOMOC ON)
ecm_setup_version(PROJECT VARIABLE_PREFIX ITINERARY VERSION_HEADER itinerary_version.h)
find_package(Qt5 REQUIRED COMPONENTS Test Gui)
find_package(KF5 REQUIRED COMPONENTS Archive)
find_package(SharedMimeInfo 1.0 REQUIRED)
add_subdirectory(src)
add_subdirectory(autotests)
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
#!/bin/bash
find "$@" -name '*.h' -o -name '*.cpp' -o -name '*.qml' | grep -v /3rdparty/ | while read FILE; do
if grep -qiE "Copyright \(C\) [0-9, -]{4,} " "$FILE" ; then continue; fi
thisfile=`basename $FILE`
authorName=`git config user.name`
authorEmail=`git config user.email`
thisYear=`date +%Y`
cat <<EOF > "$FILE".tmp
/*
Copyright (C) $thisYear $authorName <$authorEmail>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
EOF
cat "$FILE" >> "$FILE".tmp
mv "$FILE".tmp "$FILE"
done
add_definitions(-DSOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
ecm_add_test(pkpasstest.cpp LINK_LIBRARIES Qt5::Test KPkPass)
/*
Copyright (C) 2018 Volker Krause <vkrause@kde.org>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <file.h>
#include <boardingpass.h>
#include <QLocale>
#include <QtTest/qtest.h>
class PkPassTest : public QObject
{
Q_OBJECT
private slots:
void initTestCase()
{
QLocale::setDefault(QLocale("de_DE"));
}
void testBoardingPass()
{
std::unique_ptr<KPkPass::File> file(KPkPass::File::fromFile(QLatin1String(SOURCE_DIR "/data/boardingpass.pkpass")));
QVERIFY(file);
QCOMPARE(file->logoText(), QLatin1String("Boarding Pass"));
auto headers = file->headerFields();
QCOMPARE(headers.size(), 2);
auto field = headers.at(0);
QCOMPARE(field.label(), QLatin1String("Sitzplatz"));
QCOMPARE(field.value(), QLatin1String("10E"));
auto boardingPass = dynamic_cast<KPkPass::BoardingPass*>(file.get());
QVERIFY(boardingPass);
QCOMPARE(boardingPass->transitType(), KPkPass::BoardingPass::Air);
auto barcodes = file->barcodes();
QCOMPARE(barcodes.size(), 1);
auto bc = barcodes.at(0);
QCOMPARE(bc.format(), KPkPass::Barcode::QR);
QVERIFY(!bc.message().isEmpty());
}
};
QTEST_GUILESS_MAIN(PkPassTest)
#include "pkpasstest.moc"
add_subdirectory(pkpass)
include(KDECompilerSettings NO_POLICY_SCOPE)
set(pkpass_srcs
barcode.cpp
boardingpass.cpp
field.cpp
file.cpp
)
ecm_qt_declare_logging_category(pkpass_srcs
HEADER logging.h
IDENTIFIER KPkPass::Log
CATEGORY_NAME org.kde.pkpass
)
add_library(KPkPass SHARED ${pkpass_srcs})
generate_export_header(KPkPass BASE_NAME KPkPass)
set_target_properties(KPkPass PROPERTIES
VERSION ${ITINERARY_VERSION_STRING}
SOVERSION ${ITINERARY_SOVERSION}
EXPORT_NAME KPkPass
)
target_link_libraries(KPkPass
PUBLIC
Qt5::Gui
PRIVATE
KF5::Archive
)
ecm_generate_headers(KPkPass_HEADERS
HEADER_NAMES
Barcode
BoardingPass
Field
File
PREFIX KPkPass
REQUIRED_HEADERS KPkPass_HEADERS
)
install(TARGETS KPkPass EXPORT KPkPassTargets ${INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES
${KPkPass_HEADERS}
${CMAKE_CURRENT_BINARY_DIR}/kpkpass_export.h
DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/KPkPass
)
install(FILES application-vnd-apple-pkpass.xml DESTINATION ${XDG_MIME_INSTALL_DIR})
update_xdg_mimetypes(${XDG_MIME_INSTALL_DIR})
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="application/vnd.apple.pkpass">
<sub-class-of type="application/zip"/>
<comment>Apple Wallet pass</comment>
<glob pattern="*.pkpass"/>
</mime-type>
</mime-info>
/*
Copyright (C) 2018 Volker Krause <vkrause@kde.org>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "barcode.h"
#include "file.h"
#include <QJsonObject>
using namespace KPkPass;
Barcode::Barcode()
{
}
Barcode::Barcode(const QJsonObject &obj, const File *file)
{
m_altText = file->message(obj.value(QLatin1String("altText")).toString());
const auto format = obj.value(QLatin1String("format")).toString();
if (format == QLatin1String("PKBarcodeFormatQR"))
m_format = QR;
else if (format == QLatin1String("PKBarcodeFormatPDF417"))
m_format = PDF417;
else if (format == QLatin1String("PKBarcodeFormatAztec"))
m_format = Aztec;
else if (format == QLatin1String("PKBarcodeFormatCode128"))
m_format = Code128;
m_message = obj.value(QLatin1String("message")).toString();
}
Barcode::~Barcode() = default;
QString Barcode::alternativeText() const
{
return m_altText;
}
Barcode::Format KPkPass::Barcode::format() const
{
return m_format;
}
QString Barcode::message() const
{
return m_message;
}
/*
Copyright (C) 2018 Volker Krause <vkrause@kde.org>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KPKPASS_BARCODE_H
#define KPKPASS_BARCODE_H
#include "kpkpass_export.h"
#include <QMetaType>
#include <QString>
class QJsonObject;
namespace KPkPass {
class File;
/** A pass barcode element. */
class KPKPASS_EXPORT Barcode
{
Q_GADGET
Q_PROPERTY(QString alternativeText READ alternativeText CONSTANT)
Q_PROPERTY(Format format READ format CONSTANT)
Q_PROPERTY(QString message READ message CONSTANT)
public:
enum Format {
Invalid,
QR,
PDF417,
Aztec,
Code128
};
Q_ENUM(Format)
Barcode();
~Barcode();
/** A human readable version of the barcode data. */
QString alternativeText() const;
/** The barcode type. */
Format format() const;
/** The message encoded in the barcode. */
QString message() const;
private:
friend class File;
explicit Barcode(const QJsonObject &obj, const File *file);
QString m_altText;
QString m_message;
Format m_format = Invalid;
};
}
Q_DECLARE_METATYPE(KPkPass::Barcode)
#endif // KPKPASS_BARCODE_H
/*
Copyright (c) 2017-2018 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include "boardingpass.h"
using namespace KPkPass;
BoardingPass::BoardingPass(QObject *parent)
: File(QStringLiteral("boardingPass"), parent)
{
}
BoardingPass::TransitType BoardingPass::transitType() const
{
const auto t = passData().value(QLatin1String("transitType")).toString();
if (t == QLatin1String("PKTransitTypeAir")) {
return Air;
} else if (t == QLatin1String("PKTransitTypeBoat")) {
return Boat;
} else if (t == QLatin1String("PKTransitTypeBus")) {
return Bus;
} else if (t == QLatin1String("PKTransitTypeTrain")) {
return Train;
}
return Generic;
}
/*
Copyright (c) 2017-2018 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#ifndef KPKPASS_BOARDINGPASS_H
#define KPKPASS_BOARDINGPASS_H
#include "file.h"
namespace KPkPass {
/** Boarding pass */
class KPKPASS_EXPORT BoardingPass : public File
{
Q_GADGET
Q_PROPERTY(TransitType transitType READ transitType)
public:
enum TransitType {
Air,
Boat,
Bus,
Train,
Generic
};
Q_ENUM(TransitType)
explicit BoardingPass(QObject *parent = nullptr);
~BoardingPass() = default;
TransitType transitType() const;
};
}
#endif // KPKPASS_BOARDINGPASS_H
/*
Copyright (c) 2017-2018 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include "field.h"
#include "file.h"
#include <QJsonObject>
using namespace KPkPass;
Field::Field(const QJsonObject &obj, const File *file)
{
m_label = file->message(obj.value(QLatin1String("label")).toString());
m_value = file->message(obj.value(QLatin1String("value")).toString());
}
QString Field::label() const
{
return m_label;
}
QString Field::value() const
{
return m_value;
}
/*
Copyright (c) 2017-2018 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#ifndef KPKPASS_FIELD_H
#define KPKPASS_FIELD_H
#include "kpkpass_export.h"
#include <QMetaType>
#include <QString>
class QJsonObject;
namespace KPkPass {
class File;
/** Field element in a KPkPass::File. */
class KPKPASS_EXPORT Field
{
Q_GADGET
Q_PROPERTY(QString label READ label CONSTANT)
Q_PROPERTY(QString value READ value CONSTANT)
public:
Field() = default;
explicit Field(const QJsonObject &obj, const File *file);
~Field() = default;
QString label() const;
QString value() const;
private:
QString m_label;
QString m_value;
};
}
Q_DECLARE_METATYPE(KPkPass::Field)
#endif // KPKPASS_FIELD_H
/*
Copyright (c) 2017-2018 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include "file.h"
#include "boardingpass.h"
#include "logging.h"
#include <KZip>
#include <QBuffer>
#include <QColor>
#include <QFile>
#include <QImage>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QLocale>
#include <QTextCodec>
#include <QImage>
using namespace KPkPass;
File::File(const QString &passType, QObject *parent)
: QObject(parent)
, m_passType(passType)
{
}
File::~File() = default;
QJsonObject File::data() const
{
return m_passObj;
}
QJsonObject File::passData() const
{
return m_passObj.value(m_passType).toObject();
}
QString File::message(const QString &key) const
{
const auto it = m_messages.constFind(key);
if (it != m_messages.constEnd()) {
return it.value();
}
return key;
}
QString File::passTypeIdentifier() const
{
return m_passObj.value(QLatin1String("passTypeIdentifier")).toString();
}
QString File::serialNumber() const
{
return m_passObj.value(QLatin1String("serialNumber")).toString();
}
static QColor parseColor(const QString &s)
{
if (s.startsWith(QLatin1String("rgb("), Qt::CaseInsensitive)) {
const auto l = s.midRef(4, s.length() - 5).split(QLatin1Char(','));
if (l.size() != 3)
return {};
return QColor(l[0].trimmed().toInt(), l[1].trimmed().toInt(), l[2].trimmed().toInt());
}
return QColor(s);
}
QColor File::backgroundColor() const
{
return parseColor(m_passObj.value(QLatin1String("backgroundColor")).toString());
}
QColor File::foregroundColor() const
{
return parseColor(m_passObj.value(QLatin1String("foregroundColor")).toString());
}
QColor File::labelColor() const
{
const auto c = parseColor(m_passObj.value(QLatin1String("labelColor")).toString());
if (c.isValid()) {
return c;
}
return foregroundColor();
}