diff options
Diffstat (limited to 'tderesources/blogging')
-rw-r--r-- | tderesources/blogging/API_Blog.cpp | 121 | ||||
-rw-r--r-- | tderesources/blogging/API_Blog.h | 163 | ||||
-rw-r--r-- | tderesources/blogging/API_Blogger.cpp | 332 | ||||
-rw-r--r-- | tderesources/blogging/API_Blogger.h | 57 | ||||
-rw-r--r-- | tderesources/blogging/Makefile.am | 29 | ||||
-rw-r--r-- | tderesources/blogging/blogging.desktop | 49 | ||||
-rw-r--r-- | tderesources/blogging/bloggingcalendaradaptor.cpp | 259 | ||||
-rw-r--r-- | tderesources/blogging/bloggingcalendaradaptor.h | 105 | ||||
-rw-r--r-- | tderesources/blogging/bloggingglobals.cpp | 53 | ||||
-rw-r--r-- | tderesources/blogging/bloggingglobals.h | 50 | ||||
-rw-r--r-- | tderesources/blogging/kcal_resourceblogging.cpp | 97 | ||||
-rw-r--r-- | tderesources/blogging/kcal_resourceblogging.h | 60 | ||||
-rw-r--r-- | tderesources/blogging/kcal_resourceblogging_plugin.cpp | 41 | ||||
-rw-r--r-- | tderesources/blogging/kcal_resourcebloggingconfig.cpp | 41 | ||||
-rw-r--r-- | tderesources/blogging/kcal_resourcebloggingconfig.h | 41 | ||||
-rw-r--r-- | tderesources/blogging/resourcebloggingsettings.ui | 330 | ||||
-rw-r--r-- | tderesources/blogging/xmlrpcjob.cpp | 430 | ||||
-rw-r--r-- | tderesources/blogging/xmlrpcjob.h | 124 |
18 files changed, 2382 insertions, 0 deletions
diff --git a/tderesources/blogging/API_Blog.cpp b/tderesources/blogging/API_Blog.cpp new file mode 100644 index 000000000..981390fa1 --- /dev/null +++ b/tderesources/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 <tqvariant.h> + +using namespace KBlog; + +APIBlog::APIBlog( const KURL &url, TQObject *parent, const char *name ) : + TQObject( parent, name ), + mServerURL( url ), mAppID( TQString() ), 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 TQString &postID ) +{ + BlogPosting *post = new BlogPosting(); + post->setPostID( postID ); + deletePost( post ); + delete post; +}*/ + +TQValueList<TQVariant> APIBlog::defaultArgs( const TQString &id ) +{ + TQValueList<TQVariant> args; + args << TQVariant( mAppID ); + if ( !id.isNull() ) { + args << TQVariant( id ); + } + args << TQVariant( mUsername ) + << TQVariant( mPassword ); + return args; +} + + +KCal::Journal *APIBlog::journalFromPosting( KBlog::BlogPosting *blog ) +{ + if ( !blog ) return 0; + KCal::Journal *j = new KCal::Journal(); + TQDateTime dt = blog->dateTime(); + TQDateTime creationDt = blog->creationDateTime(); + TQDateTime modificationDt = blog->modificationDateTime(); +kdDebug() << "dt ="<<dt.toString( TQt::ISODate ) << endl; +kdDebug() << "creationDt ="<<creationDt.toString( TQt::ISODate ) << endl; +kdDebug() << "modificationDt="<<modificationDt.toString( TQt::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( TQStringList( 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/tderesources/blogging/API_Blog.h b/tderesources/blogging/API_Blog.h new file mode 100644 index 000000000..9425bd5e6 --- /dev/null +++ b/tderesources/blogging/API_Blog.h @@ -0,0 +1,163 @@ +/************************************************************************** +* 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 <tqobject.h> +#include <tqstring.h> +#include <tqvaluelist.h> +#include <tqdatetime.h> + +/** +This is the main interface for blog backends +@author ian reinhart geiser, Reinhold Kainhofer +*/ + +namespace KBlog { + +class BlogPosting +{ +public: + BlogPosting() {} + virtual ~BlogPosting() {} + + TQString userID() const { return mUserID; } + void setUserID( const TQString &userID ) { mUserID = userID; } + + TQString blogID() const { return mBlogID; } + void setBlogID( const TQString &blogID ) { mBlogID = blogID; } + + TQString postID() const { return mPostID; } + void setPostID( const TQString &postID ) { assignPostID( postID ); mPostID = postID; } + + TQString title() const { return mTitle; } + void setTitle( const TQString &title ) { mTitle = title; } + + TQString content() const { return mContent; } + void setContent( const TQString &content ) { mContent = content; } + + TQString category() const { return mCategory; } + void setCategory( const TQString &category ) { mCategory = category; } + + TQString fingerprint() const { return mFingerprint; } + void setFingerprint( const TQString &fp ) { mFingerprint = fp; } + + TQDateTime dateTime() const { return mDateTime; } + void setDateTime( const TQDateTime &datetime ) { mDateTime = datetime; } + + TQDateTime creationDateTime() const { return mCreationDateTime; } + void setCreationDateTime( const TQDateTime &datetime ) { mCreationDateTime = datetime; } + + TQDateTime modificationDateTime() const { return mModificationDateTime; } + void setModificationDateTime( const TQDateTime &datetime ) { mModificationDateTime = datetime; } + + virtual void wasDeleted( bool ) {} + virtual void wasUploaded( bool ) {} + virtual void error( int /*code*/, const TQString &/*error*/ ) {} + +protected: + // Override this method to detect the new postID assigned when adding a new post + virtual void assignPostID( const TQString &/*postID*/ ) {} + TQString mUserID; + TQString mBlogID; + TQString mPostID; + TQString mTitle; + TQString mContent; + TQString mCategory; + TQString mFingerprint; + TQDateTime mDateTime; + TQDateTime mCreationDateTime; + TQDateTime mModificationDateTime; +}; + + +class APIBlog : public TQObject +{ + Q_OBJECT + + public: + APIBlog( const KURL &server, TQObject *parent = 0L, const char *name = 0L ); + virtual ~APIBlog(); + virtual TQString interfaceName() const = 0; + + void setAppID( const TQString &appID ) { mAppID = appID; } + TQString appID() const { return mAppID; } + + void setPassword( const TQString &pass ) { mPassword = pass; } + TQString password() const { return mPassword; } + + void setUsername( const TQString &uname ) { mUsername = uname; } + TQString 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 TQString getFunctionName( blogFunctions type ) = 0; + virtual TQValueList<TQVariant> defaultArgs( const TQString &id = TQString() ); + + virtual TDEIO::Job *createUserInfoJob() = 0; + virtual TDEIO::Job *createListFoldersJob() = 0; + virtual TDEIO::TransferJob *createListItemsJob( const KURL &url ) = 0; + virtual TDEIO::TransferJob *createDownloadJob( const KURL &url ) = 0; + virtual TDEIO::TransferJob *createUploadJob( const KURL &url, KBlog::BlogPosting *posting ) = 0; + virtual TDEIO::TransferJob *createUploadNewJob( KBlog::BlogPosting *posting ) = 0; + virtual TDEIO::Job *createRemoveJob( const KURL &url, const TQString &postid ) = 0; + + virtual bool interpretUserInfoJob( TDEIO::Job *job ) = 0; + virtual void interpretListFoldersJob( TDEIO::Job *job ) = 0; + virtual bool interpretListItemsJob( TDEIO::Job *job ) = 0; + virtual bool interpretDownloadItemsJob( TDEIO::Job *job ) = 0; + + static KCal::Journal *journalFromPosting( KBlog::BlogPosting *post ); + static KBlog::BlogPosting *postingFromJournal( KCal::Journal *journal ); + + signals: + // TODO: Connect these + void userInfoRetrieved( const TQString &nickname, const TQString &userid, const TQString &email ); + void folderInfoRetrieved( const TQString &id, const TQString &name ); + + void itemOnServer( const KURL &remoteURL ); + void itemDownloaded( KCal::Incidence *j, const TQString &localID, + const KURL &remoteURL, const TQString &fingerprint, + const TQString &storageLocation ); + + + protected: + + KURL mServerURL; + TQString mPassword; + TQString mUsername; + TQString mAppID; + int mDownloadCount; +}; + +} +#endif diff --git a/tderesources/blogging/API_Blogger.cpp b/tderesources/blogging/API_Blogger.cpp new file mode 100644 index 000000000..69a722e22 --- /dev/null +++ b/tderesources/blogging/API_Blogger.cpp @@ -0,0 +1,332 @@ +/* + This file is part of tdepim. + + 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; + +TQString 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 TQString(); + } +} + + + + +TDEIO::Job *APIBlogger::createUserInfoJob() +{ + kdDebug() << "read user info..." << endl; + TQValueList<TQVariant> args( defaultArgs() ); + return TDEIO::xmlrpcCall( mServerURL, getFunctionName( bloggerGetUserInfo ), args, false ); +} + +TDEIO::Job *APIBlogger::createListFoldersJob() +{ + // TODO: Check if we're already authenticated. If not, do it! +// if ( isValid() ) { + kdDebug() << "Fetch List of Blogs..." << endl; + TQValueList<TQVariant> args( defaultArgs() ); + return TDEIO::xmlrpcCall( mServerURL, getFunctionName( bloggerGetUsersBlogs ), args, false ); +// } else { +// warningNotInitialized(); +// return 0; +// } +} + +TDEIO::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; + TQValueList<TQVariant> args( defaultArgs( url.url() ) ); + args << TQVariant( mDownloadCount ); + return TDEIO::xmlrpcCall( mServerURL, getFunctionName( bloggerGetRecentPosts ), args, false ); +// } else { +// warningNotInitialized(); +// return 0; +// } +} + +TDEIO::TransferJob *APIBlogger::createDownloadJob( const KURL &url ) +{ +// if ( isValid() ){ + kdDebug() << "Fetch Posting with url " << url.url() << endl; + TQValueList<TQVariant> args( defaultArgs( url.url() ) ); + return TDEIO::xmlrpcCall( mServerURL, getFunctionName( bloggerGetPost ), args, false ); +// } else { +// warningNotInitialized(); +// return 0; +// } +} + +TDEIO::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; + TQValueList<TQVariant> args( defaultArgs( posting->postID() ) ); + args << TQVariant( posting->content() ); + args << TQVariant( /*publish=*/true, 0 ); + return TDEIO::xmlrpcCall( mServerURL, getFunctionName( bloggerEditPost ), args, false ); +// } else { +// warningNotInitialized(); +// return 0; +// } +} + +TDEIO::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; + TQValueList<TQVariant> args( defaultArgs( posting->blogID() ) ); + args << TQVariant( posting->content() ); + args << TQVariant( /*publish=*/true, 0 ); + return TDEIO::xmlrpcCall( mServerURL, getFunctionName( bloggerNewPost ), args, false ); +// } else { +// warningNotInitialized(); +// return 0; +// } +} + +TDEIO::Job *APIBlogger::createRemoveJob( const KURL &/*url*/, const TQString &postid ) +{ +kdDebug() << "APIBlogger::createRemoveJob: postid=" << postid << endl; +// if ( isValid() ){ + TQValueList<TQVariant> args( defaultArgs( postid ) ); + args << TQVariant( /*publish=*/true, 0 ); + return TDEIO::xmlrpcCall( mServerURL, getFunctionName( bloggerDeletePost ), args, false ); +// } else { +// warningNotInitialized(); +// return 0; +// } +} + + + + +bool APIBlogger::interpretUserInfoJob( TDEIO::Job *job ) +{ + // TODO: Implement user authentication +// isValid = true; + TDEIO::XmlrpcJob *trfjob = dynamic_cast<TDEIO::XmlrpcJob*>(job); + if ( job->error() || !trfjob ) { + // TODO: Error handling + return false; + } else if ( trfjob ) { + TQValueList<TQVariant> message( trfjob->response() ); + + kdDebug () << "TOP: " << message[ 0 ].typeName() << endl; + const TQValueList<TQVariant> posts = message; + TQValueList<TQVariant>::ConstIterator it = posts.begin(); + TQValueList<TQVariant>::ConstIterator end = posts.end(); + for ( ; it != end; ++it ) { + kdDebug () << "MIDDLE: " << ( *it ).typeName() << endl; + const TQMap<TQString, TQVariant> postInfo = ( *it ).toMap(); + const TQString nickname = postInfo[ "nickname" ].toString(); + const TQString userid = postInfo[ "userid" ].toString(); + const TQString 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( TDEIO::Job *job ) +{ +kdDebug() << "APIBlogger::interpretListFoldersJob" << endl; + TDEIO::XmlrpcJob *trfjob = dynamic_cast<TDEIO::XmlrpcJob*>(job); + if ( job->error() || !trfjob ) { + // TODO: Error handling + } else { +kdDebug() << "APIBlogger::interpretListFoldersJob, no error!" << endl; + TQValueList<TQVariant> message( trfjob->response() ); + kdDebug () << "TOP: " << message[ 0 ].typeName() << endl; + + const TQValueList<TQVariant> posts = message[ 0 ].toList(); + TQValueList<TQVariant>::ConstIterator it = posts.begin(); + TQValueList<TQVariant>::ConstIterator end = posts.end(); + for ( ; it != end; ++it ) { + kdDebug () << "MIDDLE: " << ( *it ).typeName() << endl; + const TQMap<TQString, TQVariant> postInfo = ( *it ).toMap(); + + const TQString id( postInfo[ "blogid" ].toString() ); + const TQString name( postInfo[ "blogName" ].toString() ); + const TQString 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( TDEIO::Job *job ) +{ + return interpretDownloadItemsJob( job ); +} + +bool APIBlogger::interpretDownloadItemsJob( TDEIO::Job *job ) +{ + kdDebug(5800)<<"APIBlogger::interpretDownloadItemJob"<<endl; + TDEIO::XmlrpcJob *trfjob = dynamic_cast<TDEIO::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! + TQValueList<TQVariant> message( trfjob->response() ); + kdDebug () << "TOP: " << message[ 0 ].typeName() << endl; + + const TQValueList<TQVariant> postReceived = message[ 0 ].toList(); + TQValueList<TQVariant>::ConstIterator it = postReceived.begin(); + TQValueList<TQVariant>::ConstIterator end = postReceived.end(); + success = true; + for ( ; it != end; ++it ) { + BlogPosting posting; + kdDebug () << "MIDDLE: " << ( *it ).typeName() << endl; + const TQMap<TQString, TQVariant> 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 TQMap<TQString, TQVariant> &postInfo ) +{ + // FIXME: + if ( !post ) return false; + TQStringList mapkeys = postInfo.keys(); + kdDebug() << endl << "Keys: " << mapkeys.join(", ") << endl << endl; + + TQString fp( TQString() ); + + TQDateTime dt( postInfo[ "dateCreated" ].toDateTime() ); + if ( dt.isValid() && !dt.isNull() ) { + post->setCreationDateTime( dt ); + TQString fp = dt.toString( TQt::ISODate ); + } + dt = postInfo[ "postDate" ].toDateTime(); + if ( dt.isValid() && !dt.isNull() ) { + post->setDateTime( dt ); + fp = dt.toString( TQt::ISODate ); + } + dt = postInfo[ "lastModified" ].toDateTime(); + if ( dt.isValid() && !dt.isNull() ) { + post->setModificationDateTime( dt ); + fp = dt.toString( TQt::ISODate ); + } + post->setFingerprint( fp ); + + post->setUserID( postInfo[ "userid" ].toString() ); + post->setPostID( postInfo[ "postid" ].toString() ); + + TQString title( postInfo[ "title" ].toString() ); + TQString description( postInfo[ "description" ].toString() ); + TQString contents( postInfo[ "content" ].toString() ); + TQString 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; + TQString catTagOpen = mTemplate.categoryTagOpen(); + TQString catTagClose = mTemplate.categoryTagClose(); + TQString titleTagOpen = mTemplate.titleTagOpen(); + TQString 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/tderesources/blogging/API_Blogger.h b/tderesources/blogging/API_Blogger.h new file mode 100644 index 000000000..d7d5f43b9 --- /dev/null +++ b/tderesources/blogging/API_Blogger.h @@ -0,0 +1,57 @@ + /* + This file is part of tdepim. + + 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 <tqstring.h> +#include <tqvariant.h> +#include <tqvaluelist.h> + +namespace KBlog { + +class APIBlogger : public APIBlog +{ + public: + APIBlogger( const KURL &server, TQObject *parent = 0L, const char *name = 0L ) : APIBlog( server, parent, name ) {} + TQString getFunctionName( blogFunctions type ); + TQString interfaceName() const { return "Blogger API 1.0"; } + + + TDEIO::Job *createUserInfoJob(); + TDEIO::Job *createListFoldersJob(); + TDEIO::TransferJob *createListItemsJob( const KURL &url ); + TDEIO::TransferJob *createDownloadJob( const KURL &url ); + TDEIO::TransferJob *createUploadJob( const KURL &url, KBlog::BlogPosting *posting ); + TDEIO::TransferJob *createUploadNewJob( KBlog::BlogPosting *posting ); + TDEIO::Job *createRemoveJob( const KURL &url, const TQString &postid ); + + bool interpretUserInfoJob( TDEIO::Job *job ); + void interpretListFoldersJob( TDEIO::Job *job ); + bool interpretListItemsJob( TDEIO::Job *job ); + bool interpretDownloadItemsJob( TDEIO::Job *job ); + protected: + bool readPostingFromMap( BlogPosting *post, const TQMap<TQString, TQVariant> &postInfo ); +}; + +} +#endif diff --git a/tderesources/blogging/Makefile.am b/tderesources/blogging/Makefile.am new file mode 100644 index 000000000..563f46b20 --- /dev/null +++ b/tderesources/blogging/Makefile.am @@ -0,0 +1,29 @@ +INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tderesources/lib -I../lib -I$(top_srcdir)/tderesources/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)/libtdepim/libtdepim.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)/tderesources/kcal +kcal_service_DATA = blogging.desktop + +METASOURCES = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kres_blogging.pot + +kcal_resourceblogging.lo: ../lib/tderesources_groupwareprefs.h diff --git a/tderesources/blogging/blogging.desktop b/tderesources/blogging/blogging.desktop new file mode 100644 index 000000000..7714a362a --- /dev/null +++ b/tderesources/blogging/blogging.desktop @@ -0,0 +1,49 @@ +[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[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-TDE-Library=kcal_blogging +Type=Service +ServiceTypes=KResources/Plugin +X-TDE-ResourceFamily=calendar +X-TDE-ResourceType=blogging diff --git a/tderesources/blogging/bloggingcalendaradaptor.cpp b/tderesources/blogging/bloggingcalendaradaptor.cpp new file mode 100644 index 000000000..2ed925a88 --- /dev/null +++ b/tderesources/blogging/bloggingcalendaradaptor.cpp @@ -0,0 +1,259 @@ +/* + This file is part of tdepim. + + 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: +/*TQString BloggingCalendarAdaptor::mAppID = + TQString("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; +} + +TDEIO::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 ); +} + +TDEIO::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, TQT_SIGNAL( userInfoRetrieved( const TQString &, const TQString &, + const TQString & ) ), + TQT_SLOT( slotUserInfoRetrieved( const TQString &, const TQString &, + const TQString & ) ) ); + connect( api, TQT_SIGNAL( folderInfoRetrieved( const TQString &, const TQString & ) ), + TQT_SLOT( slotFolderInfoRetrieved( const TQString&, const TQString & ) ) ); + connect( api, TQT_SIGNAL( itemOnServer( const KURL & ) ), + TQT_SIGNAL( itemOnServer( const KURL & ) ) ); + connect( api, TQT_SIGNAL( itemDownloaded( KCal::Incidence *, const TQString &, + const KURL &, const TQString &, const TQString & ) ), + TQT_SLOT( calendarItemDownloaded( KCal::Incidence *, const TQString &, + const KURL &, const TQString &, const TQString & ) ) ); + +} + +KPIM::GroupwareUploadItem *BloggingCalendarAdaptor::newUploadItem( KCal::Incidence*it, + KPIM::GroupwareUploadItem::UploadType type ) +{ + return new BloggingUploadItem( mAPI, this, it, type ); +} + + + +void BloggingCalendarAdaptor::slotFolderInfoRetrieved( const TQString &id, const TQString &name ) +{ + emit folderInfoRetrieved( KURL(id), name, KPIM::FolderLister::Journal ); +} + +void BloggingCalendarAdaptor::slotUserInfoRetrieved( const TQString &/*nick*/, + const TQString &/*user*/, const TQString &/*email*/ ) +{ +kdDebug() << "BloggingCalendarAdaptor::slotUserInfoRetrieved"<<endl; + mAuthenticated = true; +} + +void BloggingCalendarAdaptor::setBaseURL( const KURL &url ) +{ + if ( mAPI ) { + mAPI->setURL( url ); + } +} + +void BloggingCalendarAdaptor::setUser( const TQString &user ) +{ + CalendarAdaptor::setUser( user ); + if ( mAPI ) { + mAPI->setUsername( user ); + } +} + +void BloggingCalendarAdaptor::setPassword( const TQString &password ) +{ + CalendarAdaptor::setPassword( password ); + if ( mAPI ) { + mAPI->setPassword( password ); + } +} + +void BloggingCalendarAdaptor::setUserPassword( KURL & ) +{ + kdDebug(5800) << "BloggingCalendarAdaptor::setUserPassword" << endl; +} + + + +TDEIO::Job *BloggingCalendarAdaptor::createLoginJob( const KURL &url, + const TQString &user, + const TQString &password ) +{ + if ( mAPI ) { + mAPI->setURL( url ); + mAPI->setUsername( user ); + mAPI->setPassword( password ); + return mAPI->createUserInfoJob(); + } else return 0; +} + +TDEIO::Job *BloggingCalendarAdaptor::createListFoldersJob( const KURL &/*url*/ ) +{ + if ( mAPI ) { + return mAPI->createListFoldersJob(); + } else return 0; +} + +TDEIO::TransferJob *BloggingCalendarAdaptor::createListItemsJob( const KURL &url ) +{ + if ( mAPI ) { + return mAPI->createListItemsJob( url ); + } else return 0; +} + +TDEIO::TransferJob *BloggingCalendarAdaptor::createDownloadJob( const KURL &url, + KPIM::FolderLister::ContentType ctype ) +{ + if ( mAPI && (ctype & KPIM::FolderLister::Journal) ) { + return mAPI->createDownloadJob( url ); + } else return 0; +} + +TDEIO::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( TDEIO::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( TDEIO::Job *job, KPIM::FolderLister * ) +{ +kdDebug() << "BloggingCalendarAdaptor::interpretListFoldersJob" << endl; + if ( mAPI && job ) { + mAPI->interpretListFoldersJob( job ); + } +} + + +bool BloggingCalendarAdaptor::interpretListItemsJob( TDEIO::Job *job, + const TQString &/*jobData*/ ) +{ + if ( mAPI ) { + return mAPI->interpretListItemsJob( job ); + } else { + return false; + } +} + + +bool BloggingCalendarAdaptor::interpretDownloadItemsJob( TDEIO::Job *job, + const TQString &/*jobData*/ ) +{ + if ( mAPI ) { + return mAPI->interpretDownloadItemsJob( job ); + } else { + return false; + } +} + +#include "bloggingcalendaradaptor.moc" diff --git a/tderesources/blogging/bloggingcalendaradaptor.h b/tderesources/blogging/bloggingcalendaradaptor.h new file mode 100644 index 000000000..ee6d292aa --- /dev/null +++ b/tderesources/blogging/bloggingcalendaradaptor.h @@ -0,0 +1,105 @@ + /* + This file is part of tdepim. + + 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 TDEIO { +class Job; +} + +namespace KCal { + +class BloggingUploadItem : public KPIM::GroupwareUploadItem +{ + public: + BloggingUploadItem( KBlog::APIBlog *api, CalendarAdaptor *adaptor, KCal::Incidence *incidence, UploadType type ); + virtual ~BloggingUploadItem(); + virtual TDEIO::TransferJob *createUploadNewJob( + KPIM::GroupwareDataAdaptor *adaptor, const KURL &baseurl ); + virtual TDEIO::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(); + TQValueList<KPIM::FolderLister::ContentType> supportedTypes() + { + TQValueList<KPIM::FolderLister::ContentType> types; + types << KPIM::FolderLister::Journal; + return types; + } + + TQCString identifier() const { return "KCalResourceBlogging"; } + long flags() const { return GWResNeedsLogon; } + + void setBaseURL( const KURL &url ); + void setUser( const TQString &user ); + void setPassword( const TQString &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 ); + + TDEIO::Job *createLoginJob( const KURL &url, const TQString &user, + const TQString &password ); + TDEIO::Job *createListFoldersJob( const KURL &url ); + TDEIO::TransferJob *createListItemsJob( const KURL &url ); + TDEIO::TransferJob *createDownloadJob( const KURL &url, + KPIM::FolderLister::ContentType ctype ); + TDEIO::Job *createRemoveJob( const KURL &url, KPIM::GroupwareUploadItem *deleteItem ); + + bool interpretLoginJob( TDEIO::Job *job ); + void interpretListFoldersJob( TDEIO::Job *job, KPIM::FolderLister * ); + bool interpretListItemsJob( TDEIO::Job *job, const TQString &jobData ); + bool interpretDownloadItemsJob( TDEIO::Job *job, const TQString &jobData ); + + public slots: + void slotFolderInfoRetrieved( const TQString &id, const TQString &name ); + void slotUserInfoRetrieved( const TQString &nick, const TQString &user, + const TQString &email ); + + protected: + KPIM::GroupwareUploadItem *newUploadItem( KCal::Incidence*it, + KPIM::GroupwareUploadItem::UploadType type ); + + KBlog::APIBlog *mAPI; + bool mAuthenticated; + static TQString mAppID; +}; + +} + +#endif diff --git a/tderesources/blogging/bloggingglobals.cpp b/tderesources/blogging/bloggingglobals.cpp new file mode 100644 index 000000000..53743e9a6 --- /dev/null +++ b/tderesources/blogging/bloggingglobals.cpp @@ -0,0 +1,53 @@ +/* + This file is part of tdepim. + + 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" + +TQString BloggingGlobals::mAppID = TQString("20ffffffd7ffffffc5ffffffbdffffff87ffffffb72d39fffffffe5c4bffffffcfffffff80ffffffd4665cfffffff375ffffff88ffffff871a0cffffff8029"); + +TQString 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 TQString(); + } +} + +TQValueList<TQVariant> BloggingGlobals::defaultArgs( const TQString &user, const TQString &pw, const TQString &id ) +{ + TQValueList<TQVariant> args; + args << TQVariant( mAppID ); + if ( !id.isNull() ) { + args << TQVariant( id ); + } + args << TQVariant( user ) + << TQVariant( pw ); + return args; +} + diff --git a/tderesources/blogging/bloggingglobals.h b/tderesources/blogging/bloggingglobals.h new file mode 100644 index 000000000..74eafdf75 --- /dev/null +++ b/tderesources/blogging/bloggingglobals.h @@ -0,0 +1,50 @@ + /* + This file is part of tdepim. + + 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 <tqstring.h> +#include <tqvariant.h> +#include <tqvaluelist.h> + +class BloggingGlobals +{ + public: + BloggingGlobals() {} + + enum blogFunctions { + bloggerGetUserInfo, + bloggerGetUsersBlogs, + bloggerGetRecentPosts, + bloggerNewPost, + bloggerEditPost, + bloggerDeletePost, + bloggerGetPost, + bloggerGetTemplate, + bloggerSetTemplate + }; + + static TQString getFunctionName( blogFunctions type ); + static TQValueList<TQVariant> defaultArgs( const TQString &user, const TQString &pw, const TQString &id = TQString() ); + static TQString mAppID; +}; + +#endif diff --git a/tderesources/blogging/kcal_resourceblogging.cpp b/tderesources/blogging/kcal_resourceblogging.cpp new file mode 100644 index 000000000..6f0b1d4bf --- /dev/null +++ b/tderesources/blogging/kcal_resourceblogging.cpp @@ -0,0 +1,97 @@ +/* + This file is part of tdepim. + + 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 <tderesources_groupwareprefs.h> + +using namespace KCal; + +KBlog::APIBlog *ResourceBlogging::mAPI = 0; + +ResourceBlogging::ResourceBlogging() + : ResourceGroupwareBase() +{ + init(); +} + +ResourceBlogging::ResourceBlogging( const TDEConfig *config ) + : ResourceGroupwareBase( config ) +{ + init(); + if ( config ) { + readConfig( config ); + } else { + setResourceName( i18n( "Blogs" ) ); + } +} + +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 TDEConfig *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() ); + } +// TQString 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( TDEConfig *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/tderesources/blogging/kcal_resourceblogging.h b/tderesources/blogging/kcal_resourceblogging.h new file mode 100644 index 000000000..4e850d148 --- /dev/null +++ b/tderesources/blogging/kcal_resourceblogging.h @@ -0,0 +1,60 @@ + /* + This file is part of tdepim. + + 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 <tdepimmacros.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 TDEConfig * ); + + void readConfig( const TDEConfig *config ); + void writeConfig( TDEConfig *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/tderesources/blogging/kcal_resourceblogging_plugin.cpp b/tderesources/blogging/kcal_resourceblogging_plugin.cpp new file mode 100644 index 000000000..4cc3dd8cb --- /dev/null +++ b/tderesources/blogging/kcal_resourceblogging_plugin.cpp @@ -0,0 +1,41 @@ +/* + This file is part of tdepim. + + 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() + { + TDEGlobal::locale()->insertCatalogue( "tdepimresources" ); + TDEGlobal::locale()->insertCatalogue( "kres_blogging" ); + return new BloggingFactory; + } +} diff --git a/tderesources/blogging/kcal_resourcebloggingconfig.cpp b/tderesources/blogging/kcal_resourcebloggingconfig.cpp new file mode 100644 index 000000000..bd999ffe3 --- /dev/null +++ b/tderesources/blogging/kcal_resourcebloggingconfig.cpp @@ -0,0 +1,41 @@ +/* + This file is part of tdepim. + + 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( TQWidget *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/tderesources/blogging/kcal_resourcebloggingconfig.h b/tderesources/blogging/kcal_resourcebloggingconfig.h new file mode 100644 index 000000000..b7584167c --- /dev/null +++ b/tderesources/blogging/kcal_resourcebloggingconfig.h @@ -0,0 +1,41 @@ +/* + This file is part of tdepim. + + 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 <tdepimmacros.h> +#include <kcal_resourcegroupwarebaseconfig.h> + +namespace KCal { + +class KDE_EXPORT ResourceBloggingConfig : public ResourceGroupwareBaseConfig +{ + Q_OBJECT + + public: + ResourceBloggingConfig( TQWidget *parent = 0, const char *name = 0 ); + + public slots: + virtual void saveSettings( KRES::Resource *resource ); +}; + +} + +#endif diff --git a/tderesources/blogging/resourcebloggingsettings.ui b/tderesources/blogging/resourcebloggingsettings.ui new file mode 100644 index 000000000..7d7e02279 --- /dev/null +++ b/tderesources/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="TQWidget"> + <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="TQLayoutWidget"> + <property name="name"> + <cstring>layout12</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <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="TQGroupBox"> + <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="TQLabel" 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="TQLabel" 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="TQLabel" 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="TQLabel" 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="TQGroupBox"> + <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="TQLabel" 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="TQLabel" 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/tderesources/blogging/xmlrpcjob.cpp b/tderesources/blogging/xmlrpcjob.cpp new file mode 100644 index 000000000..f2e516308 --- /dev/null +++ b/tderesources/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 <tqvariant.h> +#include <tqregexp.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kio/http.h> +#include <kmdcodec.h> +#include <kio/davjob.h> + + +#define KIO_ARGS TQByteArray packedArgs; \ + TQDataStream stream( packedArgs, IO_WriteOnly ); stream + +using namespace TDEIO; + +namespace TDEIO { + class XMLRPCResult + { + friend class XmlrpcJob; + public: + XMLRPCResult() {} + bool success() const { return m_success; } + int errorCode() const { return m_errorCode; } + TQString errorString() const { return m_errorString; } + TQValueList<TQVariant> data() const { return m_data; } + private: + bool m_success; + int m_errorCode; + TQString m_errorString; + TQValueList<TQVariant> m_data; + }; +} + +class XmlrpcJob::XmlrpcJobPrivate +{ +public: +// TQByteArray savedStaticData; +}; + + +XmlrpcJob::XmlrpcJob( const KURL& url, const TQString& method, + const TQValueList<TQVariant> ¶ms, bool showProgressInfo) + : TransferJob( url, TDEIO::CMD_SPECIAL, TQByteArray(), TQByteArray(), + showProgressInfo ) +{ + d = new XmlrpcJobPrivate; + // We couldn't set the args when calling the parent constructor, + // so do it now. + TQDataStream 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; + + TQString 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; +} + +TQString XmlrpcJob::markupCall( const TQString &cmd, + const TQValueList<TQVariant> &args ) +{ +kdDebug()<<"XmlrpcJob::markupCall, cmd="<<cmd<<endl; + TQString markup = "<?xml version=\"1.0\" ?>\r\n<methodCall>\r\n"; + + markup += "<methodName>" + cmd + "</methodName>\r\n"; + + if ( !args.isEmpty() ) + { + markup += "<params>\r\n"; + TQValueList<TQVariant>::ConstIterator it = args.begin(); + TQValueList<TQVariant>::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 TQByteArray& data ) +{ +kdDebug()<<"XmlrpcJob::slotData()"<<endl; + if ( m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error ) + m_str_response.append( TQString( 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() ) { + TQDataStream 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)TDEIO::HTTP_POST) ) { + m_packedArgs.truncate(0); + TQDataStream stream( m_packedArgs, IO_WriteOnly ); + stream << (int)7 << m_redirectionURL << (int)TDEIO::HTTP_POST; + } + } else */ + + kdDebug() << "\033[35;40mResult: " << m_str_response << "\033[0;0m" << endl; + TQDomDocument doc; + TQString 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 << TQVariant( parseFaultResponse( doc ).errorString() ); + m_responseType = XMLRPCFaultResponse; + } else { + // TODO: Set the error of the job + m_response.clear(); + m_response << TQVariant( 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 TQDomDocument &doc ) +{ + return doc.documentElement().firstChild().toElement() + .tagName().lower() == "params"; +} + +XMLRPCResult XmlrpcJob::parseMessageResponse( const TQDomDocument &doc ) +{ + XMLRPCResult response; + response.m_success = true; + + TQDomNode paramNode = doc.documentElement().firstChild().firstChild(); + while ( !paramNode.isNull() ) { + response.m_data << demarshal( paramNode.firstChild().toElement() ); + paramNode = paramNode.nextSibling(); + } + + return response; +} + + + + + +bool XmlrpcJob::isFaultResponse( const TQDomDocument &doc ) +{ + return doc.documentElement().firstChild().toElement() + .tagName().lower() == "fault"; +} + +XMLRPCResult XmlrpcJob::parseFaultResponse( const TQDomDocument &doc ) +{ + XMLRPCResult response; + response.m_success = false; + + TQDomNode errorNode = doc.documentElement().firstChild().firstChild(); + const TQVariant errorVariant = demarshal( errorNode.toElement() ); + response.m_errorCode = errorVariant.toMap() [ "faultCode" ].toInt(); + response.m_errorString = errorVariant.toMap() [ "faultString" ].toString(); + + return response; +} + + + + + +TQString XmlrpcJob::marshal( const TQVariant &arg ) +{ + switch ( arg.type() ) + { + case TQVariant::String: + case TQVariant::CString: + return "<value><string>" + arg.toString() + "</string></value>\r\n"; + case TQVariant::Int: + return "<value><int>" + TQString::number( arg.toInt() ) + + "</int></value>\r\n"; + case TQVariant::Double: + return "<value><double>" + TQString::number( arg.toDouble() ) + + "</double></value>\r\n"; + case TQVariant::Bool: + { + TQString markup = "<value><boolean>"; + markup += arg.toBool() ? "1" : "0"; + markup += "</boolean></value>\r\n"; + return markup; + } + case TQVariant::ByteArray: + return "<value><base64>" + KCodecs::base64Encode( arg.toByteArray() ) + + "</base64></value>\r\n"; + case TQVariant::DateTime: + return "<value><datetime.iso8601>" + + arg.toDateTime().toString( TQt::ISODate ) + + "</datetime.iso8601></value>\r\n"; + case TQVariant::List: + { + TQString markup = "<value><array><data>\r\n"; + const TQValueList<TQVariant> args = arg.toList(); + TQValueList<TQVariant>::ConstIterator it = args.begin(); + TQValueList<TQVariant>::ConstIterator end = args.end(); + for ( ; it != end; ++it ) + markup += marshal( *it ); + markup += "</data></array></value>\r\n"; + return markup; + } + case TQVariant::Map: + { + TQString markup = "<value><struct>\r\n"; + TQMap<TQString, TQVariant> map = arg.toMap(); + TQMap<TQString, TQVariant>::ConstIterator it = map.begin(); + TQMap<TQString, TQVariant>::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 TQString(); +} + +TQVariant XmlrpcJob::demarshal( const TQDomElement &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 TQVariant( elem.text() ); + } + +kdDebug()<<"Demarshalling element \"" << elem.text() <<"\"" << endl; + + const TQDomElement typeElement = elem.firstChild().toElement(); + const TQString typeName = typeElement.tagName().lower(); + + if ( typeName == "string" ) + return TQVariant( typeElement.text() ); + else if ( typeName == "i4" || typeName == "int" ) + return TQVariant( typeElement.text().toInt() ); + else if ( typeName == "double" ) + return TQVariant( typeElement.text().toDouble() ); + else if ( typeName == "boolean" ) + { + if ( typeElement.text().lower() == "true" || typeElement.text() == "1" ) + return TQVariant( true ); + else + return TQVariant( false ); + } + else if ( typeName == "base64" ) + return TQVariant( KCodecs::base64Decode( typeElement.text().latin1() ) ); + + else if ( typeName == "datetime" || typeName == "datetime.iso8601" ) { + + TQString text( typeElement.text() ); + if ( text.find( TQRegExp("^[0-9]{8,8}T") ) >= 0 ) { + // It's in the format 20041120T...., so adjust it to correct + // ISO 8601 Format 2004-11-20T..., else TQDateTime::fromString won't work: + text = text.insert( 6, '-' ); + text = text.insert( 4, '-' ); + } + return TQVariant( TQDateTime::fromString( text, TQt::ISODate ) ); + + } else if ( typeName == "array" ) { + + TQValueList<TQVariant> values; + TQDomNode valueNode = typeElement.firstChild().firstChild(); + while ( !valueNode.isNull() ) { + values << demarshal( valueNode.toElement() ); + valueNode = valueNode.nextSibling(); + } + return TQVariant( values ); + + } else if ( typeName == "struct" ) { + + TQMap<TQString, TQVariant> map; + TQDomNode memberNode = typeElement.firstChild(); + while ( !memberNode.isNull() ) { + const TQString key = memberNode.toElement().elementsByTagName( "name" ).item( 0 ).toElement().text(); + const TQVariant data = demarshal( memberNode.toElement().elementsByTagName( "value" ).item( 0 ).toElement() ); + map[ key ] = data; + memberNode = memberNode.nextSibling(); + } + return TQVariant( 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 TQVariant( elem.text() ); + } + + return TQVariant(); +} + + + + + +/* Convenience methods */ + +XmlrpcJob* TDEIO::xmlrpcCall( const KURL& url, const TQString &method, const TQValueList<TQVariant> ¶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* TDEIO::xmlrpcCall( const KURL& url, const TQString &method, + const TQVariant &arg, bool showProgressInfo ) +{ + TQValueList<TQVariant> args; + args << arg; + return TDEIO::xmlrpcCall( url, method, args, showProgressInfo ); +} + +XmlrpcJob* TDEIO::xmlrpcCall( const KURL& url, const TQString &method, + const TQStringList &arg, bool showProgressInfo ) +{ + TQValueList<TQVariant> args; + TQStringList::ConstIterator it = arg.begin(); + TQStringList::ConstIterator end = arg.end(); + for ( ; it != end; ++it ) + args << TQVariant( *it ); + return TDEIO::xmlrpcCall( url, method, args, showProgressInfo ); +} + +template <typename T> +XmlrpcJob* TDEIO::xmlrpcCall( const KURL& url, const TQString &method, + const TQValueList<T>&arg, bool showProgressInfo ) +{ + TQValueList<TQVariant> args; + + typename TQValueList<T>::ConstIterator it = arg.begin(); + typename TQValueList<T>::ConstIterator end = arg.end(); + for ( ; it != end; ++it ) + args << TQVariant( *it ); + return TDEIO::xmlrpcCall( url, method, args, showProgressInfo ); +} + +#include "xmlrpcjob.moc" diff --git a/tderesources/blogging/xmlrpcjob.h b/tderesources/blogging/xmlrpcjob.h new file mode 100644 index 000000000..1efe79e1d --- /dev/null +++ b/tderesources/blogging/xmlrpcjob.h @@ -0,0 +1,124 @@ +// -*- 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 <tqstring.h> +#include <tqvaluelist.h> +#include <tqdom.h> + +#include <kio/jobclasses.h> +#include <kio/global.h> + +namespace TDEIO { + + 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 TDEIO::xmlrpcCall() + * @since 3.4 + */ +class XmlrpcJob : public TransferJob { +Q_OBJECT + + + public: + /** Indicates the response type of the call + */ + enum XMLRPCResponseType { + XMLRPCMessageResponse, + XMLRPCFaultResponse, + XMLRPCUnknownResponse + }; + /** + * Use TDEIO::xmlrpcPropFind(), TDEIO::xmlrpcPropPatch() and + * TDEIO::xmlrpcSearch() to create a new XmlrpcJob. + */ + XmlrpcJob( const KURL& url, const TQString& method, + const TQValueList<TQVariant> ¶ms, bool showProgressInfo ); + virtual ~XmlrpcJob(); + /** + * Returns the response as a TQDomDocument. + * @return the response document + */ + TQValueList<TQVariant> &response() { return m_response; } + /** + * Returns the type of the response. + * @return the type of the response + */ + XMLRPCResponseType responseType() const { return m_responseType; } + + static TQString markupCall( const TQString &cmd, + const TQValueList<TQVariant> &args ); + protected slots: + virtual void slotFinished(); + virtual void slotData( const TQByteArray &data); + + protected: + static TQString marshal( const TQVariant &arg ); + static TQVariant demarshal( const TQDomElement &e ); + + static bool isMessageResponse( const TQDomDocument &doc ); + static bool isFaultResponse( const TQDomDocument &doc ); + + static XMLRPCResult parseMessageResponse( const TQDomDocument &doc ); + static XMLRPCResult parseFaultResponse( const TQDomDocument &doc ); + + + private: + class XmlrpcJobPrivate; + XmlrpcJobPrivate *d; + TQString m_str_response; + TQValueList<TQVariant> 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 TQValueList<TQVariant>) for the method call. + * @param showProgressInfo true to show progress information + * @return the new XmlrpcJob + */ +XmlrpcJob* xmlrpcCall( const KURL& url, const TQString &method, + const TQValueList<TQVariant> ¶ms, + bool showProgressInfo = true ); + +XmlrpcJob* xmlrpcCall( const KURL& url, const TQString &method, + const TQVariant &arg, bool showProgressInfo = true ); +XmlrpcJob* xmlrpcCall( const KURL& url, const TQString &method, + const TQStringList &arg, bool showProgressInfo = true ); +template <typename T> +XmlrpcJob* xmlrpcCall( const KURL& url, const TQString &method, + const TQValueList<T>&arg,bool showProgressInfo = true ); +} + +#endif |