TDE personal information management applications
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

333 lines
12 KiB

  1. /*
  2. This file is part of tdepim.
  3. Copyright (c) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public License
  13. along with this library; see the file COPYING.LIB. If not, write to
  14. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  15. Boston, MA 02110-1301, USA.
  16. */
  17. #include "API_Blogger.h"
  18. #include "xmlrpcjob.h"
  19. #include <kdebug.h>
  20. using namespace KBlog;
  21. TQString APIBlogger::getFunctionName( blogFunctions type )
  22. {
  23. switch ( type ) {
  24. case bloggerGetUserInfo: return "blogger.getUserInfo";
  25. case bloggerGetUsersBlogs: return "blogger.getUsersBlogs";
  26. case bloggerGetRecentPosts: return "blogger.getRecentPosts";
  27. case bloggerNewPost: return "blogger.newPost";
  28. case bloggerEditPost: return "blogger.editPost";
  29. case bloggerDeletePost: return "blogger.deletePost";
  30. case bloggerGetPost: return "blogger.getPost";
  31. case bloggerGetTemplate: return "blogger.getTemplate";
  32. case bloggerSetTemplate: return "blogger.setTemplate";
  33. default: return TQString();
  34. }
  35. }
  36. TDEIO::Job *APIBlogger::createUserInfoJob()
  37. {
  38. kdDebug() << "read user info..." << endl;
  39. TQValueList<TQVariant> args( defaultArgs() );
  40. return TDEIO::xmlrpcCall( mServerURL, getFunctionName( bloggerGetUserInfo ), args, false );
  41. }
  42. TDEIO::Job *APIBlogger::createListFoldersJob()
  43. {
  44. // TODO: Check if we're already authenticated. If not, do it!
  45. // if ( isValid() ) {
  46. kdDebug() << "Fetch List of Blogs..." << endl;
  47. TQValueList<TQVariant> args( defaultArgs() );
  48. return TDEIO::xmlrpcCall( mServerURL, getFunctionName( bloggerGetUsersBlogs ), args, false );
  49. // } else {
  50. // warningNotInitialized();
  51. // return 0;
  52. // }
  53. }
  54. TDEIO::TransferJob *APIBlogger::createListItemsJob( const KURL &url )
  55. {
  56. // TODO: Check if we're already authenticated. If not, do it!
  57. // if ( isValid() ) {
  58. kdDebug() << "Fetch List of Posts..." << endl;
  59. TQValueList<TQVariant> args( defaultArgs( url.url() ) );
  60. args << TQVariant( mDownloadCount );
  61. return TDEIO::xmlrpcCall( mServerURL, getFunctionName( bloggerGetRecentPosts ), args, false );
  62. // } else {
  63. // warningNotInitialized();
  64. // return 0;
  65. // }
  66. }
  67. TDEIO::TransferJob *APIBlogger::createDownloadJob( const KURL &url )
  68. {
  69. // if ( isValid() ){
  70. kdDebug() << "Fetch Posting with url " << url.url() << endl;
  71. TQValueList<TQVariant> args( defaultArgs( url.url() ) );
  72. return TDEIO::xmlrpcCall( mServerURL, getFunctionName( bloggerGetPost ), args, false );
  73. // } else {
  74. // warningNotInitialized();
  75. // return 0;
  76. // }
  77. }
  78. TDEIO::TransferJob *APIBlogger::createUploadJob( const KURL &url, KBlog::BlogPosting *posting )
  79. {
  80. if ( !posting ) {
  81. kdDebug() << "APIBlogger::createUploadJob: posting=0" << endl;
  82. return 0;
  83. }
  84. // if ( isValid() ){
  85. kdDebug() << "Uploading Posting with url " << url.url() << endl;
  86. TQValueList<TQVariant> args( defaultArgs( posting->postID() ) );
  87. args << TQVariant( posting->content() );
  88. args << TQVariant( /*publish=*/true );
  89. return TDEIO::xmlrpcCall( mServerURL, getFunctionName( bloggerEditPost ), args, false );
  90. // } else {
  91. // warningNotInitialized();
  92. // return 0;
  93. // }
  94. }
  95. TDEIO::TransferJob *APIBlogger::createUploadNewJob( KBlog::BlogPosting *posting )
  96. {
  97. if ( !posting ) {
  98. kdDebug() << "APIBlogger::createUploadNewJob: posting=0" << endl;
  99. return 0;
  100. }
  101. // if ( isValid() ){
  102. kdDebug() << "Creating new Posting with blogid " << posting->blogID() << " at url " << mServerURL << endl;
  103. TQValueList<TQVariant> args( defaultArgs( posting->blogID() ) );
  104. args << TQVariant( posting->content() );
  105. args << TQVariant( /*publish=*/true );
  106. return TDEIO::xmlrpcCall( mServerURL, getFunctionName( bloggerNewPost ), args, false );
  107. // } else {
  108. // warningNotInitialized();
  109. // return 0;
  110. // }
  111. }
  112. TDEIO::Job *APIBlogger::createRemoveJob( const KURL &/*url*/, const TQString &postid )
  113. {
  114. kdDebug() << "APIBlogger::createRemoveJob: postid=" << postid << endl;
  115. // if ( isValid() ){
  116. TQValueList<TQVariant> args( defaultArgs( postid ) );
  117. args << TQVariant( /*publish=*/true );
  118. return TDEIO::xmlrpcCall( mServerURL, getFunctionName( bloggerDeletePost ), args, false );
  119. // } else {
  120. // warningNotInitialized();
  121. // return 0;
  122. // }
  123. }
  124. bool APIBlogger::interpretUserInfoJob( TDEIO::Job *job )
  125. {
  126. // TODO: Implement user authentication
  127. // isValid = true;
  128. TDEIO::XmlrpcJob *trfjob = dynamic_cast<TDEIO::XmlrpcJob*>(job);
  129. if ( job->error() || !trfjob ) {
  130. // TODO: Error handling
  131. return false;
  132. } else if ( trfjob ) {
  133. TQValueList<TQVariant> message( trfjob->response() );
  134. kdDebug () << "TOP: " << message[ 0 ].typeName() << endl;
  135. const TQValueList<TQVariant> posts = message;
  136. TQValueList<TQVariant>::ConstIterator it = posts.begin();
  137. TQValueList<TQVariant>::ConstIterator end = posts.end();
  138. for ( ; it != end; ++it ) {
  139. kdDebug () << "MIDDLE: " << ( *it ).typeName() << endl;
  140. const TQStringVariantMap postInfo = ( *it ).toMap();
  141. const TQString nickname = postInfo[ "nickname" ].toString();
  142. const TQString userid = postInfo[ "userid" ].toString();
  143. const TQString email = postInfo[ "email" ].toString();
  144. kdDebug() << "Post " << nickname << " " << userid << " " << email << endl;
  145. // FIXME: How about a BlogUserInfo class???
  146. emit userInfoRetrieved( nickname, userid, email );
  147. }
  148. return true;
  149. }
  150. return false;
  151. }
  152. void APIBlogger::interpretListFoldersJob( TDEIO::Job *job )
  153. {
  154. kdDebug() << "APIBlogger::interpretListFoldersJob" << endl;
  155. TDEIO::XmlrpcJob *trfjob = dynamic_cast<TDEIO::XmlrpcJob*>(job);
  156. if ( job->error() || !trfjob ) {
  157. // TODO: Error handling
  158. } else {
  159. kdDebug() << "APIBlogger::interpretListFoldersJob, no error!" << endl;
  160. TQValueList<TQVariant> message( trfjob->response() );
  161. kdDebug () << "TOP: " << message[ 0 ].typeName() << endl;
  162. const TQValueList<TQVariant> posts = message[ 0 ].toList();
  163. TQValueList<TQVariant>::ConstIterator it = posts.begin();
  164. TQValueList<TQVariant>::ConstIterator end = posts.end();
  165. for ( ; it != end; ++it ) {
  166. kdDebug () << "MIDDLE: " << ( *it ).typeName() << endl;
  167. const TQStringVariantMap postInfo = ( *it ).toMap();
  168. const TQString id( postInfo[ "blogid" ].toString() );
  169. const TQString name( postInfo[ "blogName" ].toString() );
  170. const TQString url( postInfo[ "url" ].toString() );
  171. // Use the Blog ID instead of the URL. The ID already indicates the correct blog, and the
  172. // URL for all calls will be the XML-RPC interface, anyway.
  173. if ( !id.isEmpty() && !name.isEmpty() ) {
  174. emit folderInfoRetrieved( id, name );
  175. kdDebug()<< "Emitting folderInfoRetrieved( id=" << id << ", name=" << name << "); " << endl;
  176. }
  177. }
  178. }
  179. }
  180. bool APIBlogger::interpretListItemsJob( TDEIO::Job *job )
  181. {
  182. return interpretDownloadItemsJob( job );
  183. }
  184. bool APIBlogger::interpretDownloadItemsJob( TDEIO::Job *job )
  185. {
  186. kdDebug(5800)<<"APIBlogger::interpretDownloadItemJob"<<endl;
  187. TDEIO::XmlrpcJob *trfjob = dynamic_cast<TDEIO::XmlrpcJob*>(job);
  188. bool success = false;
  189. if ( job->error() || !trfjob ) {
  190. // TODO: Error handling
  191. success = false;
  192. } else {
  193. //array of structs containing ISO.8601 dateCreated, String userid, String postid, String content;
  194. // TODO: Time zone for the dateCreated!
  195. TQValueList<TQVariant> message( trfjob->response() );
  196. kdDebug () << "TOP: " << message[ 0 ].typeName() << endl;
  197. const TQValueList<TQVariant> postReceived = message[ 0 ].toList();
  198. TQValueList<TQVariant>::ConstIterator it = postReceived.begin();
  199. TQValueList<TQVariant>::ConstIterator end = postReceived.end();
  200. success = true;
  201. for ( ; it != end; ++it ) {
  202. BlogPosting posting;
  203. kdDebug () << "MIDDLE: " << ( *it ).typeName() << endl;
  204. const TQStringVariantMap postInfo = ( *it ).toMap();
  205. if ( readPostingFromMap( &posting, postInfo ) ) {
  206. KCal::Journal *j = journalFromPosting( &posting );
  207. // dumpBlog( &posting );
  208. kdDebug() << "Emitting itemOnServer( posting.postID()="<<posting.postID() << "); " << endl;
  209. emit itemOnServer( KURL( posting.postID() ) );
  210. kdDebug() << "Emitting itemDownloaded( j=" << j << ", uid=" << j->uid()
  211. << ", postID=" << posting.postID() << ", fpr="
  212. << posting.fingerprint() << "); " << endl;
  213. emit itemDownloaded( j, j->uid(), KURL( posting.postID() ),
  214. posting.fingerprint(), posting.postID() );
  215. } else {
  216. kdDebug() << "readPostingFromMap failed! " << endl;
  217. success = false;
  218. // TODO: Error handling
  219. }
  220. }
  221. }
  222. return success;
  223. }
  224. bool APIBlogger::readPostingFromMap( BlogPosting *post, const TQStringVariantMap &postInfo )
  225. {
  226. // FIXME:
  227. if ( !post ) return false;
  228. TQStringList mapkeys = postInfo.keys();
  229. kdDebug() << endl << "Keys: " << mapkeys.join(", ") << endl << endl;
  230. TQString fp( TQString() );
  231. TQDateTime dt( postInfo[ "dateCreated" ].toDateTime() );
  232. if ( dt.isValid() && !dt.isNull() ) {
  233. post->setCreationDateTime( dt );
  234. TQString fp = dt.toString( TQt::ISODate );
  235. }
  236. dt = postInfo[ "postDate" ].toDateTime();
  237. if ( dt.isValid() && !dt.isNull() ) {
  238. post->setDateTime( dt );
  239. fp = dt.toString( TQt::ISODate );
  240. }
  241. dt = postInfo[ "lastModified" ].toDateTime();
  242. if ( dt.isValid() && !dt.isNull() ) {
  243. post->setModificationDateTime( dt );
  244. fp = dt.toString( TQt::ISODate );
  245. }
  246. post->setFingerprint( fp );
  247. post->setUserID( postInfo[ "userid" ].toString() );
  248. post->setPostID( postInfo[ "postid" ].toString() );
  249. TQString title( postInfo[ "title" ].toString() );
  250. TQString description( postInfo[ "description" ].toString() );
  251. TQString contents( postInfo[ "content" ].toString() );
  252. TQString category;
  253. // TODO: Extract title and cats from the old-style blogger api without extensions
  254. /*
  255. if ( (title.isEmpty() || description.isEmpty() ) && !contents.isEmpty() ) {
  256. // we don't have both title and description, so use the content (ie. it's an
  257. // old-style blogger api, not the extended drupal api.
  258. kdDebug() << "No title and description given, so it's an old-style "
  259. "Blogger API without extensions" << endl;
  260. TQString catTagOpen = mTemplate.categoryTagOpen();
  261. TQString catTagClose = mTemplate.categoryTagClose();
  262. TQString titleTagOpen = mTemplate.titleTagOpen();
  263. TQString titleTagClose = mTemplate.titleTagClose();
  264. int catStart = contents.find( catTagOpen, 0, false ) + catTagOpen.length();
  265. int catEnd = contents.find( catTagClose, 0, false );
  266. kdDebug() << " catTagOpen = " << catTagOpen << ", catTagClose = " << catTagClose << ", start - end : " << catStart <<" - " << catEnd << endl;
  267. if ( catEnd > catStart ) {
  268. category = contents.mid( catStart, catEnd - catStart );
  269. kdDebug() << "Found a category \"" << category << "\"" << endl;
  270. contents = contents.remove( catStart - catTagOpen.length(),
  271. catEnd - catStart + catTagClose.length() + catTagOpen.length() );
  272. }
  273. int titleStart = contents.find( titleTagOpen, 0, false ) + titleTagOpen.length();
  274. int titleEnd = contents.find( titleTagClose, 0, false );
  275. kdDebug() << " titleTagOpen = " << titleTagOpen << ", titleTagClose = " << titleTagClose << ", start - end : " << titleStart <<" - " << titleEnd << endl;
  276. kdDebug() << "Title start and end: " << titleStart << ", " << titleEnd << endl;
  277. if ( titleEnd > titleStart ) {
  278. title = contents.mid( titleStart, titleEnd - titleStart );
  279. contents = contents.remove( titleStart - titleTagOpen.length(),
  280. titleEnd - titleStart + titleTagClose.length() + titleTagOpen.length() );
  281. }
  282. kdDebug() << endl << endl << endl << "After treatment of the special tags, we have a content of: "<< endl << contents << endl;
  283. }
  284. */
  285. post->setTitle( title );
  286. post->setContent( contents );
  287. if ( !category.isEmpty() )
  288. post->setCategory( category );
  289. return true;
  290. }