diff options
Diffstat (limited to 'kresources/blogging')
-rw-r--r-- | kresources/blogging/API_Blog.cpp | 121 | ||||
-rw-r--r-- | kresources/blogging/API_Blog.h | 162 | ||||
-rw-r--r-- | kresources/blogging/API_Blogger.cpp | 332 | ||||
-rw-r--r-- | kresources/blogging/API_Blogger.h | 57 | ||||
-rw-r--r-- | kresources/blogging/Makefile.am | 29 | ||||
-rw-r--r-- | kresources/blogging/blogging.desktop | 50 | ||||
-rw-r--r-- | kresources/blogging/bloggingcalendaradaptor.cpp | 259 | ||||
-rw-r--r-- | kresources/blogging/bloggingcalendaradaptor.h | 104 | ||||
-rw-r--r-- | kresources/blogging/bloggingglobals.cpp | 53 | ||||
-rw-r--r-- | kresources/blogging/bloggingglobals.h | 50 | ||||
-rw-r--r-- | kresources/blogging/kcal_resourceblogging.cpp | 93 | ||||
-rw-r--r-- | kresources/blogging/kcal_resourceblogging.h | 59 | ||||
-rw-r--r-- | kresources/blogging/kcal_resourceblogging_plugin.cpp | 41 | ||||
-rw-r--r-- | kresources/blogging/kcal_resourcebloggingconfig.cpp | 41 | ||||
-rw-r--r-- | kresources/blogging/kcal_resourcebloggingconfig.h | 40 | ||||
-rw-r--r-- | kresources/blogging/resourcebloggingsettings.ui | 330 | ||||
-rw-r--r-- | kresources/blogging/xmlrpcjob.cpp | 430 | ||||
-rw-r--r-- | kresources/blogging/xmlrpcjob.h | 123 |
18 files changed, 2374 insertions, 0 deletions
diff --git a/kresources/blogging/API_Blog.cpp b/kresources/blogging/API_Blog.cpp new file mode 100644 index 000000000..670cd1661 --- /dev/null +++ b/kresources/blogging/API_Blog.cpp @@ -0,0 +1,121 @@ +/*************************************************************************** +* Copyright (C) 2004-05 Reinhold Kainhofer <reinhold@kainhofer.com> * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +***************************************************************************/ +#include "API_Blog.h" +#include <kdebug.h> +#include <qvariant.h> + +using namespace KBlog; + +APIBlog::APIBlog( const KURL &url, QObject *parent, const char *name ) : + QObject( parent, name ), + mServerURL( url ), mAppID( QString::null ), mDownloadCount( 20 ) +{} + +APIBlog::~APIBlog() +{} + +void APIBlog::dumpBlog( BlogPosting *blog ) +{ + kdDebug() << "-----------------------------------" << endl; + kdDebug() << "Post " << blog->postID() << " by \"" << + blog->userID() << "\" on " << + blog->dateTime().toString() << endl; + kdDebug() << "Title: " << blog->title() << endl; + kdDebug() << blog->content() <<endl; + kdDebug() << "-----------------------------------" << endl; +} + + + +/*void APIBlog::setTemplateTags( const BlogTemplate& Template ) +{ + mTemplate = Template; +} +BlogTemplate APIBlog::templateTags() const +{ + return mTemplate; +}*/ + +/*void APIBlog::deletePost( const QString &postID ) +{ + BlogPosting *post = new BlogPosting(); + post->setPostID( postID ); + deletePost( post ); + delete post; +}*/ + +QValueList<QVariant> APIBlog::defaultArgs( const QString &id ) +{ + QValueList<QVariant> args; + args << QVariant( mAppID ); + if ( !id.isNull() ) { + args << QVariant( id ); + } + args << QVariant( mUsername ) + << QVariant( mPassword ); + return args; +} + + +KCal::Journal *APIBlog::journalFromPosting( KBlog::BlogPosting *blog ) +{ + if ( !blog ) return 0; + KCal::Journal *j = new KCal::Journal(); + QDateTime dt = blog->dateTime(); + QDateTime creationDt = blog->creationDateTime(); + QDateTime modificationDt = blog->modificationDateTime(); +kdDebug() << "dt ="<<dt.toString( Qt::ISODate ) << endl; +kdDebug() << "creationDt ="<<creationDt.toString( Qt::ISODate ) << endl; +kdDebug() << "modificationDt="<<modificationDt.toString( Qt::ISODate ) << endl; + if ( dt.isValid() && !dt.isNull() ) { + j->setDtStart( dt ); + } else if ( creationDt.isValid() && !creationDt.isNull() ) { + j->setDtStart( creationDt ); + } else if ( modificationDt.isValid() && !modificationDt.isNull() ) { + j->setDtStart( modificationDt ); + } + + j->setCreated( blog->creationDateTime() ); + j->setLastModified( blog->modificationDateTime() ); + j->setFloats( false ); + kdDebug() << "Date for blog " << blog->title() << " is " + << blog->dateTime().toString()<<endl; + j->setSummary( blog->title() ); + j->setDescription( blog->content() ); + j->setCategories( QStringList( blog->category() ) ); + j->setOrganizer( blog->userID() ); + j->setCustomProperty( "KCalBloggerRes", "UserID", blog->userID() ); + j->setCustomProperty( "KCalBloggerRes", "BlogID", blog->blogID() ); + j->setCustomProperty( "KCalBloggerRes", "PostID", blog->postID() ); + + // TODO: Set the read-only flag in the resource! +// j->setReadOnly( readOnly() ); + + return j; +} + +KBlog::BlogPosting *APIBlog::postingFromJournal( KCal::Journal *journal ) +{ + KBlog::BlogPosting *item = new KBlog::BlogPosting(); + if ( journal && item ) { + item->setContent( journal->description() ); + item->setTitle( journal->summary() ); + item->setCategory( journal->categories().first() ); + item->setDateTime( journal->dtStart() ); + item->setModificationDateTime( journal->lastModified() ); + item->setCreationDateTime( journal->created() ); + item->setUserID( journal->customProperty( "KCalBloggerRes", "UserID" ) ); + item->setBlogID( journal->customProperty( "KCalBloggerRes", "BlogID" ) ); + item->setPostID( journal->customProperty( "KCalBloggerRes", "PostID" ) ); + } + return item; +} + + +#include "API_Blog.moc" diff --git a/kresources/blogging/API_Blog.h b/kresources/blogging/API_Blog.h new file mode 100644 index 000000000..77c27d68b --- /dev/null +++ b/kresources/blogging/API_Blog.h @@ -0,0 +1,162 @@ +/************************************************************************** +* Copyright (C) 2004 by Reinhold Kainhofer <reinhold@kainhofer.com> * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +***************************************************************************/ +#ifndef API_BLOG_H +#define API_BLOG_H + +#include <kurl.h> +#include <kio/job.h> +#include <libkcal/journal.h> + +#include <qobject.h> +#include <qstring.h> +#include <qvaluelist.h> +#include <qdatetime.h> + +/** +This is the main interface for blog backends +@author ian reinhart geiser, Reinhold Kainhofer +*/ + +namespace KBlog { + +class BlogPosting +{ +public: + BlogPosting() {} + virtual ~BlogPosting() {} + + QString userID() const { return mUserID; } + void setUserID( const QString &userID ) { mUserID = userID; } + + QString blogID() const { return mBlogID; } + void setBlogID( const QString &blogID ) { mBlogID = blogID; } + + QString postID() const { return mPostID; } + void setPostID( const QString &postID ) { assignPostID( postID ); mPostID = postID; } + + QString title() const { return mTitle; } + void setTitle( const QString &title ) { mTitle = title; } + + QString content() const { return mContent; } + void setContent( const QString &content ) { mContent = content; } + + QString category() const { return mCategory; } + void setCategory( const QString &category ) { mCategory = category; } + + QString fingerprint() const { return mFingerprint; } + void setFingerprint( const QString &fp ) { mFingerprint = fp; } + + QDateTime dateTime() const { return mDateTime; } + void setDateTime( const QDateTime &datetime ) { mDateTime = datetime; } + + QDateTime creationDateTime() const { return mCreationDateTime; } + void setCreationDateTime( const QDateTime &datetime ) { mCreationDateTime = datetime; } + + QDateTime modificationDateTime() const { return mModificationDateTime; } + void setModificationDateTime( const QDateTime &datetime ) { mModificationDateTime = datetime; } + + virtual void wasDeleted( bool ) {} + virtual void wasUploaded( bool ) {} + virtual void error( int /*code*/, const QString &/*error*/ ) {} + +protected: + // Override this method to detect the new postID assigned when adding a new post + virtual void assignPostID( const QString &/*postID*/ ) {} + QString mUserID; + QString mBlogID; + QString mPostID; + QString mTitle; + QString mContent; + QString mCategory; + QString mFingerprint; + QDateTime mDateTime; + QDateTime mCreationDateTime; + QDateTime mModificationDateTime; +}; + + +class APIBlog : public QObject +{ + Q_OBJECT + public: + APIBlog( const KURL &server, QObject *parent = 0L, const char *name = 0L ); + virtual ~APIBlog(); + virtual QString interfaceName() const = 0; + + void setAppID( const QString &appID ) { mAppID = appID; } + QString appID() const { return mAppID; } + + void setPassword( const QString &pass ) { mPassword = pass; } + QString password() const { return mPassword; } + + void setUsername( const QString &uname ) { mUsername = uname; } + QString username() const { return mUsername; } + + void setURL( const KURL& url ) { mServerURL = url; } + KURL url() const { return mServerURL; } + + void setDownloadCount( int nr ) { mDownloadCount = nr; } + int downloadCount() const { return mDownloadCount; } + + static void dumpBlog( BlogPosting *blog ); + + + enum blogFunctions { + bloggerGetUserInfo, + bloggerGetUsersBlogs, + bloggerGetRecentPosts, + bloggerNewPost, + bloggerEditPost, + bloggerDeletePost, + bloggerGetPost, + bloggerGetTemplate, + bloggerSetTemplate + }; + + virtual QString getFunctionName( blogFunctions type ) = 0; + virtual QValueList<QVariant> defaultArgs( const QString &id = QString::null ); + + virtual KIO::Job *createUserInfoJob() = 0; + virtual KIO::Job *createListFoldersJob() = 0; + virtual KIO::TransferJob *createListItemsJob( const KURL &url ) = 0; + virtual KIO::TransferJob *createDownloadJob( const KURL &url ) = 0; + virtual KIO::TransferJob *createUploadJob( const KURL &url, KBlog::BlogPosting *posting ) = 0; + virtual KIO::TransferJob *createUploadNewJob( KBlog::BlogPosting *posting ) = 0; + virtual KIO::Job *createRemoveJob( const KURL &url, const QString &postid ) = 0; + + virtual bool interpretUserInfoJob( KIO::Job *job ) = 0; + virtual void interpretListFoldersJob( KIO::Job *job ) = 0; + virtual bool interpretListItemsJob( KIO::Job *job ) = 0; + virtual bool interpretDownloadItemsJob( KIO::Job *job ) = 0; + + static KCal::Journal *journalFromPosting( KBlog::BlogPosting *post ); + static KBlog::BlogPosting *postingFromJournal( KCal::Journal *journal ); + + signals: + // TODO: Connect these + void userInfoRetrieved( const QString &nickname, const QString &userid, const QString &email ); + void folderInfoRetrieved( const QString &id, const QString &name ); + + void itemOnServer( const KURL &remoteURL ); + void itemDownloaded( KCal::Incidence *j, const QString &localID, + const KURL &remoteURL, const QString &fingerprint, + const QString &storageLocation ); + + + protected: + + KURL mServerURL; + QString mPassword; + QString mUsername; + QString mAppID; + int mDownloadCount; +}; + +} +#endif diff --git a/kresources/blogging/API_Blogger.cpp b/kresources/blogging/API_Blogger.cpp new file mode 100644 index 000000000..f30c56206 --- /dev/null +++ b/kresources/blogging/API_Blogger.cpp @@ -0,0 +1,332 @@ +/* + This file is part of kdepim. + + Copyright (c) 2004 Reinhold Kainhofer <reinhold@kainhofer.com> + + 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 "API_Blogger.h" +#include "xmlrpcjob.h" +#include <kdebug.h> + +using namespace KBlog; + +QString APIBlogger::getFunctionName( blogFunctions type ) +{ + switch ( type ) { + case bloggerGetUserInfo: return "blogger.getUserInfo"; + case bloggerGetUsersBlogs: return "blogger.getUsersBlogs"; + case bloggerGetRecentPosts: return "blogger.getRecentPosts"; + case bloggerNewPost: return "blogger.newPost"; + case bloggerEditPost: return "blogger.editPost"; + case bloggerDeletePost: return "blogger.deletePost"; + case bloggerGetPost: return "blogger.getPost"; + case bloggerGetTemplate: return "blogger.getTemplate"; + case bloggerSetTemplate: return "blogger.setTemplate"; + default: return QString::null; + } +} + + + + +KIO::Job *APIBlogger::createUserInfoJob() +{ + kdDebug() << "read user info..." << endl; + QValueList<QVariant> args( defaultArgs() ); + return KIO::xmlrpcCall( mServerURL, getFunctionName( bloggerGetUserInfo ), args, false ); +} + +KIO::Job *APIBlogger::createListFoldersJob() +{ + // TODO: Check if we're already authenticated. If not, do it! +// if ( isValid() ) { + kdDebug() << "Fetch List of Blogs..." << endl; + QValueList<QVariant> args( defaultArgs() ); + return KIO::xmlrpcCall( mServerURL, getFunctionName( bloggerGetUsersBlogs ), args, false ); +// } else { +// warningNotInitialized(); +// return 0; +// } +} + +KIO::TransferJob *APIBlogger::createListItemsJob( const KURL &url ) +{ + // TODO: Check if we're already authenticated. If not, do it! +// if ( isValid() ) { + kdDebug() << "Fetch List of Posts..." << endl; + QValueList<QVariant> args( defaultArgs( url.url() ) ); + args << QVariant( mDownloadCount ); + return KIO::xmlrpcCall( mServerURL, getFunctionName( bloggerGetRecentPosts ), args, false ); +// } else { +// warningNotInitialized(); +// return 0; +// } +} + +KIO::TransferJob *APIBlogger::createDownloadJob( const KURL &url ) +{ +// if ( isValid() ){ + kdDebug() << "Fetch Posting with url " << url.url() << endl; + QValueList<QVariant> args( defaultArgs( url.url() ) ); + return KIO::xmlrpcCall( mServerURL, getFunctionName( bloggerGetPost ), args, false ); +// } else { +// warningNotInitialized(); +// return 0; +// } +} + +KIO::TransferJob *APIBlogger::createUploadJob( const KURL &url, KBlog::BlogPosting *posting ) +{ + if ( !posting ) { + kdDebug() << "APIBlogger::createUploadJob: posting=0" << endl; + return 0; + } +// if ( isValid() ){ + kdDebug() << "Uploading Posting with url " << url.url() << endl; + QValueList<QVariant> args( defaultArgs( posting->postID() ) ); + args << QVariant( posting->content() ); + args << QVariant( /*publish=*/true, 0 ); + return KIO::xmlrpcCall( mServerURL, getFunctionName( bloggerEditPost ), args, false ); +// } else { +// warningNotInitialized(); +// return 0; +// } +} + +KIO::TransferJob *APIBlogger::createUploadNewJob( KBlog::BlogPosting *posting ) +{ + if ( !posting ) { + kdDebug() << "APIBlogger::createUploadNewJob: posting=0" << endl; + return 0; + } +// if ( isValid() ){ + kdDebug() << "Creating new Posting with blogid " << posting->blogID() << " at url " << mServerURL << endl; + QValueList<QVariant> args( defaultArgs( posting->blogID() ) ); + args << QVariant( posting->content() ); + args << QVariant( /*publish=*/true, 0 ); + return KIO::xmlrpcCall( mServerURL, getFunctionName( bloggerNewPost ), args, false ); +// } else { +// warningNotInitialized(); +// return 0; +// } +} + +KIO::Job *APIBlogger::createRemoveJob( const KURL &/*url*/, const QString &postid ) +{ +kdDebug() << "APIBlogger::createRemoveJob: postid=" << postid << endl; +// if ( isValid() ){ + QValueList<QVariant> args( defaultArgs( postid ) ); + args << QVariant( /*publish=*/true, 0 ); + return KIO::xmlrpcCall( mServerURL, getFunctionName( bloggerDeletePost ), args, false ); +// } else { +// warningNotInitialized(); +// return 0; +// } +} + + + + +bool APIBlogger::interpretUserInfoJob( KIO::Job *job ) +{ + // TODO: Implement user authentication +// isValid = true; + KIO::XmlrpcJob *trfjob = dynamic_cast<KIO::XmlrpcJob*>(job); + if ( job->error() || !trfjob ) { + // TODO: Error handling + return false; + } else if ( trfjob ) { + QValueList<QVariant> message( trfjob->response() ); + + kdDebug () << "TOP: " << message[ 0 ].typeName() << endl; + const QValueList<QVariant> posts = message; + QValueList<QVariant>::ConstIterator it = posts.begin(); + QValueList<QVariant>::ConstIterator end = posts.end(); + for ( ; it != end; ++it ) { + kdDebug () << "MIDDLE: " << ( *it ).typeName() << endl; + const QMap<QString, QVariant> postInfo = ( *it ).toMap(); + const QString nickname = postInfo[ "nickname" ].toString(); + const QString userid = postInfo[ "userid" ].toString(); + const QString email = postInfo[ "email" ].toString(); + kdDebug() << "Post " << nickname << " " << userid << " " << email << endl; + // FIXME: How about a BlogUserInfo class??? + emit userInfoRetrieved( nickname, userid, email ); + } + return true; + } + return false; +} + +void APIBlogger::interpretListFoldersJob( KIO::Job *job ) +{ +kdDebug() << "APIBlogger::interpretListFoldersJob" << endl; + KIO::XmlrpcJob *trfjob = dynamic_cast<KIO::XmlrpcJob*>(job); + if ( job->error() || !trfjob ) { + // TODO: Error handling + } else { +kdDebug() << "APIBlogger::interpretListFoldersJob, no error!" << endl; + QValueList<QVariant> message( trfjob->response() ); + kdDebug () << "TOP: " << message[ 0 ].typeName() << endl; + + const QValueList<QVariant> posts = message[ 0 ].toList(); + QValueList<QVariant>::ConstIterator it = posts.begin(); + QValueList<QVariant>::ConstIterator end = posts.end(); + for ( ; it != end; ++it ) { + kdDebug () << "MIDDLE: " << ( *it ).typeName() << endl; + const QMap<QString, QVariant> postInfo = ( *it ).toMap(); + + const QString id( postInfo[ "blogid" ].toString() ); + const QString name( postInfo[ "blogName" ].toString() ); + const QString url( postInfo[ "url" ].toString() ); + + // Use the Blog ID instead of the URL. The ID already indicates the correct blog, and the + // URL for all calls will be the XML-RPC interface, anyway. + if ( !id.isEmpty() && !name.isEmpty() ) { + emit folderInfoRetrieved( id, name ); +kdDebug()<< "Emitting folderInfoRetrieved( id=" << id << ", name=" << name << "); " << endl; + } + } + } +} + +bool APIBlogger::interpretListItemsJob( KIO::Job *job ) +{ + return interpretDownloadItemsJob( job ); +} + +bool APIBlogger::interpretDownloadItemsJob( KIO::Job *job ) +{ + kdDebug(5800)<<"APIBlogger::interpretDownloadItemJob"<<endl; + KIO::XmlrpcJob *trfjob = dynamic_cast<KIO::XmlrpcJob*>(job); + bool success = false; + if ( job->error() || !trfjob ) { + // TODO: Error handling + success = false; + } else { + //array of structs containing ISO.8601 dateCreated, String userid, String postid, String content; + // TODO: Time zone for the dateCreated! + QValueList<QVariant> message( trfjob->response() ); + kdDebug () << "TOP: " << message[ 0 ].typeName() << endl; + + const QValueList<QVariant> postReceived = message[ 0 ].toList(); + QValueList<QVariant>::ConstIterator it = postReceived.begin(); + QValueList<QVariant>::ConstIterator end = postReceived.end(); + success = true; + for ( ; it != end; ++it ) { + BlogPosting posting; + kdDebug () << "MIDDLE: " << ( *it ).typeName() << endl; + const QMap<QString, QVariant> postInfo = ( *it ).toMap(); + if ( readPostingFromMap( &posting, postInfo ) ) { + KCal::Journal *j = journalFromPosting( &posting ); +// dumpBlog( &posting ); + kdDebug() << "Emitting itemOnServer( posting.postID()="<<posting.postID() << "); " << endl; + emit itemOnServer( KURL( posting.postID() ) ); + kdDebug() << "Emitting itemDownloaded( j=" << j << ", uid=" << j->uid() + << ", postID=" << posting.postID() << ", fpr=" + << posting.fingerprint() << "); " << endl; + emit itemDownloaded( j, j->uid(), KURL( posting.postID() ), + posting.fingerprint(), posting.postID() ); + } else { + kdDebug() << "readPostingFromMap failed! " << endl; + success = false; + // TODO: Error handling + } + } + } + return success; +} + + +bool APIBlogger::readPostingFromMap( BlogPosting *post, const QMap<QString, QVariant> &postInfo ) +{ + // FIXME: + if ( !post ) return false; + QStringList mapkeys = postInfo.keys(); + kdDebug() << endl << "Keys: " << mapkeys.join(", ") << endl << endl; + + QString fp( QString::null ); + + QDateTime dt( postInfo[ "dateCreated" ].toDateTime() ); + if ( dt.isValid() && !dt.isNull() ) { + post->setCreationDateTime( dt ); + QString fp = dt.toString( Qt::ISODate ); + } + dt = postInfo[ "postDate" ].toDateTime(); + if ( dt.isValid() && !dt.isNull() ) { + post->setDateTime( dt ); + fp = dt.toString( Qt::ISODate ); + } + dt = postInfo[ "lastModified" ].toDateTime(); + if ( dt.isValid() && !dt.isNull() ) { + post->setModificationDateTime( dt ); + fp = dt.toString( Qt::ISODate ); + } + post->setFingerprint( fp ); + + post->setUserID( postInfo[ "userid" ].toString() ); + post->setPostID( postInfo[ "postid" ].toString() ); + + QString title( postInfo[ "title" ].toString() ); + QString description( postInfo[ "description" ].toString() ); + QString contents( postInfo[ "content" ].toString() ); + QString category; + + // TODO: Extract title and cats from the old-style blogger api without extensions +/* + if ( (title.isEmpty() || description.isEmpty() ) && !contents.isEmpty() ) { + // we don't have both title and description, so use the content (ie. it's an + // old-style blogger api, not the extended drupal api. + + kdDebug() << "No title and description given, so it's an old-style " + "Blogger API without extensions" << endl; + QString catTagOpen = mTemplate.categoryTagOpen(); + QString catTagClose = mTemplate.categoryTagClose(); + QString titleTagOpen = mTemplate.titleTagOpen(); + QString titleTagClose = mTemplate.titleTagClose(); + + int catStart = contents.find( catTagOpen, 0, false ) + catTagOpen.length(); + int catEnd = contents.find( catTagClose, 0, false ); +kdDebug() << " catTagOpen = " << catTagOpen << ", catTagClose = " << catTagClose << ", start - end : " << catStart <<" - " << catEnd << endl; + if ( catEnd > catStart ) { + category = contents.mid( catStart, catEnd - catStart ); + kdDebug() << "Found a category \"" << category << "\"" << endl; + contents = contents.remove( catStart - catTagOpen.length(), + catEnd - catStart + catTagClose.length() + catTagOpen.length() ); + } + int titleStart = contents.find( titleTagOpen, 0, false ) + titleTagOpen.length(); + int titleEnd = contents.find( titleTagClose, 0, false ); +kdDebug() << " titleTagOpen = " << titleTagOpen << ", titleTagClose = " << titleTagClose << ", start - end : " << titleStart <<" - " << titleEnd << endl; + kdDebug() << "Title start and end: " << titleStart << ", " << titleEnd << endl; + if ( titleEnd > titleStart ) { + title = contents.mid( titleStart, titleEnd - titleStart ); + contents = contents.remove( titleStart - titleTagOpen.length(), + titleEnd - titleStart + titleTagClose.length() + titleTagOpen.length() ); + } + kdDebug() << endl << endl << endl << "After treatment of the special tags, we have a content of: "<< endl << contents << endl; + } +*/ + + post->setTitle( title ); + post->setContent( contents ); + if ( !category.isEmpty() ) + post->setCategory( category ); + return true; +} + + + diff --git a/kresources/blogging/API_Blogger.h b/kresources/blogging/API_Blogger.h new file mode 100644 index 000000000..3195b472e --- /dev/null +++ b/kresources/blogging/API_Blogger.h @@ -0,0 +1,57 @@ + /* + This file is part of kdepim. + + Copyright (c) 2004 Reinhold Kainhofer <reinhold@kainhofer.com> + + 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 API_BLOGGER_H +#define API_BLOGGER_H + +#include "API_Blog.h" + +#include <qstring.h> +#include <qvariant.h> +#include <qvaluelist.h> + +namespace KBlog { + +class APIBlogger : public APIBlog +{ + public: + APIBlogger( const KURL &server, QObject *parent = 0L, const char *name = 0L ) : APIBlog( server, parent, name ) {} + QString getFunctionName( blogFunctions type ); + QString interfaceName() const { return "Blogger API 1.0"; } + + + KIO::Job *createUserInfoJob(); + KIO::Job *createListFoldersJob(); + KIO::TransferJob *createListItemsJob( const KURL &url ); + KIO::TransferJob *createDownloadJob( const KURL &url ); + KIO::TransferJob *createUploadJob( const KURL &url, KBlog::BlogPosting *posting ); + KIO::TransferJob *createUploadNewJob( KBlog::BlogPosting *posting ); + KIO::Job *createRemoveJob( const KURL &url, const QString &postid ); + + bool interpretUserInfoJob( KIO::Job *job ); + void interpretListFoldersJob( KIO::Job *job ); + bool interpretListItemsJob( KIO::Job *job ); + bool interpretDownloadItemsJob( KIO::Job *job ); + protected: + bool readPostingFromMap( BlogPosting *post, const QMap<QString, QVariant> &postInfo ); +}; + +} +#endif diff --git a/kresources/blogging/Makefile.am b/kresources/blogging/Makefile.am new file mode 100644 index 000000000..b15724361 --- /dev/null +++ b/kresources/blogging/Makefile.am @@ -0,0 +1,29 @@ +INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/kresources/lib -I../lib -I$(top_srcdir)/kresources/blogging/libkblog/ $(all_includes) + +lib_LTLIBRARIES = libkcal_blogging.la +kde_module_LTLIBRARIES = kcal_blogging.la + +libkcal_blogging_la_SOURCES = API_Blog.cpp API_Blogger.cpp xmlrpcjob.cpp \ + bloggingglobals.cpp \ + bloggingcalendaradaptor.cpp \ + kcal_resourceblogging.cpp kcal_resourcebloggingconfig.cpp +libkcal_blogging_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) \ + -version-info 1:0:0 -no-undefined +libkcal_blogging_la_LIBADD = \ + ../lib/libkgroupwarebase.la \ + $(top_builddir)/libkcal/libkcal.la $(top_builddir)/libkdepim/libkdepim.la + + +kcal_blogging_la_SOURCES = kcal_resourceblogging_plugin.cpp +kcal_blogging_la_LDFLAGS = $(all_libraries) -module -no-undefined $(KDE_PLUGIN) +kcal_blogging_la_LIBADD = libkcal_blogging.la + +kcal_servicedir = $(kde_servicesdir)/kresources/kcal +kcal_service_DATA = blogging.desktop + +METASOURCES = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kres_blogging.pot + +kcal_resourceblogging.lo: ../lib/kresources_groupwareprefs.h diff --git a/kresources/blogging/blogging.desktop b/kresources/blogging/blogging.desktop new file mode 100644 index 000000000..061b06341 --- /dev/null +++ b/kresources/blogging/blogging.desktop @@ -0,0 +1,50 @@ +[Desktop Entry] +Name=Journals as Blogs on a Server +Name[af]=Joernale as Blogs op 'n bediener +Name[bg]=Дневници и блогове +Name[ca]=Diaris com a blocs en un servidor +Name[cs]=Deníky jako blogy na serveru +Name[da]=Journaler som www-blogger på en server +Name[de]=Journaleinträge als Blogs auf einem Server +Name[el]=Εφημερίδες ως Blogs σε έναν εξυπηρετητή +Name[es]=Diarios, como bitácoras en un servidor +Name[et]=Päevik veebipäevikuna serveris +Name[eu]=Egunkariak blog moduan zerbitzarian +Name[fa]=نشریهها به عنوان وبنوشتها روی یک کارساز +Name[fi]=Päiväkirjat blogeina palvelimella +Name[fr]=Journaux (blogs) sur un serveur +Name[fy]=Journalen as blochs op in tsjinner +Name[gl]=Xornais como Bitácoras nun Servidor +Name[hu]=Naplók blogként tárolása a kiszolgálón +Name[is]=Dagbækur sem blogg á þjóni +Name[it]=Diari come blog su un server +Name[ja]=サーバ上のブログとしてのジャーナル +Name[ka]=ბლოგისმაგვარი ჟურნალები სერვერზე +Name[kk]=Сервердегі күнделік блог ретінде +Name[km]=ទិនានុប្បវត្តិជាកំណត់ហេតុបណ្ដាញនៅលើម៉ាស៊ីនបម្រើ +Name[lt]=Dienynai kaip Blog'ai serveryje +Name[ms]=Jurnal sebagai Blog pada pelayan +Name[nb]=Dagbok som blogg på en tjener +Name[nds]=Daagbookindräag as Blog op en Server +Name[ne]=सर्भरमा बल्गका रुपका पत्रिका +Name[nl]=Journalen als blogs op een server +Name[nn]=Dagbøker som bloggar på ein tenar +Name[pl]=Dzienniki jako blogi na serwerze +Name[pt]=Diários como 'Blogs' num Servidor +Name[pt_BR]=Diários como Blogs em um Servidor +Name[ru]=Журналы (блоги) на сервере +Name[sk]=Žurnály ako blogy na serveri +Name[sl]=Dnevniki kot spletni dnevniki (blogi) na strežniku +Name[sr]=Дневници као блогови на серверу +Name[sr@Latn]=Dnevnici kao blogovi na serveru +Name[sv]=Journaler som webbloggar på en server +Name[ta]=சேவகனில் பேச்சுரைகள் பத்திரிககளாக உள்ளன +Name[tr]=Web Günlüğü gibi, bir Sunucuya yazar +Name[uk]=Журнали як веб-щоденники на сервері +Name[zh_CN]=日记作为服务器上的博客日志 +Name[zh_TW]=日誌做為伺服器上的部落格 +X-KDE-Library=kcal_blogging +Type=Service +ServiceTypes=KResources/Plugin +X-KDE-ResourceFamily=calendar +X-KDE-ResourceType=blogging diff --git a/kresources/blogging/bloggingcalendaradaptor.cpp b/kresources/blogging/bloggingcalendaradaptor.cpp new file mode 100644 index 000000000..252452788 --- /dev/null +++ b/kresources/blogging/bloggingcalendaradaptor.cpp @@ -0,0 +1,259 @@ +/* + This file is part of kdepim. + + Copyright (c) 2005 Reinhold Kainhofer <reinhold@kainhofer.com> + + 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 "bloggingcalendaradaptor.h" +#include "bloggingglobals.h" +#include <libemailfunctions/idmapper.h> +#include <folderlister.h> + +#include <libkcal/calendarlocal.h> +#include <libkcal/icalformat.h> +#include <libkcal/resourcecached.h> + +#include <kdebug.h> + +using namespace KCal; + +// That terribly long app key was generated at +// http://www.blogger.com/developers/api/1_docs/register.html +// for the "KDE-Pim libkcal blogging resource". +// TODO: +/*QString BloggingCalendarAdaptor::mAppID = + QString("20ffffffd7ffffffc5ffffffbdffffff87ffffffb72d39fffffffe5c4bfffff" + "fcfffffff80ffffffd4665cfffffff375ffffff88ffffff871a0cffffff8029"); +*/ + + +BloggingUploadItem::BloggingUploadItem( KBlog::APIBlog *api, CalendarAdaptor *adaptor, KCal::Incidence *incidence, KPIM::GroupwareUploadItem::UploadType type ) + : GroupwareUploadItem( type ), mPosting( 0 ), mAPI( 0 ) +{ + Journal* j = dynamic_cast<Journal*>( incidence ); + if ( api && j && adaptor ) { + mItemType = KPIM::FolderLister::Journal; + + setUrl( j->customProperty( adaptor->identifier(), "storagelocation" ) ); + setUid( j->uid() ); + + mPosting = api->postingFromJournal( j ); + mAPI = api; + } +} + +BloggingUploadItem::~BloggingUploadItem() +{ + delete mPosting; +} + +KIO::TransferJob *BloggingUploadItem::createUploadJob( KPIM::GroupwareDataAdaptor *adaptor, const KURL &baseurl ) +{ +kdDebug()<<"BloggingUploadItem::createUploadJob, adaptor="<<adaptor<<", URL="<<baseurl.url()<<endl; + Q_ASSERT( adaptor ); + if ( !adaptor || !mAPI ) return 0; + kdDebug() << "Uploading to: " << url().prettyURL() << endl; + mAPI->setURL( baseurl ); + return mAPI->createUploadJob( url(), mPosting ); +} + +KIO::TransferJob *BloggingUploadItem::createUploadNewJob( KPIM::GroupwareDataAdaptor *adaptor, const KURL &baseurl ) +{ +kdDebug()<<"BloggingUploadItem::createUploadNewJob"<<endl; + Q_ASSERT( adaptor ); + if ( !adaptor || !mAPI ) return 0; + kdDebug() << "Uploading new item to: " << baseurl.prettyURL() << endl; + mAPI->setURL( baseurl ); + return mAPI->createUploadNewJob( mPosting ); +} + + + + + + +BloggingCalendarAdaptor::BloggingCalendarAdaptor() : mAPI( 0 ), mAuthenticated( false ) +{ +} + + +KBlog::APIBlog *BloggingCalendarAdaptor::api() const +{ + return mAPI; +} + +void BloggingCalendarAdaptor::setAPI( KBlog::APIBlog *api ) +{ + delete mAPI; + mAPI = api; + mAuthenticated = false; + connect( api, SIGNAL( userInfoRetrieved( const QString &, const QString &, + const QString & ) ), + SLOT( slotUserInfoRetrieved( const QString &, const QString &, + const QString & ) ) ); + connect( api, SIGNAL( folderInfoRetrieved( const QString &, const QString & ) ), + SLOT( slotFolderInfoRetrieved( const QString&, const QString & ) ) ); + connect( api, SIGNAL( itemOnServer( const KURL & ) ), + SIGNAL( itemOnServer( const KURL & ) ) ); + connect( api, SIGNAL( itemDownloaded( KCal::Incidence *, const QString &, + const KURL &, const QString &, const QString & ) ), + SLOT( calendarItemDownloaded( KCal::Incidence *, const QString &, + const KURL &, const QString &, const QString & ) ) ); + +} + +KPIM::GroupwareUploadItem *BloggingCalendarAdaptor::newUploadItem( KCal::Incidence*it, + KPIM::GroupwareUploadItem::UploadType type ) +{ + return new BloggingUploadItem( mAPI, this, it, type ); +} + + + +void BloggingCalendarAdaptor::slotFolderInfoRetrieved( const QString &id, const QString &name ) +{ + emit folderInfoRetrieved( KURL(id), name, KPIM::FolderLister::Journal ); +} + +void BloggingCalendarAdaptor::slotUserInfoRetrieved( const QString &/*nick*/, + const QString &/*user*/, const QString &/*email*/ ) +{ +kdDebug() << "BloggingCalendarAdaptor::slotUserInfoRetrieved"<<endl; + mAuthenticated = true; +} + +void BloggingCalendarAdaptor::setBaseURL( const KURL &url ) +{ + if ( mAPI ) { + mAPI->setURL( url ); + } +} + +void BloggingCalendarAdaptor::setUser( const QString &user ) +{ + CalendarAdaptor::setUser( user ); + if ( mAPI ) { + mAPI->setUsername( user ); + } +} + +void BloggingCalendarAdaptor::setPassword( const QString &password ) +{ + CalendarAdaptor::setPassword( password ); + if ( mAPI ) { + mAPI->setPassword( password ); + } +} + +void BloggingCalendarAdaptor::setUserPassword( KURL & ) +{ + kdDebug(5800) << "BloggingCalendarAdaptor::setUserPassword" << endl; +} + + + +KIO::Job *BloggingCalendarAdaptor::createLoginJob( const KURL &url, + const QString &user, + const QString &password ) +{ + if ( mAPI ) { + mAPI->setURL( url ); + mAPI->setUsername( user ); + mAPI->setPassword( password ); + return mAPI->createUserInfoJob(); + } else return 0; +} + +KIO::Job *BloggingCalendarAdaptor::createListFoldersJob( const KURL &/*url*/ ) +{ + if ( mAPI ) { + return mAPI->createListFoldersJob(); + } else return 0; +} + +KIO::TransferJob *BloggingCalendarAdaptor::createListItemsJob( const KURL &url ) +{ + if ( mAPI ) { + return mAPI->createListItemsJob( url ); + } else return 0; +} + +KIO::TransferJob *BloggingCalendarAdaptor::createDownloadJob( const KURL &url, + KPIM::FolderLister::ContentType ctype ) +{ + if ( mAPI && (ctype & KPIM::FolderLister::Journal) ) { + return mAPI->createDownloadJob( url ); + } else return 0; +} + +KIO::Job *BloggingCalendarAdaptor::createRemoveJob( const KURL &url, + KPIM::GroupwareUploadItem *deleteItem ) +{ +kdDebug()<<"BloggingCalendarAdaptor::createRemoveJob( " << url.url() << ", ..)" << endl; + if ( mAPI && deleteItem ) { + return mAPI->createRemoveJob( url, deleteItem->url().url() ); + } else return 0; +} + + + + +bool BloggingCalendarAdaptor::interpretLoginJob( KIO::Job *job ) +{ +kdDebug()<<"BloggingCalendarAdaptor::interpretLoginJob"<<endl; + if ( mAPI && job ) { +kdDebug()<<"We have an API and a job"<<endl; + mAuthenticated = false; + mAPI->interpretUserInfoJob( job ); +kdDebug() << "authenticated=" << mAuthenticated << endl; + return mAuthenticated; + } else return false; +} + + +void BloggingCalendarAdaptor::interpretListFoldersJob( KIO::Job *job, KPIM::FolderLister * ) +{ +kdDebug() << "BloggingCalendarAdaptor::interpretListFoldersJob" << endl; + if ( mAPI && job ) { + mAPI->interpretListFoldersJob( job ); + } +} + + +bool BloggingCalendarAdaptor::interpretListItemsJob( KIO::Job *job, + const QString &/*jobData*/ ) +{ + if ( mAPI ) { + return mAPI->interpretListItemsJob( job ); + } else { + return false; + } +} + + +bool BloggingCalendarAdaptor::interpretDownloadItemsJob( KIO::Job *job, + const QString &/*jobData*/ ) +{ + if ( mAPI ) { + return mAPI->interpretDownloadItemsJob( job ); + } else { + return false; + } +} + +#include "bloggingcalendaradaptor.moc" diff --git a/kresources/blogging/bloggingcalendaradaptor.h b/kresources/blogging/bloggingcalendaradaptor.h new file mode 100644 index 000000000..b078a744a --- /dev/null +++ b/kresources/blogging/bloggingcalendaradaptor.h @@ -0,0 +1,104 @@ + /* + This file is part of kdepim. + + Copyright (C) 2004-05 Reinhold Kainhofer <reinhold@kainhofer.com> + + 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 KCAL_BLOGGINGCALENDARADAPTOR_H +#define KCAL_BLOGGINGCALENDARADAPTOR_H + +#include "calendaradaptor.h" +#include "groupwareuploadjob.h" +#include "API_Blog.h" +#include <kurl.h> + +namespace KIO { +class Job; +} + +namespace KCal { + +class BloggingUploadItem : public KPIM::GroupwareUploadItem +{ + public: + BloggingUploadItem( KBlog::APIBlog *api, CalendarAdaptor *adaptor, KCal::Incidence *incidence, UploadType type ); + virtual ~BloggingUploadItem(); + virtual KIO::TransferJob *createUploadNewJob( + KPIM::GroupwareDataAdaptor *adaptor, const KURL &baseurl ); + virtual KIO::TransferJob *createUploadJob( + KPIM::GroupwareDataAdaptor *adaptor, const KURL &url ); + + protected: + BloggingUploadItem( UploadType type ) : KPIM::GroupwareUploadItem( type ) {} + KBlog::BlogPosting *mPosting; + KBlog::APIBlog *mAPI; +}; + +class BloggingCalendarAdaptor : public CalendarAdaptor +{ +Q_OBJECT + public: + BloggingCalendarAdaptor(); + QValueList<KPIM::FolderLister::ContentType> supportedTypes() + { + QValueList<KPIM::FolderLister::ContentType> types; + types << KPIM::FolderLister::Journal; + return types; + } + + QCString identifier() const { return "KCalResourceBlogging"; } + long flags() const { return GWResNeedsLogon; } + + void setBaseURL( const KURL &url ); + void setUser( const QString &user ); + void setPassword( const QString &password ); + // We don't want to set the username / pw for the URL! + void setUserPassword( KURL &url ); + + KBlog::APIBlog *api() const; + void setAPI( KBlog::APIBlog *api ); + + KIO::Job *createLoginJob( const KURL &url, const QString &user, + const QString &password ); + KIO::Job *createListFoldersJob( const KURL &url ); + KIO::TransferJob *createListItemsJob( const KURL &url ); + KIO::TransferJob *createDownloadJob( const KURL &url, + KPIM::FolderLister::ContentType ctype ); + KIO::Job *createRemoveJob( const KURL &url, KPIM::GroupwareUploadItem *deleteItem ); + + bool interpretLoginJob( KIO::Job *job ); + void interpretListFoldersJob( KIO::Job *job, KPIM::FolderLister * ); + bool interpretListItemsJob( KIO::Job *job, const QString &jobData ); + bool interpretDownloadItemsJob( KIO::Job *job, const QString &jobData ); + + public slots: + void slotFolderInfoRetrieved( const QString &id, const QString &name ); + void slotUserInfoRetrieved( const QString &nick, const QString &user, + const QString &email ); + + protected: + KPIM::GroupwareUploadItem *newUploadItem( KCal::Incidence*it, + KPIM::GroupwareUploadItem::UploadType type ); + + KBlog::APIBlog *mAPI; + bool mAuthenticated; + static QString mAppID; +}; + +} + +#endif diff --git a/kresources/blogging/bloggingglobals.cpp b/kresources/blogging/bloggingglobals.cpp new file mode 100644 index 000000000..fae91610f --- /dev/null +++ b/kresources/blogging/bloggingglobals.cpp @@ -0,0 +1,53 @@ +/* + This file is part of kdepim. + + Copyright (c) 2004 Reinhold Kainhofer <reinhold@kainhofer.com> + + 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 "bloggingglobals.h" + +QString BloggingGlobals::mAppID = QString("20ffffffd7ffffffc5ffffffbdffffff87ffffffb72d39fffffffe5c4bffffffcfffffff80ffffffd4665cfffffff375ffffff88ffffff871a0cffffff8029"); + +QString BloggingGlobals::getFunctionName( blogFunctions type ) +{ + switch ( type ) { + case bloggerGetUserInfo: return "blogger.getUserInfo"; + case bloggerGetUsersBlogs: return "blogger.getUsersBlogs"; + case bloggerGetRecentPosts: return "blogger.getRecentPosts"; + case bloggerNewPost: return "blogger.newPost"; + case bloggerEditPost: return "blogger.editPost"; + case bloggerDeletePost: return "blogger.deletePost"; + case bloggerGetPost: return "blogger.getPost"; + case bloggerGetTemplate: return "blogger.getTemplate"; + case bloggerSetTemplate: return "blogger.setTemplate"; + default: return QString::null; + } +} + +QValueList<QVariant> BloggingGlobals::defaultArgs( const QString &user, const QString &pw, const QString &id ) +{ + QValueList<QVariant> args; + args << QVariant( mAppID ); + if ( !id.isNull() ) { + args << QVariant( id ); + } + args << QVariant( user ) + << QVariant( pw ); + return args; +} + diff --git a/kresources/blogging/bloggingglobals.h b/kresources/blogging/bloggingglobals.h new file mode 100644 index 000000000..7d6ed786b --- /dev/null +++ b/kresources/blogging/bloggingglobals.h @@ -0,0 +1,50 @@ + /* + This file is part of kdepim. + + Copyright (c) 2005 Reinhold Kainhofer <reinhold@kainhofer.com> + + 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 BLOGGINGGLOBALS_H +#define BLOGGINGGLOBALS_H + +#include <qstring.h> +#include <qvariant.h> +#include <qvaluelist.h> + +class BloggingGlobals +{ + public: + BloggingGlobals() {} + + enum blogFunctions { + bloggerGetUserInfo, + bloggerGetUsersBlogs, + bloggerGetRecentPosts, + bloggerNewPost, + bloggerEditPost, + bloggerDeletePost, + bloggerGetPost, + bloggerGetTemplate, + bloggerSetTemplate + }; + + static QString getFunctionName( blogFunctions type ); + static QValueList<QVariant> defaultArgs( const QString &user, const QString &pw, const QString &id = QString::null ); + static QString mAppID; +}; + +#endif diff --git a/kresources/blogging/kcal_resourceblogging.cpp b/kresources/blogging/kcal_resourceblogging.cpp new file mode 100644 index 000000000..bffce10d3 --- /dev/null +++ b/kresources/blogging/kcal_resourceblogging.cpp @@ -0,0 +1,93 @@ +/* + This file is part of kdepim. + + Copyright (c) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>> + + 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 General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "bloggingcalendaradaptor.h" +#include "API_Blogger.h" + +#include "kcal_resourceblogging.h" +#include <kresources_groupwareprefs.h> + +using namespace KCal; + +KBlog::APIBlog *ResourceBlogging::mAPI = 0; + +ResourceBlogging::ResourceBlogging() + : ResourceGroupwareBase() +{ + init(); +} + +ResourceBlogging::ResourceBlogging( const KConfig *config ) + : ResourceGroupwareBase( config ) +{ + init(); + if ( config ) readConfig( config ); +} + +void ResourceBlogging::init() +{ + setType( "ResourceBlogging" ); + setPrefs( createPrefs() ); + setFolderLister( new KPIM::FolderLister( KPIM::FolderLister::Calendar ) ); + BloggingCalendarAdaptor *ad = new BloggingCalendarAdaptor(); + setAdaptor( ad ); + ad->setAPI( new KBlog::APIBlogger( prefs()->url(), this ) ); + + ResourceGroupwareBase::init(); +} + +void ResourceBlogging::readConfig( const KConfig *config ) +{ + BloggingCalendarAdaptor *ad = dynamic_cast<BloggingCalendarAdaptor*>( adaptor() ); + ResourceGroupwareBase::readConfig( config ); + if ( ad && prefs() ) { + ad->setUser( prefs()->user() ); + ad->setPassword( prefs()->password() ); + ad->setBaseURL( prefs()->url() ); + } +// QString url = config->readEntry( "URL" ); +// mUrl = KURL( url ); + +// mServerAPI = config->readNumEntry( "ServerAPI" ); +// mTemplate.setCategoryTagOpen( config->readEntry( "CategoryTagOpen", "<CATEGORY>" ) ); +// mTemplate.setCategoryTagClose( config->readEntry( "CategoryTagClose", "</CATEGORY>" ) ); +// mTemplate.setTitleTagOpen( config->readEntry( "TitleTagOpen", "<TITLE>" ) ); +// mTemplate.setTitleTagClose( config->readEntry( "TitleTagClose", "</TITLE>" ) ); + +} + +void ResourceBlogging::writeConfig( KConfig *config ) +{ + kdDebug(5800) << "ResourceBlogging::writeConfig()" << endl; + + ResourceCalendar::writeConfig( config ); + +// config->writeEntry( "URL", mUrl.url() ); +// config->writeEntry( "ServerAPI", mServerAPI ); +// config->writeEntry( "CategoryTagOpen", mTemplate.categoryTagOpen() ); +// config->writeEntry( "CategoryTagClose", mTemplate.categoryTagClose() ); +// config->writeEntry( "TitleTagOpen", mTemplate.titleTagOpen() ); +// config->writeEntry( "TitleTagClose", mTemplate.titleTagClose() ); + + ResourceGroupwareBase::writeConfig( config ); +} + + +#include "kcal_resourceblogging.moc" diff --git a/kresources/blogging/kcal_resourceblogging.h b/kresources/blogging/kcal_resourceblogging.h new file mode 100644 index 000000000..2563b66ed --- /dev/null +++ b/kresources/blogging/kcal_resourceblogging.h @@ -0,0 +1,59 @@ + /* + This file is part of kdepim. + + Copyright (c) 2004 Reinhold Kainhofer <reinhold@kainhofer.com> + + 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 KCAL_RESOURCEBLOGGING_H +#define KCAL_RESOURCEBLOGGING_H + +#include <kcal_resourcegroupwarebase.h> +#include <kdepimmacros.h> + +namespace KBlog { +class APIBlog; +} + +namespace KCal { + +/** + This class provides a resource for accessing blogs on a blogging server as journals +*/ +class KDE_EXPORT ResourceBlogging : public ResourceGroupwareBase +{ + Q_OBJECT + public: + ResourceBlogging(); + ResourceBlogging( const KConfig * ); + + void readConfig( const KConfig *config ); + void writeConfig( KConfig *config ); + + bool addEvent( Event* ) { return false; } + bool addTodo( Todo * ) { return false; } + bool deleteEvent( Event* ) { return false; } + bool deleteTodo( Todo * ) { return false; } + static KBlog::APIBlog *api() { return mAPI; } + + protected: + void init(); + static KBlog::APIBlog *mAPI; +}; + +} + +#endif diff --git a/kresources/blogging/kcal_resourceblogging_plugin.cpp b/kresources/blogging/kcal_resourceblogging_plugin.cpp new file mode 100644 index 000000000..108d5e896 --- /dev/null +++ b/kresources/blogging/kcal_resourceblogging_plugin.cpp @@ -0,0 +1,41 @@ +/* + This file is part of kdepim. + + Copyright (c) 2004 Reinhold Kainhofer <reinhold@kainhofer.com> + + 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 "kcal_resourceblogging.h" +#include "kcal_resourcebloggingconfig.h" + +#include <kglobal.h> +#include <klocale.h> + +using namespace KCal; + +typedef KRES::PluginFactory< ResourceBlogging, ResourceBloggingConfig > BloggingFactory; +//K_EXPORT_COMPONENT_FACTORY( kcal_blogging, BloggingFactory ) + +extern "C" +{ + void *init_kcal_blogging() + { + KGlobal::locale()->insertCatalogue( "kdepimresources" ); + KGlobal::locale()->insertCatalogue( "kres_blogging" ); + return new BloggingFactory; + } +} diff --git a/kresources/blogging/kcal_resourcebloggingconfig.cpp b/kresources/blogging/kcal_resourcebloggingconfig.cpp new file mode 100644 index 000000000..6e2348288 --- /dev/null +++ b/kresources/blogging/kcal_resourcebloggingconfig.cpp @@ -0,0 +1,41 @@ +/* + This file is part of kdepim. + + Copyright (c) 2005 Reinhold Kainhofer <reinhold@kainhofer.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "kcal_resourcebloggingconfig.h" + +#include <kmessagebox.h> +#include <klocale.h> + +using namespace KCal; + +ResourceBloggingConfig::ResourceBloggingConfig( QWidget *parent, const char *name ) : ResourceGroupwareBaseConfig( parent, name ) +{ +} + +void ResourceBloggingConfig::saveSettings( KRES::Resource *resource ) +{ + if ( resource && !resource->readOnly() ) { + KMessageBox::information( this, i18n("Currently, the blogging resource is only read-only. You will not be able to add journals to this resource or upload any changes to the server."), i18n("Read-Only"), "AutoSetReadOnly"); + resource->setReadOnly( true ); + } + ResourceGroupwareBaseConfig::saveSettings( resource ); +} + +#include "kcal_resourcebloggingconfig.moc" diff --git a/kresources/blogging/kcal_resourcebloggingconfig.h b/kresources/blogging/kcal_resourcebloggingconfig.h new file mode 100644 index 000000000..a7a7a4b00 --- /dev/null +++ b/kresources/blogging/kcal_resourcebloggingconfig.h @@ -0,0 +1,40 @@ +/* + This file is part of kdepim. + + Copyright (c) 2005 Reinhold Kainhofer <reinhold@kainhofer.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +#ifndef KCAL_RESOURCEBLOGGINGCONFIG_H +#define KCAL_RESOURCEBLOGGINGCONFIG_H + +#include <kdepimmacros.h> +#include <kcal_resourcegroupwarebaseconfig.h> + +namespace KCal { + +class KDE_EXPORT ResourceBloggingConfig : public ResourceGroupwareBaseConfig +{ + Q_OBJECT + public: + ResourceBloggingConfig( QWidget *parent = 0, const char *name = 0 ); + + public slots: + virtual void saveSettings( KRES::Resource *resource ); +}; + +} + +#endif diff --git a/kresources/blogging/resourcebloggingsettings.ui b/kresources/blogging/resourcebloggingsettings.ui new file mode 100644 index 000000000..6dbb64b03 --- /dev/null +++ b/kresources/blogging/resourcebloggingsettings.ui @@ -0,0 +1,330 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ResourceBloggingSettings</class> +<author>Ian Reinhart Geiser <geiseri@kde.org></author> +<widget class="QWidget"> + <property name="name"> + <cstring>ResourceBloggingSettings</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>363</width> + <height>289</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout12</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_4</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Service:</string> + </property> + </widget> + <widget class="KComboBox"> + <item> + <property name="text"> + <string>Custom</string> + </property> + </item> + <item> + <property name="text"> + <string>Blogger.com</string> + </property> + </item> + <property name="name"> + <cstring>mServiceType</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox2</cstring> + </property> + <property name="title"> + <string>Server Settings</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>URL:</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel9</cstring> + </property> + <property name="text"> + <string>Username:</string> + </property> + </widget> + <widget class="KLineEdit" row="1" column="1"> + <property name="name"> + <cstring>mUser</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel10</cstring> + </property> + <property name="text"> + <string>Password:</string> + </property> + </widget> + <widget class="KURLRequester" row="0" column="1"> + <property name="name"> + <cstring>mURL</cstring> + </property> + <property name="url" stdset="0"> + <string>http://www.kdedevelopers.com/xmlrpc.php</string> + </property> + <property name="showLocalProtocol"> + <bool>true</bool> + </property> + </widget> + <widget class="KLineEdit" row="2" column="1"> + <property name="name"> + <cstring>mPassword</cstring> + </property> + <property name="echoMode"> + <enum>Password</enum> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>textLabel4_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Server API:</string> + </property> + </widget> + <widget class="KComboBox" row="3" column="1"> + <item> + <property name="text"> + <string>Blogger API</string> + </property> + </item> + <item> + <property name="text"> + <string>Drupal API</string> + </property> + </item> + <item> + <property name="text"> + <string>metaWeblog API</string> + </property> + </item> + <item> + <property name="text"> + <string>Moveable Type API</string> + </property> + </item> + <property name="name"> + <cstring>mServerAPI</cstring> + </property> + <property name="contextMenuEnabled"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox3</cstring> + </property> + <property name="title"> + <string>Templates</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KLineEdit" row="0" column="2" rowspan="2" colspan="1"> + <property name="name"> + <cstring>mCloseTitle</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></TITLE></string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel7_2</cstring> + </property> + <property name="text"> + <string>Title tags:</string> + </property> + </widget> + <widget class="KLineEdit" row="0" column="1" rowspan="2" colspan="1"> + <property name="name"> + <cstring>mOpenTitle</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string><TITLE></string> + </property> + </widget> + <widget class="KLineEdit" row="2" column="1"> + <property name="name"> + <cstring>mOpenCategory</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="lineWidth"> + <number>2</number> + </property> + <property name="text"> + <string><CATEGORY></string> + </property> + </widget> + <widget class="QLabel" row="1" column="0" rowspan="2" colspan="1"> + <property name="name"> + <cstring>textLabel8_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Category tags:</string> + </property> + </widget> + <widget class="KLineEdit" row="2" column="2"> + <property name="name"> + <cstring>mCloseCategory</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></CATEGORY></string> + </property> + </widget> + </grid> + </widget> + <spacer> + <property name="name"> + <cstring>spacer4_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>84</height> + </size> + </property> + </spacer> + </vbox> +</widget> +<customwidgets> +</customwidgets> +<tabstops> + <tabstop>mServiceType</tabstop> + <tabstop>mURL</tabstop> + <tabstop>mUser</tabstop> + <tabstop>mPassword</tabstop> + <tabstop>mServerAPI</tabstop> + <tabstop>mOpenTitle</tabstop> + <tabstop>mCloseTitle</tabstop> + <tabstop>mOpenCategory</tabstop> + <tabstop>mCloseCategory</tabstop> +</tabstops> +<layoutdefaults spacing="5" margin="5"/> +<includehints> + <includehint>kcombobox.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kcombobox.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> +</includehints> +</UI> diff --git a/kresources/blogging/xmlrpcjob.cpp b/kresources/blogging/xmlrpcjob.cpp new file mode 100644 index 000000000..76bee44f8 --- /dev/null +++ b/kresources/blogging/xmlrpcjob.cpp @@ -0,0 +1,430 @@ +/* This file is part of the KDE libraries + Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com> + + Based on the davjob: + Copyright (C) 2002 Jan-Pascal van Best <janpascal@vanbest.org> + XML-RPC specific parts taken from the xmlrpciface: + Copyright (C) 2003 - 2004 by Frerich Raabe <raabe@kde.org> + Tobias Koenig <tokoe@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 "xmlrpcjob.h" + +#include <qvariant.h> +#include <qregexp.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kio/http.h> +#include <kmdcodec.h> +#include <kio/davjob.h> + + +#define KIO_ARGS QByteArray packedArgs; \ + QDataStream stream( packedArgs, IO_WriteOnly ); stream + +using namespace KIO; + +namespace KIO { + class XMLRPCResult + { + friend class XmlrpcJob; + public: + XMLRPCResult() {} + bool success() const { return m_success; } + int errorCode() const { return m_errorCode; } + QString errorString() const { return m_errorString; } + QValueList<QVariant> data() const { return m_data; } + private: + bool m_success; + int m_errorCode; + QString m_errorString; + QValueList<QVariant> m_data; + }; +} + +class XmlrpcJob::XmlrpcJobPrivate +{ +public: +// QByteArray savedStaticData; +}; + + +XmlrpcJob::XmlrpcJob( const KURL& url, const QString& method, + const QValueList<QVariant> ¶ms, bool showProgressInfo) + : TransferJob( url, KIO::CMD_SPECIAL, QByteArray(), QByteArray(), + showProgressInfo ) +{ + d = new XmlrpcJobPrivate; + // We couldn't set the args when calling the parent constructor, + // so do it now. + QDataStream stream( m_packedArgs, IO_WriteOnly ); + stream << (int)1 << url; +kdDebug()<<"XMLrpcJob::url="<<url.url()<<endl; +kdDebug()<<"XmlrpcJob::XmlrpcJob, method="<<method<<endl; + // Same for static data + if ( ! method.isEmpty() ) { +kdDebug()<<"XmlrpcJob::XmlrpcJob, method not empty."<<endl; + + QString call = markupCall( method, params ); + staticData = call.utf8(); + staticData.truncate( staticData.size() - 1 ); + kdDebug() << "Message: " << call << endl; +// d->savedStaticData = staticData.copy(); + } + addMetaData( "UserAgent", "KDE XML-RPC TransferJob" ); + addMetaData( "content-type", "Content-Type: text/xml; charset=utf-8" ); + addMetaData( "ConnectTimeout", "50" ); +} + +XmlrpcJob::~XmlrpcJob() +{ + delete d; + d = 0; +} + +QString XmlrpcJob::markupCall( const QString &cmd, + const QValueList<QVariant> &args ) +{ +kdDebug()<<"XmlrpcJob::markupCall, cmd="<<cmd<<endl; + QString markup = "<?xml version=\"1.0\" ?>\r\n<methodCall>\r\n"; + + markup += "<methodName>" + cmd + "</methodName>\r\n"; + + if ( !args.isEmpty() ) + { + markup += "<params>\r\n"; + QValueList<QVariant>::ConstIterator it = args.begin(); + QValueList<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; +} + + + + + +void XmlrpcJob::slotData( const QByteArray& data ) +{ +kdDebug()<<"XmlrpcJob::slotData()"<<endl; + if ( m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error ) + m_str_response.append( QString( data ) ); +} + +void XmlrpcJob::slotFinished() +{ +kdDebug() << "XmlrpcJob::slotFinished()" << endl; +kdDebug() << m_str_response << endl; + + // TODO: Redirection with XML-RPC?? +/* if (! m_redirectionURL.isEmpty() && m_redirectionURL.isValid() ) { + QDataStream istream( m_packedArgs, IO_ReadOnly ); + int s_cmd, s_method; + KURL s_url; + istream >> s_cmd; + istream >> s_url; + istream >> s_method; + // PROPFIND + if ( (s_cmd == 7) && (s_method == (int)KIO::HTTP_POST) ) { + m_packedArgs.truncate(0); + QDataStream stream( m_packedArgs, IO_WriteOnly ); + stream << (int)7 << m_redirectionURL << (int)KIO::HTTP_POST; + } + } else */ + + kdDebug() << "\033[35;40mResult: " << m_str_response << "\033[0;0m" << endl; + QDomDocument doc; + QString errMsg; + int errLine, errCol; + if ( doc.setContent( m_str_response, false, &errMsg, &errLine, &errCol ) ) { + if ( isMessageResponse( doc ) ) { + m_response = parseMessageResponse( doc ).data(); + m_responseType = XMLRPCMessageResponse; + } else if ( isFaultResponse( doc ) ) { + // TODO: Set the error of the job + m_response.clear(); + m_response << QVariant( parseFaultResponse( doc ).errorString() ); + m_responseType = XMLRPCFaultResponse; + } else { + // TODO: Set the error of the job + m_response.clear(); + m_response << QVariant( i18n( "Unknown type of XML markup received. " + "Markup: \n %1" ).arg( m_str_response ) ); + m_responseType = XMLRPCUnknownResponse; + } + + } else { + // TODO: if we can't parse the XML response, set the correct error message! +// emit fault( -1, i18n( "Received invalid XML markup: %1 at %2:%3" ) +// .arg( errMsg ).arg( errLine ).arg( errCol ), m_id ); + } + + TransferJob::slotFinished(); +// TODO: Redirect: if( d ) staticData = d->savedStaticData.copy(); +// Need to send XMLRPC request to this host too +} + + + + + +bool XmlrpcJob::isMessageResponse( const QDomDocument &doc ) +{ + return doc.documentElement().firstChild().toElement() + .tagName().lower() == "params"; +} + +XMLRPCResult XmlrpcJob::parseMessageResponse( const QDomDocument &doc ) +{ + XMLRPCResult response; + response.m_success = true; + + QDomNode paramNode = doc.documentElement().firstChild().firstChild(); + while ( !paramNode.isNull() ) { + response.m_data << demarshal( paramNode.firstChild().toElement() ); + paramNode = paramNode.nextSibling(); + } + + return response; +} + + + + + +bool XmlrpcJob::isFaultResponse( const QDomDocument &doc ) +{ + return doc.documentElement().firstChild().toElement() + .tagName().lower() == "fault"; +} + +XMLRPCResult XmlrpcJob::parseFaultResponse( const QDomDocument &doc ) +{ + XMLRPCResult response; + response.m_success = false; + + QDomNode errorNode = doc.documentElement().firstChild().firstChild(); + const QVariant errorVariant = demarshal( errorNode.toElement() ); + response.m_errorCode = errorVariant.toMap() [ "faultCode" ].toInt(); + response.m_errorString = errorVariant.toMap() [ "faultString" ].toString(); + + return response; +} + + + + + +QString XmlrpcJob::marshal( const QVariant &arg ) +{ + switch ( arg.type() ) + { + case QVariant::String: + case QVariant::CString: + return "<value><string>" + arg.toString() + "</string></value>\r\n"; + 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>" + KCodecs::base64Encode( arg.toByteArray() ) + + "</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 QValueList<QVariant> args = arg.toList(); + QValueList<QVariant>::ConstIterator it = args.begin(); + QValueList<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.begin(); + QMap<QString, QVariant>::ConstIterator end = map.end(); + for ( ; it != end; ++it ) + { + markup += "<member>\r\n"; + markup += "<name>" + it.key() + "</name>\r\n"; + markup += marshal( it.data() ); + markup += "</member>\r\n"; + } + markup += "</struct></value>\r\n"; + return markup; + } + default: + kdWarning() << "Failed to marshal unknown variant type: " + << arg.type() << endl; + }; + return QString::null; +} + +QVariant XmlrpcJob::demarshal( const QDomElement &elem ) +{ + Q_ASSERT( elem.tagName().lower() == "value" ); + + if ( !elem.hasChildNodes() ) { + // it doesn't have child nodes, so no explicit type name was given, + // i.e. <value>here comes the value</value> instead of + // <value><string>here comes the value</string></value> + // Assume <string> in that case: + // Actually, the element will still have a child node, so this will not help here. + // The dirty hack is at the end of this method. +kdDebug()<<"XmlrpcJob::demarshal: No child nodes, assume type=string. Text: "<<elem.text()<<endl; + return QVariant( elem.text() ); + } + +kdDebug()<<"Demarshalling element \"" << elem.text() <<"\"" << endl; + + const QDomElement typeElement = elem.firstChild().toElement(); + const QString typeName = typeElement.tagName().lower(); + + 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().lower() == "true" || typeElement.text() == "1" ) + return QVariant( true ); + else + return QVariant( false ); + } + else if ( typeName == "base64" ) + return QVariant( KCodecs::base64Decode( typeElement.text().latin1() ) ); + + else if ( typeName == "datetime" || typeName == "datetime.iso8601" ) { + + QString text( typeElement.text() ); + if ( text.find( QRegExp("^[0-9]{8,8}T") ) >= 0 ) { + // It's in the format 20041120T...., so adjust it to correct + // ISO 8601 Format 2004-11-20T..., else QDateTime::fromString won't work: + text = text.insert( 6, '-' ); + text = text.insert( 4, '-' ); + } + return QVariant( QDateTime::fromString( text, Qt::ISODate ) ); + + } else if ( typeName == "array" ) { + + QValueList<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 { + + kdWarning() << "Cannot demarshal unknown type " << typeName << ", text= " << typeElement.text() << endl; + // FIXME: This is just a workaround, for the issue mentioned at the beginning of this method. + return QVariant( elem.text() ); + } + + return QVariant(); +} + + + + + +/* Convenience methods */ + +XmlrpcJob* KIO::xmlrpcCall( const KURL& url, const QString &method, const QValueList<QVariant> ¶ms, bool showProgressInfo ) +{ + if ( url.isEmpty() ) { + kdWarning() << "Cannot execute call to " << method << ": empty server URL" << endl; + return 0; + } + XmlrpcJob *job = new XmlrpcJob( url, method, params, showProgressInfo ); +// job->addMetaData( "xmlrpcDepth", depth ); + + return job; +} + +XmlrpcJob* KIO::xmlrpcCall( const KURL& url, const QString &method, + const QVariant &arg, bool showProgressInfo ) +{ + QValueList<QVariant> args; + args << arg; + return KIO::xmlrpcCall( url, method, args, showProgressInfo ); +} + +XmlrpcJob* KIO::xmlrpcCall( const KURL& url, const QString &method, + const QStringList &arg, bool showProgressInfo ) +{ + QValueList<QVariant> args; + QStringList::ConstIterator it = arg.begin(); + QStringList::ConstIterator end = arg.end(); + for ( ; it != end; ++it ) + args << QVariant( *it ); + return KIO::xmlrpcCall( url, method, args, showProgressInfo ); +} + +template <typename T> +XmlrpcJob* KIO::xmlrpcCall( const KURL& url, const QString &method, + const QValueList<T>&arg, bool showProgressInfo ) +{ + QValueList<QVariant> args; + + typename QValueList<T>::ConstIterator it = arg.begin(); + typename QValueList<T>::ConstIterator end = arg.end(); + for ( ; it != end; ++it ) + args << QVariant( *it ); + return KIO::xmlrpcCall( url, method, args, showProgressInfo ); +} + +#include "xmlrpcjob.moc" diff --git a/kresources/blogging/xmlrpcjob.h b/kresources/blogging/xmlrpcjob.h new file mode 100644 index 000000000..cd657aa3b --- /dev/null +++ b/kresources/blogging/xmlrpcjob.h @@ -0,0 +1,123 @@ +// -*- c++ -*- +/* This file is part of the KDE libraries + Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com> + Based on the davjob: + Copyright (C) 2002 Jan-Pascal van Best <janpascal@vanbest.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 __kio_xmlrpcjob_h__ +#define __kio_xmlrpcjob_h__ + +#include <kurl.h> + +#include <qstring.h> +#include <qvaluelist.h> +#include <qdom.h> + +#include <kio/jobclasses.h> +#include <kio/global.h> + +namespace KIO { + + class XMLRPCResult; + +/** + * The transfer job pumps data into and/or out of a Slave. + * Data is sent to the slave on request of the slave ( dataReq ). + * If data coming from the slave can not be handled, the + * reading of data from the slave should be suspended. + * @see KIO::xmlrpcCall() + * @since 3.4 + */ +class XmlrpcJob : public TransferJob { +Q_OBJECT + + public: + /** Indicates the response type of the call + */ + enum XMLRPCResponseType { + XMLRPCMessageResponse, + XMLRPCFaultResponse, + XMLRPCUnknownResponse + }; + /** + * Use KIO::xmlrpcPropFind(), KIO::xmlrpcPropPatch() and + * KIO::xmlrpcSearch() to create a new XmlrpcJob. + */ + XmlrpcJob( const KURL& url, const QString& method, + const QValueList<QVariant> ¶ms, bool showProgressInfo ); + virtual ~XmlrpcJob(); + /** + * Returns the response as a QDomDocument. + * @return the response document + */ + QValueList<QVariant> &response() { return m_response; } + /** + * Returns the type of the response. + * @return the type of the response + */ + XMLRPCResponseType responseType() const { return m_responseType; } + + static QString markupCall( const QString &cmd, + const QValueList<QVariant> &args ); + protected slots: + virtual void slotFinished(); + virtual void slotData( const QByteArray &data); + + protected: + static QString marshal( const QVariant &arg ); + static QVariant demarshal( const QDomElement &e ); + + static bool isMessageResponse( const QDomDocument &doc ); + static bool isFaultResponse( const QDomDocument &doc ); + + static XMLRPCResult parseMessageResponse( const QDomDocument &doc ); + static XMLRPCResult parseFaultResponse( const QDomDocument &doc ); + + + private: + class XmlrpcJobPrivate; + XmlrpcJobPrivate *d; + QString m_str_response; + QValueList<QVariant> m_response; + XMLRPCResponseType m_responseType; +}; + +/** + * Creates a XmlrpcJob that calls a @p method of the API at the given @p url. + * + * @param url the URL of the XML-RPC Interface of the server + * @param method the name of the method to call + * @param params the arguments (as QValueList<QVariant>) for the method call. + * @param showProgressInfo true to show progress information + * @return the new XmlrpcJob + */ +XmlrpcJob* xmlrpcCall( const KURL& url, const QString &method, + const QValueList<QVariant> ¶ms, + bool showProgressInfo = true ); + +XmlrpcJob* xmlrpcCall( const KURL& url, const QString &method, + const QVariant &arg, bool showProgressInfo = true ); +XmlrpcJob* xmlrpcCall( const KURL& url, const QString &method, + const QStringList &arg, bool showProgressInfo = true ); +template <typename T> +XmlrpcJob* xmlrpcCall( const KURL& url, const QString &method, + const QValueList<T>&arg,bool showProgressInfo = true ); +} + +#endif |