Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[contacts] Move vcardconverter from qmlcontacts-tools
  • Loading branch information
rburchell committed Jun 14, 2013
1 parent 07aa192 commit f1be024
Show file tree
Hide file tree
Showing 10 changed files with 400 additions and 2 deletions.
2 changes: 1 addition & 1 deletion contacts.pro
@@ -1,4 +1,4 @@
TEMPLATE = subdirs
SUBDIRS = src tests
SUBDIRS = src tools tests

tests.depends = src
14 changes: 14 additions & 0 deletions rpm/nemo-qml-plugin-contacts-qt5.spec
Expand Up @@ -28,6 +28,14 @@ BuildRequires: pkgconfig(mlite5)
%description
%{summary}.

%package tools
Summary: Development tools for qmlcontacts
License: BSD
Group: Applications/System

%description tools
%{summary}.

%package tests
Summary: QML contacts plugin tests
Group: System/Libraries
Expand Down Expand Up @@ -69,6 +77,12 @@ rm -rf %{buildroot}
# >> files
# << files

%files tools
%defattr(-,root,root,-)
%{_bindir}/vcardconverter
# >> files tools
# << files tools

%files tests
%defattr(-,root,root,-)
/opt/tests/nemo-qml-plugins-qt5/contacts/*
Expand Down
9 changes: 9 additions & 0 deletions rpm/nemo-qml-plugin-contacts-qt5.yaml
Expand Up @@ -24,6 +24,15 @@ Files:
- "%{_libdir}/qt5/qml/org/nemomobile/contacts/libnemocontacts.so"
- "%{_libdir}/qt5/qml/org/nemomobile/contacts/qmldir"
SubPackages:
- Name: tools
Summary: Development tools for qmlcontacts
Description: "%{summary}."
Group: Applications/System
License: BSD
AutoDepend: false
Files:
- "%{_bindir}/vcardconverter"

- Name: tests
Summary: QML contacts plugin tests
Group: System/Libraries
Expand Down
16 changes: 15 additions & 1 deletion rpm/nemo-qml-plugin-contacts.spec
Expand Up @@ -9,7 +9,7 @@ Name: nemo-qml-plugin-contacts
# << macros

Summary: Nemo QML contacts plugin
Version: 0.0.6
Version: 0.0.0
Release: 1
Group: System/Libraries
License: BSD
Expand All @@ -27,6 +27,14 @@ Obsoletes: nemo-qml-plugins-contacts <= 0.3.26
%description
%{summary}.

%package tools
Summary: Development tools for qmlcontacts
License: BSD
Group: Applications/System

%description tools
%{summary}.

%package tests
Summary: QML contacts plugin tests
Group: System/Libraries
Expand Down Expand Up @@ -68,6 +76,12 @@ rm -rf %{buildroot}
# >> files
# << files

%files tools
%defattr(-,root,root,-)
%{_bindir}/vcardconverter
# >> files tools
# << files tools

%files tests
%defattr(-,root,root,-)
/opt/tests/nemo-qml-plugins/contacts/*
Expand Down
9 changes: 9 additions & 0 deletions rpm/nemo-qml-plugin-contacts.yaml
Expand Up @@ -24,6 +24,15 @@ Files:
- "%{_libdir}/qt4/imports/org/nemomobile/contacts/libnemocontacts.so"
- "%{_libdir}/qt4/imports/org/nemomobile/contacts/qmldir"
SubPackages:
- Name: tools
Summary: Development tools for qmlcontacts
Description: "%{summary}."
Group: Applications/System
License: BSD
AutoDepend: false
Files:
- "%{_bindir}/vcardconverter"

- Name: tests
Summary: QML contacts plugin tests
Group: System/Libraries
Expand Down
2 changes: 2 additions & 0 deletions tools/tools.pro
@@ -0,0 +1,2 @@
TEMPLATE = subdirs
SUBDIRS = vcardconverter
122 changes: 122 additions & 0 deletions tools/vcardconverter/main.cpp
@@ -0,0 +1,122 @@
/*
* Copyright (C) 2012 Robin Burchell <robin+mer@viroteck.net>
*
* You may use this file under the terms of the BSD license as follows:
*
* "Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Nemo Mobile nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
*/

// Qt
#include <QCoreApplication>
#include <QFile>
#include <QTimer>

// Contacts
#include <QContactSaveRequest>

// Versit
#include <QVersitReader>
#include <QVersitContactImporter>

// Custom Photo Handler
#include "photohandler.h"

USE_CONTACTS_NAMESPACE
USE_VERSIT_NAMESPACE

class RequestHandler : public QObject
{
Q_OBJECT
public:
RequestHandler(QObject *object)
: QObject(object) { }

void startRequest(QContactSaveRequest *request)
{
this->request = request;
QTimer::singleShot(0, this, SLOT(internalStartRequest()));
}

private slots:

void internalStartRequest()
{
connect(request, SIGNAL(stateChanged(QContactAbstractRequest::State)),
SLOT(onStateChanged(QContactAbstractRequest::State)));
request->start();
}

void onStateChanged(QContactAbstractRequest::State state)
{
if (state != QContactAbstractRequest::FinishedState)
return;

QContactSaveRequest *request = static_cast<QContactSaveRequest *>(sender());
qDebug("Saved %d contacts", request->contacts().count());
QCoreApplication::instance()->exit();
}

private:
QContactSaveRequest *request;
};

int main(int argc, char **argv)
{
QCoreApplication qca(argc, argv);
QContactSaveRequest req;

PhotoHandler photoHandler;
QVersitContactImporter importer;
importer.setPropertyHandler(&photoHandler);

for (int i = 1; i < argc; ++i) {
QFile vcf(argv[i]);
if (!vcf.open(QIODevice::ReadOnly)) {
qWarning("vcardconverter: %s cannot be opened", argv[i]);
exit(1);
}

QVersitReader reader(&vcf);
reader.startReading();
reader.waitForFinished();

importer.importDocuments(reader.results());
}

qDebug("Saving %d contacts", importer.contacts().count());

req.setManager(new QContactManager(&req));
req.setContacts(importer.contacts());
req.start();

RequestHandler *rq = new RequestHandler(QCoreApplication::instance());
rq->startRequest(&req);

return qca.exec();
}

#include "main.moc"

125 changes: 125 additions & 0 deletions tools/vcardconverter/photohandler.cpp
@@ -0,0 +1,125 @@
/*
* Copyright (C) 2013 Jolla Ltd.
* Contact: Chris Adams <chris.adams@jollamobile.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* "Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Nemo Mobile nor Jolla Ltd nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
*/

#include "photohandler.h"

#ifdef QT_VERSION_5
#include <QStandardPaths>
#else
#include <QDesktopServices>
#include <QContactThumbnail>
#endif
#include <QContactAvatar>
#include <QUuid>
#include <QDir>
#include <QImage>

USE_CONTACTS_NAMESPACE

PhotoHandler::PhotoHandler()
{
}

PhotoHandler::~PhotoHandler()
{
}

void PhotoHandler::documentProcessed(const QVersitDocument &, QContact *)
{
// do nothing, have no state to clean.
}

void PhotoHandler::propertyProcessed(const QVersitDocument &, const QVersitProperty &property, const QContact &, bool *alreadyProcessed, QList<QContactDetail> * updatedDetails)
{
// if the property is a PHOTO property, store the data to disk
// and then create an avatar detail which points to it.
if (property.name().toLower() != QLatin1String("photo"))
return;

// we will save the avatar image to disk at some generic data services location.
QString photoDirPath;

#ifndef QT_VERSION_5
// The Qt4 / QtMobility version has QContactThumbnail support.
// We need to remove any such thumbnail detail from the output,
// as some backends (such as qtcontacts-sqlite) do not support
// that detail type.
for (int i = 0; i < updatedDetails->size(); ++i) {
if (updatedDetails->at(i).definitionName() == QContactThumbnail::DefinitionName) {
updatedDetails->removeAt(i);
--i;
}
}

photoDirPath = QDesktopServices::storageLocation(QDesktopServices::HomeLocation)
+ QLatin1String("/.local/share/data/avatars/");
#else
photoDirPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
#endif

// create the photo file dir if it doesn't exist.
QDir photoDir;
if (!photoDir.mkpath(photoDirPath)) {
qWarning() << "Failed to create avatar image directory when loading avatar image from vCard PHOTO data";
return;
}

// construct the filename of the new avatar image.
QString photoFilePath = QUuid::createUuid().toString();
photoFilePath = photoFilePath.mid(1, photoFilePath.length() - 2) + QLatin1String(".jpg");
photoFilePath = photoDirPath + photoFilePath;

// save the file to disk
QImage img;
bool loaded = img.loadFromData(property.variantValue().toByteArray());
if (!loaded) {
qWarning() << "Failed to load avatar image from vCard PHOTO data";
return;
}

bool saved = img.save(photoFilePath);
if (!saved) {
qWarning() << "Failed to save avatar image from vCard PHOTO data to" << photoFilePath;
return;
}

qWarning() << "Successfully saved avatar image from vCard PHOTO data to" << photoFilePath;

// save the avatar detail - TODO: mark the avatar as "owned by the contact" (remove on delete)
QContactAvatar newAvatar;
newAvatar.setImageUrl(QUrl::fromLocalFile(photoFilePath));
updatedDetails->append(newAvatar);

// we have successfully processed this PHOTO property.
*alreadyProcessed = true;
}

0 comments on commit f1be024

Please sign in to comment.