/* This file is part of tdepim. Copyright (c) 2004 Reinhold Kainhofer 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 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 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 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 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 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 args( defaultArgs( posting->postID() ) ); args << TQVariant( posting->content() ); args << TQVariant( /*publish=*/true ); 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 args( defaultArgs( posting->blogID() ) ); args << TQVariant( posting->content() ); args << TQVariant( /*publish=*/true ); 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 args( defaultArgs( postid ) ); args << TQVariant( /*publish=*/true ); 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(job); if ( job->error() || !trfjob ) { // TODO: Error handling return false; } else if ( trfjob ) { TQValueList message( trfjob->response() ); kdDebug () << "TOP: " << message[ 0 ].typeName() << endl; const TQValueList posts = message; TQValueList::ConstIterator it = posts.begin(); TQValueList::ConstIterator end = posts.end(); for ( ; it != end; ++it ) { kdDebug () << "MIDDLE: " << ( *it ).typeName() << endl; const TQMap 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(job); if ( job->error() || !trfjob ) { // TODO: Error handling } else { kdDebug() << "APIBlogger::interpretListFoldersJob, no error!" << endl; TQValueList message( trfjob->response() ); kdDebug () << "TOP: " << message[ 0 ].typeName() << endl; const TQValueList posts = message[ 0 ].toList(); TQValueList::ConstIterator it = posts.begin(); TQValueList::ConstIterator end = posts.end(); for ( ; it != end; ++it ) { kdDebug () << "MIDDLE: " << ( *it ).typeName() << endl; const TQMap 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"<(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 message( trfjob->response() ); kdDebug () << "TOP: " << message[ 0 ].typeName() << endl; const TQValueList postReceived = message[ 0 ].toList(); TQValueList::ConstIterator it = postReceived.begin(); TQValueList::ConstIterator end = postReceived.end(); success = true; for ( ; it != end; ++it ) { BlogPosting posting; kdDebug () << "MIDDLE: " << ( *it ).typeName() << endl; const TQMap postInfo = ( *it ).toMap(); if ( readPostingFromMap( &posting, postInfo ) ) { KCal::Journal *j = journalFromPosting( &posting ); // dumpBlog( &posting ); kdDebug() << "Emitting itemOnServer( posting.postID()="<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 &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; }