Package: tellico
Version: 2.3.5+dfsg.1-4
Severity: wishlist
Tags: patch
Dear Maintainer,
*** Please consider answering these questions, where appropriate ***
* What led up to the situation?
* What exactly did you do (or not do) that was effective (or
ineffective)?
* What was the outcome of this action?
* What outcome did you expect instead?
*** End of the template - remove these lines ***
-- System Information:
Debian Release: 7.1
APT prefers stable
APT policy: (500, 'stable')
Architecture: i386 (i686)
Kernel: Linux 3.2.0-4-686-pae (SMP w/1 CPU core)
Locale: LANG=fr_FR.UTF8, LC_CTYPE=fr_FR.UTF8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Versions of packages tellico depends on:
ii kde-runtime 4:4.8.4-2
ii libc6 2.13-38
ii libexempi3 2.2.0-1
ii libgcc1 1:4.7.2-5
ii libkabc4 4:4.8.4-2
ii libkcal4 4:4.8.4-2
ii libkcddb4 4:4.8.4-2
ii libkdecore5 4:4.8.4-4
ii libkdeui5 4:4.8.4-4
ii libkhtml5 4:4.8.4-4
ii libkio5 4:4.8.4-4
ii libknewstuff3-4 4:4.8.4-4
ii libkparts4 4:4.8.4-4
ii libkresources4 4:4.8.4-2
ii libksane0 4:4.8.4-1
ii libkxmlrpcclient4 4:4.8.4-2
ii libnepomuk4 4:4.8.4-4
ii libpoppler-qt4-3 0.18.4-6
ii libqimageblitz4 1:0.0.6-4
ii libqjson0 0.7.1-7
ii libqt4-dbus 4:4.8.2+dfsg-11
ii libqt4-xml 4:4.8.2+dfsg-11
ii libqtcore4 4:4.8.2+dfsg-11
ii libqtgui4 4:4.8.2+dfsg-11
ii libsolid4 4:4.8.4-4
ii libstdc++6 4.7.2-5
ii libtag1c2a 1.7.2-1
ii libxml2 2.8.0+dfsg1-7+nmu1
ii libxslt1.1 1.1.26-14.1
ii libyaz4 4.2.30-2
ii tellico-data 2.3.5+dfsg.1-4
ii tellico-scripts 2.3.5+dfsg.1-4
Versions of packages tellico recommends:
ii khelpcenter4 4:4.8.4-2
tellico suggests no packages.
-- no debconf information
Although kdepimlibs is an optional dependency, tellico does not compile without
kdepimlibs5-dev. This is a knwown error and a patch is proposed by the
upstream. I have slightly modified the patch, and I can generate the debian
package without the kdepimlibs dependancy
Description: <short summary of the patch>
TODO: Put a short summary on the line above and replace this paragraph
with a longer explanation of this change. Complete the meta-information
with other relevant fields (see below for details). To make it easier, the
information below has been extracted from the changelog. Adjust it or drop
it.
.
tellico (2.3.5+dfsg.1-4) unstable; urgency=low
.
* Fix passing of hardening flags. Thanks Simon Ruderich. Closes: #669190.
Author: Regis Boudin <[email protected]>
Bug-Debian: http://bugs.debian.org/669190
---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:
Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: http://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: <YYYY-MM-DD>
--- tellico-2.3.5+dfsg.1.orig/src/fetch/CMakeLists.txt
+++ tellico-2.3.5+dfsg.1/src/fetch/CMakeLists.txt
@@ -55,7 +55,14 @@ TARGET_LINK_LIBRARIES(fetch
btparse
)
-TARGET_LINK_LIBRARIES(fetch ${KDEPIMLIBS_KXMLRPCCLIENT_LIBS})
+# Versions of KDE prior to 4.7 have a character encoding bug in libkxmlrpc
+# Use internal version of libkxmlrpc if so
+IF (KDEPIMLIBS_FOUND AND ${KDE_VERSION} VERSION_GREATER "4.6.99")
+ TARGET_LINK_LIBRARIES(fetch ${KDEPIMLIBS_KXMLRPCCLIENT_LIBS})
+ELSE (KDEPIMLIBS_FOUND AND ${KDE_VERSION} VERSION_GREATER "4.6.99")
+ ADD_SUBDIRECTORY(xmlrpc)
+ TARGET_LINK_LIBRARIES(fetch xmlrpc)
+ENDIF (KDEPIMLIBS_FOUND AND ${KDE_VERSION} VERSION_GREATER "4.6.99")
IF( YAZ_FOUND )
TARGET_LINK_LIBRARIES(fetch ${YAZ_LIBRARIES})
@@ -68,3 +75,4 @@ ENDIF( QJSON_FOUND )
########### install files ###############
INSTALL(FILES z3950-servers.cfg DESTINATION ${TELLICO_DATA_INSTALL_DIR} )
+
--- tellico-2.3.5+dfsg.1.orig/src/fetch/moviemeterfetcher.cpp
+++ tellico-2.3.5+dfsg.1/src/fetch/moviemeterfetcher.cpp
@@ -22,7 +22,7 @@
* *
***************************************************************************/
-#include <config.h>
+#include "config.h"
#include "moviemeterfetcher.h"
#include "../collections/videocollection.h"
#include "../images/imagefactory.h"
@@ -40,7 +40,15 @@
#include <QGridLayout>
#include <QTextCodec>
+// we use an internal copy of kxmlrpc for versions before 4.7
+// since it doesn't handle character encoding correctly
+// see https://git.reviewboard.kde.org/r/101838/
+#include <kdeversion.h>
+#if defined(HAVE_KXMLRPC) && KDE_IS_VERSION(4,7,0)
#include <kxmlrpcclient/client.h>
+#else
+#include "xmlrpc/client.h"
+#endif
namespace {
static const char* MOVIEMETER_API_KEY = "t80a06uf736d0yd00jpynpdsgea255yk";
@@ -371,3 +379,4 @@ QString MovieMeterFetcher::ConfigWidget:
}
#include "moviemeterfetcher.moc"
+
--- /dev/null
+++ tellico-2.3.5+dfsg.1/src/fetch/xmlrpc/query.h
@@ -0,0 +1,103 @@
+/******************************************************************************
+ * Copyright (C) 2003 - 2004 by Frerich Raabe <[email protected]> *
+ * Tobias Koenig <[email protected]> *
+ * Copyright (C) 2006 by Narayan Newton <[email protected]> *
+ * *
+ * 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. For licensing and distribution *
+ * details, check the accompanying file 'COPYING.BSD'. *
+ *****************************************************************************/
+/**
+ @file
+
+ This file is part of KXmlRpc and defines our internal classes.
+
+ @author Frerich Raabe <[email protected]>
+ @author Tobias Koenig <[email protected]>
+ @author Narayan Newton <[email protected]>
+*/
+
+#ifndef KXML_RPC_QUERY_H
+#define KXML_RPC_QUERY_H
+
+#undef QT_NO_CAST_FROM_ASCII
+
+#include <QtCore/QList>
+#include <QtCore/QObject>
+#include <QtCore/QVariant>
+#include <QtCore/QMap>
+#include <kio/job.h>
+
+class QString;
+
+/** Namespace for XmlRpc related classes */
+namespace KXmlRpc {
+
+/**
+ @brief
+ Query is a class that represents an individual XML-RPC call.
+
+ This is an internal class and is only used by the KXmlRpc::Client class.
+ @internal
+ */
+class Query : public QObject
+{
+ friend class Result;
+ Q_OBJECT
+
+ public:
+ /**
+ Constructs a query.
+
+ @param id an optional id for the query.
+ @param parent an optional parent for the query.
+ */
+ static Query *create( const QVariant &id = QVariant(), QObject *parent = 0 );
+
+ public Q_SLOTS:
+ /**
+ Calls the specified method on the specified server with
+ the given argument list.
+
+ @param server the server to contact.
+ @param method the method to call.
+ @param args an argument list to pass to said method.
+ @param jobMetaData additional arguments to pass to the KIO::Job.
+ */
+ void call( const QString &server, const QString &method,
+ const QList<QVariant> &args,
+ const QMap<QString, QString> &jobMetaData );
+
+ Q_SIGNALS:
+ /**
+ A signal sent when we receive a result from the server.
+ */
+ void message( const QList<QVariant> &result, const QVariant &id );
+
+ /**
+ A signal sent when we receive an error from the server.
+ */
+ void fault( int, const QString &, const QVariant &id );
+
+ /**
+ A signal sent when a query finishes.
+ */
+ void finished( Query * );
+
+ private:
+ explicit Query( const QVariant &id, QObject *parent = 0 );
+ ~Query();
+
+ class Private;
+ Private *const d;
+
+ Q_PRIVATE_SLOT( d, void slotData( KIO::Job *, const QByteArray & ) )
+ Q_PRIVATE_SLOT( d, void slotResult( KJob * ) )
+};
+
+} // namespace XmlRpc
+
+#endif
+
+
--- /dev/null
+++ tellico-2.3.5+dfsg.1/src/fetch/xmlrpc/client.cpp
@@ -0,0 +1,223 @@
+/*****************************************************************************
+ * Copyright (C) 2003 - 2004 by Frerich Raabe <[email protected]> *
+ * Tobias Koenig <[email protected]> *
+ * Copyright (C) 2006 by Narayan Newton <[email protected]> *
+ * *
+ * 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. For licensing and distribution *
+ * details, check the accompanying file 'COPYING.BSD'. *
+ *****************************************************************************/
+/**
+ @file
+ This file is part of the API for accessing XML-RPC Servers
+ and defines the Client class.
+
+ @brief
+ Defines the Client class.
+
+ @author Frerich Raabe <[email protected]>
+ @author Tobias Koenig <[email protected]>
+ @author Narayan Newton <[email protected]>
+*/
+
+#include "client.h"
+#include "query.h"
+
+#include <kio/job.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kurl.h>
+
+#include <QtCore/QVariant>
+
+using namespace KXmlRpc;
+
+class Client::Private
+{
+ public:
+ Private() : mUserAgent( "KDE XMLRPC resources" ), mDigestAuth( false ){}
+
+ void queryFinished( Query * );
+
+ KUrl mUrl;
+ QString mUserAgent;
+ bool mDigestAuth;
+ QList<Query*> mPendingQueries;
+};
+
+void Client::Private::queryFinished( Query *query )
+{
+ mPendingQueries.removeAll( query );
+ query->deleteLater();
+}
+
+Client::Client( QObject *parent )
+ : QObject( parent ), d( new Private )
+{
+}
+
+Client::Client( const KUrl &url, QObject *parent )
+ : QObject( parent ), d( new Private )
+{
+ d->mUrl = url;
+}
+
+Client::~Client()
+{
+ QList<Query *>::Iterator it;
+ for ( it = d->mPendingQueries.begin(); it != d->mPendingQueries.end(); ++it ) {
+ (*it)->deleteLater();
+ }
+
+ d->mPendingQueries.clear();
+
+ delete d;
+}
+
+void Client::setUrl( const KUrl &url )
+{
+ d->mUrl = url.isValid() ? url : KUrl();
+}
+
+KUrl Client::url() const
+{
+ return d->mUrl;
+}
+
+QString Client::userAgent() const
+{
+ return d->mUserAgent;
+}
+
+void Client::setUserAgent( const QString &userAgent )
+{
+ d->mUserAgent = userAgent;
+}
+
+bool Client::isDigestAuthEnabled() const
+{
+ return d->mDigestAuth;
+}
+
+void Client::setDigestAuthEnabled( bool enabled )
+{
+ d->mDigestAuth = enabled;
+}
+
+void Client::call( const QString &method, const QList<QVariant> &args,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot, const QVariant &id )
+{
+
+ QMap<QString, QString> metaData;
+
+ if ( d->mUrl.isEmpty() ) {
+ kWarning() << "Cannot execute call to" << method << ": empty server URL";
+ }
+
+ //Fill metadata, with userAgent and possible digest auth
+ if ( d->mUserAgent.isEmpty() ) {
+ metaData["UserAgent"] = "KDE-XMLRPC";
+ } else {
+ metaData["UserAgent"] = d->mUserAgent;
+ }
+
+ if ( d->mDigestAuth ) {
+ metaData["WWW-Authenticate:"] = "Digest";
+ }
+
+ Query *query = Query::create( id, this );
+ connect( query, SIGNAL(message(const QList<QVariant> &,const QVariant &)), msgObj, messageSlot );
+ connect( query, SIGNAL(fault(int,const QString &,const QVariant &)), faultObj, faultSlot );
+ connect( query, SIGNAL(finished(Query *)), this, SLOT(queryFinished(Query *)) );
+ d->mPendingQueries.append( query );
+
+ query->call( d->mUrl.url(), method, args, metaData );
+}
+
+void Client::call( const QString &method, const QVariant &arg,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot,
+ const QVariant &id )
+{
+ QList<QVariant> args;
+ args << arg ;
+ call( method, args, msgObj, messageSlot, faultObj, faultSlot, id );
+}
+
+void Client::call( const QString &method, int arg,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot,
+ const QVariant &id )
+{
+ QList<QVariant> args;
+ args << QVariant( arg );
+ call( method, args, msgObj, messageSlot, faultObj, faultSlot, id );
+}
+
+void Client::call( const QString &method, bool arg,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot,
+ const QVariant &id )
+{
+ QList<QVariant> args;
+ args << QVariant( arg );
+ call( method, args, msgObj, messageSlot, faultObj, faultSlot, id );
+}
+
+void Client::call( const QString &method, double arg,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot,
+ const QVariant &id )
+{
+ QList<QVariant> args;
+ args << QVariant( arg );
+ call( method, args, msgObj, messageSlot, faultObj, faultSlot, id );
+}
+
+void Client::call( const QString &method, const QString &arg,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot,
+ const QVariant &id )
+{
+ QList<QVariant> args;
+ args << QVariant( arg );
+ call( method, args, msgObj, messageSlot, faultObj, faultSlot, id );
+}
+
+void Client::call( const QString &method, const QByteArray &arg,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot,
+ const QVariant &id )
+{
+ QList<QVariant> args;
+ args << QVariant( arg );
+ call( method, args, faultObj, faultSlot, msgObj, messageSlot, id );
+}
+
+void Client::call( const QString &method, const QDateTime &arg,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot,
+ const QVariant &id )
+{
+ QList<QVariant> args;
+ args << QVariant( arg );
+ call( method, args, msgObj, messageSlot, faultObj, faultSlot, id );
+}
+
+void Client::call( const QString &method, const QStringList &arg,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot,
+ const QVariant &id )
+{
+ QList<QVariant> args;
+ for ( int i = 0; i < arg.count(); ++i ) {
+ args << QVariant( arg[ i ] );
+ }
+
+ call( method, args, msgObj, messageSlot, faultObj, faultSlot, id );
+}
+
+#include "client.moc"
+
--- /dev/null
+++ tellico-2.3.5+dfsg.1/src/fetch/xmlrpc/CMakeLists.txt
@@ -0,0 +1,9 @@
+########### next target ###############
+
+SET(xmlrpc_STAT_SRCS
+ query.cpp
+ client.cpp
+ )
+
+KDE4_ADD_LIBRARY(xmlrpc STATIC ${xmlrpc_STAT_SRCS})
+
--- /dev/null
+++ tellico-2.3.5+dfsg.1/src/fetch/xmlrpc/query.cpp
@@ -0,0 +1,454 @@
+/******************************************************************************
+ * Copyright (C) 2003 - 2004 by Frerich Raabe <[email protected]> *
+ * Tobias Koenig <[email protected]> *
+ * Copyright (C) 2006 by Narayan Newton <[email protected]> *
+ * *
+ * 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. For licensing and distribution *
+ * details, check the accompanying file 'COPYING.BSD'. *
+ *****************************************************************************/
+/**
+ @file
+
+ This file is part of KXmlRpc and defines our internal classes.
+
+ @author Frerich Raabe <[email protected]>
+ @author Tobias Koenig <[email protected]>
+ @author Narayan Newton <[email protected]>
+*/
+
+#include "query.h"
+
+#include <kdebug.h>
+#include <klocale.h>
+
+#include <QtCore/QDateTime>
+#include <QtCore/QVariant>
+#include <QtXml/QDomDocument>
+
+
+using namespace KXmlRpc;
+
+/**
+ @file
+
+ Implementation of Query
+**/
+
+namespace KXmlRpc {
+
+/**
+ @brief
+ Result is an internal class that represents a response
+ from a XML-RPC server.
+
+ This is an internal class and is only used by Query.
+ @internal
+ */
+class Result
+{
+ friend class Query;
+ friend class Query::Private;
+
+ public:
+ /**
+ Constructs a result.
+ */
+ Result();
+
+ /**
+ Destroys a result.
+ */
+ ~Result();
+
+ /**
+ Returns true if the method call succeeded, false
+ if there was an XML-RPC fault.
+
+ @see errorCode(), errorString()
+ */
+ bool success() const;
+
+ /**
+ Returns the error code of the fault.
+
+ @see success(), errorString()
+ */
+ int errorCode() const;
+
+ /**
+ Returns the error string that describes the fault.
+
+ @see success, errorCode()
+ */
+ QString errorString() const;
+
+ /**
+ Returns the data sent to us from the server.
+ */
+ QList<QVariant> data() const;
+
+ private:
+ bool mSuccess;
+ int mErrorCode;
+ QString mErrorString;
+ QList<QVariant> mData;
+};
+
+} // namespace KXmlRpcClient
+
+KXmlRpc::Result::Result()
+{
+}
+
+KXmlRpc::Result::~Result()
+{
+}
+
+bool KXmlRpc::Result::success() const
+{
+ return mSuccess;
+}
+
+int KXmlRpc::Result::errorCode() const
+{
+ return mErrorCode;
+}
+
+QString KXmlRpc::Result::errorString() const
+{
+ return mErrorString;
+}
+
+QList<QVariant> KXmlRpc::Result::data() const
+{
+ return mData;
+}
+
+class Query::Private
+{
+ public:
+ Private( Query *parent )
+ : mParent( parent )
+ {
+ }
+
+ bool isMessageResponse( const QDomDocument &doc ) const;
+ bool isFaultResponse( const QDomDocument &doc ) const;
+
+ Result parseMessageResponse( const QDomDocument &doc ) const;
+ Result parseFaultResponse( const QDomDocument &doc ) const;
+
+ QString markupCall( const QString &method, const QList<QVariant> &args ) const;
+ QString marshal( const QVariant &value ) const;
+ QVariant demarshal( const QDomElement &element ) const;
+
+ void slotData( KIO::Job *job, const QByteArray &data );
+ void slotResult( KJob *job );
+
+ Query *mParent;
+ QByteArray mBuffer;
+ QVariant mId;
+ QList<KJob*> mPendingJobs;
+};
+
+bool Query::Private::isMessageResponse( const QDomDocument &doc ) const
+{
+ return doc.documentElement().firstChild().toElement().tagName().toLower()
+ == "params";
+}
+
+bool Query::Private::isFaultResponse( const QDomDocument &doc ) const
+{
+ return doc.documentElement().firstChild().toElement().tagName().toLower()
+ == "fault";
+}
+
+Result Query::Private::parseMessageResponse( const QDomDocument &doc ) const
+{
+ Result response;
+ response.mSuccess = true;
+
+ QDomNode paramNode = doc.documentElement().firstChild().firstChild();
+ while ( !paramNode.isNull() ) {
+ response.mData << demarshal( paramNode.firstChild().toElement() );
+ paramNode = paramNode.nextSibling();
+ }
+
+ return response;
+}
+
+Result Query::Private::parseFaultResponse( const QDomDocument &doc ) const
+{
+ Result response;
+ response.mSuccess = false;
+
+ QDomNode errorNode = doc.documentElement().firstChild().firstChild();
+ const QVariant errorVariant = demarshal( errorNode.toElement() );
+ response.mErrorCode = errorVariant.toMap() [ "faultCode" ].toInt();
+ response.mErrorString = errorVariant.toMap() [ "faultString" ].toString();
+
+ return response;
+}
+
+QString Query::Private::markupCall( const QString &cmd,
+ const QList<QVariant> &args ) const
+{
+ QString markup = "<?xml version=\"1.0\" ?>\r\n<methodCall>\r\n";
+
+ markup += "<methodName>" + cmd + "</methodName>\r\n";
+
+ if ( !args.isEmpty() ) {
+
+ markup += "<params>\r\n";
+ QList<QVariant>::ConstIterator it = args.begin();
+ QList<QVariant>::ConstIterator end = args.end();
+ for ( ; it != end; ++it ) {
+ markup += "<param>\r\n" + marshal( *it ) + "</param>\r\n";
+ }
+ markup += "</params>\r\n";
+ }
+
+ markup += "</methodCall>\r\n";
+
+ return markup;
+}
+
+QString Query::Private::marshal( const QVariant &arg ) const
+{
+ switch ( arg.type() ) {
+
+ case QVariant::String:
+ return "<value><string><![CDATA[" + arg.toString() + "]]></string></value>\r\n";
+ case QVariant::StringList:
+ {
+ QStringList data = arg.toStringList();
+ QStringListIterator dataIterator(data);
+ QString markup;
+ markup += "<value><array><data>";
+ while ( dataIterator.hasNext() ) {
+ markup += "<value><string><![CDATA[" + dataIterator.next() + "]]></string></value>\r\n";
+ }
+ markup += "</data></array></value>";
+ return markup;
+ }
+ case QVariant::Int:
+ return "<value><int>" + QString::number( arg.toInt() ) + "</int></value>\r\n";
+ case QVariant::Double:
+ return "<value><double>" + QString::number( arg.toDouble() ) + "</double></value>\r\n";
+ case QVariant::Bool:
+ {
+ QString markup = "<value><boolean>";
+ markup += arg.toBool() ? "1" : "0";
+ markup += "</boolean></value>\r\n";
+ return markup;
+ }
+ case QVariant::ByteArray:
+ return "<value><base64>" + arg.toByteArray().toBase64() + "</base64></value>\r\n";
+ case QVariant::DateTime:
+ {
+ return "<value><dateTime.iso8601>" +
+ arg.toDateTime().toString( Qt::ISODate ) +
+ "</dateTime.iso8601></value>\r\n";
+ }
+ case QVariant::List:
+ {
+ QString markup = "<value><array><data>\r\n";
+ const QList<QVariant> args = arg.toList();
+ QList<QVariant>::ConstIterator it = args.begin();
+ QList<QVariant>::ConstIterator end = args.end();
+ for ( ; it != end; ++it ) {
+ markup += marshal( *it );
+ }
+ markup += "</data></array></value>\r\n";
+ return markup;
+ }
+ case QVariant::Map:
+ {
+ QString markup = "<value><struct>\r\n";
+ QMap<QString, QVariant> map = arg.toMap();
+ QMap<QString, QVariant>::ConstIterator it = map.constBegin();
+ QMap<QString, QVariant>::ConstIterator end = map.constEnd();
+ for ( ; it != end; ++it ) {
+ markup += "<member>\r\n";
+ markup += "<name>" + it.key() + "</name>\r\n";
+ markup += marshal( it.value() );
+ markup += "</member>\r\n";
+ }
+ markup += "</struct></value>\r\n";
+ return markup;
+ }
+ default:
+ kWarning() << "Failed to marshal unknown variant type:" << arg.type();
+ };
+
+ return QString();
+}
+
+QVariant Query::Private::demarshal( const QDomElement &element ) const
+{
+ Q_ASSERT( element.tagName().toLower() == "value" );
+
+ const QDomElement typeElement = element.firstChild().toElement();
+ const QString typeName = typeElement.tagName().toLower();
+
+ if ( typeName == "string" ) {
+ return QVariant( typeElement.text() );
+ } else if ( typeName == "i4" || typeName == "int" ) {
+ return QVariant( typeElement.text().toInt() );
+ } else if ( typeName == "double" ) {
+ return QVariant( typeElement.text().toDouble() );
+ } else if ( typeName == "boolean" ) {
+
+ if ( typeElement.text().toLower() == "true" || typeElement.text() == "1" ) {
+ return QVariant( true );
+ } else {
+ return QVariant( false );
+ }
+ } else if ( typeName == "base64" ) {
+ return QVariant( QByteArray::fromBase64( typeElement.text().toLatin1() ) );
+ } else if ( typeName == "datetime" || typeName == "datetime.iso8601" ) {
+ QDateTime date;
+ QString dateText = typeElement.text();
+ // Test for broken use of Basic ISO8601 date and extended ISO8601 time
+ if ( 17 <= dateText.length() && dateText.length() <= 18 &&
+ dateText.at( 4 ) != '-' && dateText.at( 11 ) == ':' ) {
+ if ( dateText.endsWith( 'Z' ) ) {
+ date = QDateTime::fromString( dateText, "yyyyMMddTHH:mm:ssZ" );
+ } else {
+ date = QDateTime::fromString( dateText, "yyyyMMddTHH:mm:ss" );
+ }
+ } else {
+ date = QDateTime::fromString( dateText, Qt::ISODate );
+ }
+ return QVariant( date );
+ } else if ( typeName == "array" ) {
+ QList<QVariant> values;
+ QDomNode valueNode = typeElement.firstChild().firstChild();
+ while ( !valueNode.isNull() ) {
+ values << demarshal( valueNode.toElement() );
+ valueNode = valueNode.nextSibling();
+ }
+ return QVariant( values );
+ } else if ( typeName == "struct" ) {
+
+ QMap<QString, QVariant> map;
+ QDomNode memberNode = typeElement.firstChild();
+ while ( !memberNode.isNull() ) {
+ const QString key = memberNode.toElement().elementsByTagName(
+ "name" ).item( 0 ).toElement().text();
+ const QVariant data = demarshal( memberNode.toElement().elementsByTagName(
+ "value" ).item( 0 ).toElement() );
+ map[ key ] = data;
+ memberNode = memberNode.nextSibling();
+ }
+ return QVariant( map );
+ } else {
+ kWarning() << "Cannot demarshal unknown type" << typeName;
+ }
+ return QVariant();
+}
+
+void Query::Private::slotData( KIO::Job *, const QByteArray &data )
+{
+ unsigned int oldSize = mBuffer.size();
+ mBuffer.resize( oldSize + data.size() );
+ memcpy( mBuffer.data() + oldSize, data.data(), data.size() );
+}
+
+void Query::Private::slotResult( KJob *job )
+{
+ mPendingJobs.removeAll( job );
+
+ if ( job->error() != 0 ) {
+ emit mParent->fault( job->error(), job->errorString(), mId );
+ emit mParent->finished( mParent );
+ return;
+ }
+
+// const QString data = QString::fromUtf8( mBuffer.data(), mBuffer.size() );
+
+ QDomDocument doc;
+ QString errMsg;
+ int errLine, errCol;
+ if ( !doc.setContent( mBuffer, false, &errMsg, &errLine, &errCol ) ) {
+ emit mParent->fault( -1, i18n( "Received invalid XML markup: %1 at %2:%3",
+ errMsg, errLine, errCol ), mId );
+ emit mParent->finished( mParent );
+ return;
+ }
+
+ mBuffer.truncate( 0 );
+
+ if ( isMessageResponse( doc ) ) {
+ emit mParent->message( parseMessageResponse( doc ).data(), mId );
+ } else if ( isFaultResponse( doc ) ) {
+ emit mParent->fault( parseFaultResponse( doc ).errorCode(),
+ parseFaultResponse( doc ).errorString(), mId );
+ } else {
+ emit mParent->fault( 1, i18n( "Unknown type of XML markup received" ),
+ mId );
+ }
+
+ emit mParent->finished( mParent );
+}
+
+Query *Query::create( const QVariant &id, QObject *parent )
+{
+ return new Query( id, parent );
+}
+
+void Query::call( const QString &server,
+ const QString &method,
+ const QList<QVariant> &args,
+ const QMap<QString, QString> &jobMetaData )
+{
+
+ const QString xmlMarkup = d->markupCall( method, args );
+
+ QMap<QString, QString>::const_iterator mapIter;
+ QByteArray postData;
+ QDataStream stream( &postData, QIODevice::WriteOnly );
+ stream.writeRawData( xmlMarkup.toUtf8(), xmlMarkup.toUtf8().length() );
+
+ KIO::TransferJob *job = KIO::http_post( KUrl( server ), postData, KIO::HideProgressInfo );
+
+ if ( !job ) {
+ kWarning() << "Unable to create KIO job for" << server;
+ return;
+ }
+
+ job->addMetaData( "content-type", "Content-Type: text/xml; charset=utf-8" );
+ job->addMetaData( "ConnectTimeout", "50" );
+
+ for ( mapIter = jobMetaData.begin(); mapIter != jobMetaData.end(); ++mapIter ) {
+ job->addMetaData( mapIter.key(), mapIter.value() );
+ }
+
+ connect( job, SIGNAL( data( KIO::Job *, const QByteArray & ) ),
+ this, SLOT( slotData( KIO::Job *, const QByteArray & ) ) );
+ connect( job, SIGNAL( result( KJob * ) ),
+ this, SLOT( slotResult( KJob * ) ) );
+
+ d->mPendingJobs.append( job );
+}
+
+Query::Query( const QVariant &id, QObject *parent )
+ : QObject( parent ), d( new Private( this ) )
+{
+ d->mId = id;
+}
+
+Query::~Query()
+{
+ QList<KJob*>::Iterator it;
+ for ( it = d->mPendingJobs.begin(); it != d->mPendingJobs.end(); ++it ) {
+ (*it)->kill();
+ }
+ delete d;
+}
+
+#include "query.moc"
+
+
--- /dev/null
+++ tellico-2.3.5+dfsg.1/src/fetch/xmlrpc/client.h
@@ -0,0 +1,323 @@
+/******************************************************************************
+ * Copyright (C) 2003 - 2004 by Frerich Raabe <[email protected]> *
+ * Tobias Koenig <[email protected]> *
+ * Copyright (C) 2006 by Narayan Newton <[email protected]> *
+ * *
+ * 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. For licensing and distribution *
+ * details, check the accompanying file 'COPYING.BSD'. *
+ *****************************************************************************/
+/**
+ @file
+ This file is part of the API for accessing XML-RPC Servers
+ and defines the Client class.
+
+ @brief
+ Defines the Client class.
+
+ @author Frerich Raabe <[email protected]>
+ @author Tobias Koenig <[email protected]>
+ @author Narayan Newton <[email protected]>
+*/
+
+#ifndef KXML_RPC_CLIENT_H
+#define KXML_RPC_CLIENT_H
+
+#undef QT_NO_CAST_FROM_ASCII
+
+#include <kurl.h>
+
+#include <QtCore/QList>
+#include <QtCore/QObject>
+#include <QtCore/QVariant>
+
+/** Names for XmlRpc related classes */
+namespace KXmlRpc {
+
+/**
+ @brief
+ A class that represents a connection to a XML-RPC server.
+ This is the main interface to the XML-RPC client library.
+
+ @code
+ KXmlRpc::Client *c = new Client(KUrl( "http://localhost" ), this);
+ c->setUserAgent( "Test/1.0" );
+ c->call( "xmlrpc.command1", "Hi!",
+ this, SLOT( gotData( const QList<QVariant>&, const QVariant ) ),
+ this, SLOT( gotError( const QString&, const QVariant& ) ) );
+ @endcode
+
+ @author Narayan Newton <[email protected]>
+ */
+class Client : public QObject
+{
+ Q_OBJECT
+
+ public:
+ /**
+ Constructs a XML-RPC Client.
+
+ @param parent the parent of this object, defaults to NULL.
+ */
+ explicit Client( QObject *parent = 0 );
+
+ /**
+ Constructs a XML-RPC Client, which will connect to @p url.
+
+ @param url the url of the xml-rpc server.
+ @param parent the parent of this object, defaults to NULL.
+ */
+ explicit Client( const KUrl &url, QObject *parent = 0 );
+
+ /**
+ Destroys the XML-RPC Client.
+ */
+ ~Client();
+
+ /**
+ Returns the current url the XML-RPC Client will connect to.
+
+ @see setUrl()
+ */
+ KUrl url() const;
+
+ /**
+ Sets the url the Client will connect to.
+
+ @param url the url for the xml-rpc server we will be connecting to.
+
+ @see url()
+ */
+ void setUrl( const KUrl &url );
+
+ /**
+ Returns the user agent string currently used by the Client.
+
+ @see setUserAgent()
+ */
+ QString userAgent() const;
+
+ /**
+ Sets the userAgent string the Client will use to identify itself.
+
+ @param userAgent the user agent string to use.
+
+ @see userAgent()
+ */
+ void setUserAgent( const QString &userAgent );
+
+ /**
+ Returns true if HTTP-Digest authentication is enabled, false
+ if not.
+
+ @see setDigestAuthEnabled()
+ */
+ bool isDigestAuthEnabled() const;
+
+ /**
+ Enables/disables HTTP-Digest authentication
+
+ @see isDigestAuthEnabled()
+ */
+
+ void setDigestAuthEnabled( bool enabled );
+
+ public Q_SLOTS:
+ /**
+ Calls the given method on a XML-RPC server, with the given
+ argument list.
+
+ @param method the method on the server we are going to be calling
+ @param args the argument list to pass to the server
+ @param msgObj the object containing the data slot
+ @param messageSlot the data slot itself
+ @param faultObj the object containing the error slot
+ @param faultSlot the error slot itself
+ @param id the id for our #Client object, defaults to empty
+ */
+ void call( const QString &method, const QList<QVariant> &args,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot,
+ const QVariant &id = QVariant() );
+
+ /**
+ Calls the given method on a XML-RPC server, with the given
+ argument.
+
+ @param method the method on the server we are going to be calling
+ @param arg the argument to pass to the server
+ @param msgObj the object containing the data slot
+ @param messageSlot the data slot itself
+ @param faultObj the object containing the error slot
+ @param faultSlot the error slot itself
+ @param id the id for our Client object, defaults to empty
+ */
+ void call( const QString &method, const QVariant &arg,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot,
+ const QVariant &id = QVariant() );
+
+ /**
+ Calls the given method on a XML-RPC server, with the given
+ int as the argument.
+
+ @param method the method on the server we are going to be calling
+ @param arg the int to pass to the server
+ @param msgObj the object containing the data slot
+ @param messageSlot the data slot itself
+ @param faultObj the object containing the error slot
+ @param faultSlot the error slot itself
+ @param id the id for our Client object, defaults to empty
+ */
+ void call( const QString &method, int arg,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot,
+ const QVariant &id = QVariant() );
+
+ /**
+ Calls the given method on a XML-RPC server, with the given
+ bool as the argument.
+
+ @param method the method on the server we are going to be calling
+ @param arg the bool to pass to the server
+ @param msgObj the object containing the data slot
+ @param messageSlot the data slot itself
+ @param faultObj the object containing the error slot
+ @param faultSlot the error slot itself
+ @param id the id for our Client object, defaults to empty
+ */
+ void call( const QString &method, bool arg,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot,
+ const QVariant &id = QVariant() );
+
+ /**
+ Calls the given method on a XML-RPC server, with the given
+ double as the argument.
+
+ @param method the method on the server we are going to be calling
+ @param arg the double to pass to the server
+ @param msgObj the object containing the data slot
+ @param messageSlot the data slot itself
+ @param faultObj the object containing the error slot
+ @param faultSlot the error slot itself
+ @param id the id for our Client object, defaults to empty
+ */
+ void call( const QString &method, double arg,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot,
+ const QVariant &id = QVariant() );
+
+ /**
+ Calls the given method on a XML-RPC server, with the given
+ string as the argument.
+
+ @param method the method on the server we are going to be calling
+ @param arg the string to pass to the server
+ @param msgObj the object containing the data slot
+ @param messageSlot the data slot itself
+ @param faultObj the object containing the error slot
+ @param faultSlot the error slot itself
+ @param id the id for our Client object, defaults to empty
+ */
+ void call( const QString &method, const QString &arg,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot,
+ const QVariant &id = QVariant() );
+
+ /**
+ Calls the given method on a XML-RPC server, with the given
+ byte array as the argument.
+
+ @param method the method on the server we are going to be calling
+ @param arg the array to pass to the server
+ @param msgObj the object containing the data slot
+ @param messageSlot the data slot itself
+ @param faultObj the object containing the error slot
+ @param faultSlot the error slot itself
+ @param id the id for our Client object, defaults to empty
+ */
+ void call( const QString &method, const QByteArray &arg,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot,
+ const QVariant &id = QVariant() );
+
+ /**
+ Calls the given method on a XML-RPC server, with the given
+ date as the argument
+
+ @param method the method on the server we are going to be calling
+ @param arg the date and/or time to pass to the server
+ @param msgObj the object containing the data slot
+ @param messageSlot the data slot itself
+ @param faultObj the object containing the error slot
+ @param faultSlot the error slot itself
+ @param id the id for our Client object, defaults to empty
+ */
+ void call( const QString &method, const QDateTime &arg,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot,
+ const QVariant &id = QVariant() );
+
+ /**
+ Calls the given method on a XML-RPC server, with the given
+ string list as the argument
+
+ @param method the method on the server we are going to be calling
+ @param arg the list of strings to pass to the server
+ @param msgObj the object containing the data slot
+ @param messageSlot the data slot itself
+ @param faultObj the object containing the error slot
+ @param faultSlot the error slot itself
+ @param id the id for our Client object, defaults to empty
+ */
+ void call( const QString &method, const QStringList &arg,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot,
+ const QVariant &id = QVariant() );
+
+ private:
+ class Private;
+ Private *const d;
+
+ template <typename T>
+ void call( const QString &method, const QList<T> &arg,
+ QObject *obj1, const char *messageSlot,
+ QObject *obj2, const char *faultSlot,
+ const QVariant &id = QVariant() );
+
+ Q_PRIVATE_SLOT( d, void queryFinished( Query * ) )
+};
+
+/**
+ Calls the given method on a XML-RPC server with the given
+ list of type T arguments.
+
+ @param method the method on the server we are going to be calling
+ @param arg the list of type T to pass to the server
+ @param msgObj the object containing the data slot
+ @param messageSlot the data slot itself
+ @param faultObj the object containing the error slot
+ @param faultSlot the error slot itself
+ @param id the id for our Client object, defaults to empty
+*/
+template <typename T>
+void Client::call( const QString &method, const QList<T> &arg,
+ QObject *msgObj, const char *messageSlot,
+ QObject *faultObj, const char *faultSlot,
+ const QVariant &id )
+{
+ QList<QVariant> args;
+
+ for ( int i = 0; i < arg.count(); ++i ) {
+ args << QVariant( arg[ i ] );
+ }
+
+ return call( method, args, faultObj, faultSlot, msgObj, messageSlot, id );
+}
+
+}
+
+#endif
+