1 | /* |
2 | This file is part of the kblog library. |
3 | |
4 | Copyright (c) 2004 Reinhold Kainhofer <reinhold@kainhofer.com> |
5 | Copyright (c) 2006-2009 Christian Weilbach <christian_weilbach@web.de> |
6 | Copyright (c) 2007-2008 Mike McQuaid <mike@mikemcquaid.com> |
7 | |
8 | This library is free software; you can redistribute it and/or |
9 | modify it under the terms of the GNU Library General Public |
10 | License as published by the Free Software Foundation; either |
11 | version 2 of the License, or (at your option) any later version. |
12 | |
13 | This library is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | Library General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU Library General Public License |
19 | along with this library; see the file COPYING.LIB. If not, write to |
20 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
21 | Boston, MA 02110-1301, USA. |
22 | */ |
23 | |
24 | #include "movabletype.h" |
25 | #include "movabletype_p.h" |
26 | #include "blogpost.h" |
27 | |
28 | #include <kxmlrpcclient/client.h> |
29 | #include <kio/job.h> |
30 | |
31 | #include <KDebug> |
32 | #include <KLocalizedString> |
33 | #include <KDateTime> |
34 | |
35 | #include <QtCore/QStringList> |
36 | |
37 | using namespace KBlog; |
38 | |
39 | MovableType::MovableType( const KUrl &server, QObject *parent ) |
40 | : MetaWeblog( server, *new MovableTypePrivate, parent ) |
41 | { |
42 | kDebug(); |
43 | } |
44 | |
45 | MovableType::MovableType( const KUrl &server, MovableTypePrivate &dd, |
46 | QObject *parent ) |
47 | : MetaWeblog( server, dd, parent ) |
48 | { |
49 | kDebug(); |
50 | } |
51 | |
52 | MovableType::~MovableType() |
53 | { |
54 | kDebug(); |
55 | } |
56 | |
57 | QString MovableType::interfaceName() const |
58 | { |
59 | return QLatin1String( "Movable Type" ); |
60 | } |
61 | |
62 | void MovableType::listRecentPosts( int number ) |
63 | { |
64 | Q_D( MovableType ); |
65 | kDebug(); |
66 | QList<QVariant> args( d->defaultArgs( blogId() ) ); |
67 | args << QVariant( number ); |
68 | d->mXmlRpcClient->call( |
69 | QLatin1String("metaWeblog.getRecentPosts" ), args, |
70 | this, SLOT(slotListRecentPosts(QList<QVariant>,QVariant)), |
71 | this, SLOT(slotError(int,QString,QVariant)), |
72 | QVariant( number ) ); |
73 | } |
74 | |
75 | void MovableType::listTrackBackPings( KBlog::BlogPost *post ) |
76 | { |
77 | Q_D( MovableType ); |
78 | kDebug(); |
79 | QList<QVariant> args; |
80 | args << QVariant( post->postId() ); |
81 | unsigned int i = d->mCallCounter++; |
82 | d->mCallMap[ i ] = post; |
83 | d->mXmlRpcClient->call( |
84 | QLatin1String("mt.getTrackbackPings" ), args, |
85 | this, SLOT(slotListTrackbackPings(QList<QVariant>,QVariant)), |
86 | this, SLOT(slotError(int,QString,QVariant)), |
87 | QVariant( i ) ); |
88 | } |
89 | |
90 | void MovableType::fetchPost( BlogPost *post ) |
91 | { |
92 | Q_D( MovableType ); |
93 | kDebug(); |
94 | d->loadCategories(); |
95 | if ( d->mCategoriesList.isEmpty() && |
96 | post->categories( ).count() ) { |
97 | d->mFetchPostCache << post; |
98 | if ( d->mFetchPostCache.count() ) { |
99 | // we are already trying to fetch another post, so we don't need to start |
100 | // another listCategories() job |
101 | return; |
102 | } |
103 | |
104 | connect( this, SIGNAL(listedCategories(QList<QMap<QString,QString> >)), |
105 | this, SLOT(slotTriggerFetchPost()) ); |
106 | listCategories(); |
107 | } else { |
108 | MetaWeblog::fetchPost( post ); |
109 | } |
110 | } |
111 | |
112 | void MovableType::createPost( BlogPost *post ) |
113 | { |
114 | // reimplemented because we do this: |
115 | // http://comox.textdrive.com/pipermail/wp-testers/2005-July/000284.html |
116 | kDebug(); |
117 | Q_D( MovableType ); |
118 | |
119 | // we need mCategoriesList to be loaded first, since we cannot use the post->categories() |
120 | // names later, but we need to map them to categoryId of the blog |
121 | d->loadCategories(); |
122 | if ( d->mCategoriesList.isEmpty() && |
123 | !post->categories().isEmpty() ) { |
124 | kDebug() << "No categories in the cache yet. Have to fetch them first." ; |
125 | d->mCreatePostCache << post; |
126 | connect( this, SIGNAL(listedCategories(QList<QMap<QString,QString> >)), |
127 | this, SLOT(slotTriggerCreatePost()) ); |
128 | listCategories(); |
129 | } |
130 | else { |
131 | bool publish = post->isPrivate(); |
132 | // If we do setPostCategories() later than we disable publishing first. |
133 | if ( !post->categories().isEmpty() ) { |
134 | post->setPrivate( true ); |
135 | if ( d->mSilentCreationList.contains( post ) ) { |
136 | kDebug() << "Post already in mSilentCreationList, this *should* never happen!" ; |
137 | } else { |
138 | d->mSilentCreationList << post; |
139 | } |
140 | } |
141 | MetaWeblog::createPost( post ); |
142 | // HACK: uuh this a bit ugly now... reenable the original publish argument, |
143 | // since createPost should have parsed now |
144 | post->setPrivate( publish ); |
145 | } |
146 | } |
147 | |
148 | void MovableType::modifyPost( BlogPost *post ) |
149 | { |
150 | // reimplemented because we do this: |
151 | // http://comox.textdrive.com/pipermail/wp-testers/2005-July/000284.html |
152 | kDebug(); |
153 | Q_D( MovableType ); |
154 | |
155 | // we need mCategoriesList to be loaded first, since we cannot use the post->categories() |
156 | // names later, but we need to map them to categoryId of the blog |
157 | d->loadCategories(); |
158 | if ( d->mCategoriesList.isEmpty() && |
159 | !post->categories().isEmpty() ) { |
160 | kDebug() << "No categories in the cache yet. Have to fetch them first." ; |
161 | d->mModifyPostCache << post; |
162 | connect( this, SIGNAL(listedCategories(QList<QMap<QString,QString> >)), |
163 | this, SLOT(slotTriggerModifyPost()) ); |
164 | listCategories(); |
165 | } |
166 | else { |
167 | MetaWeblog::modifyPost( post ); |
168 | } |
169 | } |
170 | |
171 | void MovableTypePrivate::slotTriggerCreatePost() |
172 | { |
173 | kDebug(); |
174 | Q_Q( MovableType ); |
175 | |
176 | q->disconnect( q, SIGNAL(listedCategories(QList<QMap<QString,QString> >)), |
177 | q, SLOT(slotTriggerCreatePost()) ); |
178 | // now we can recall createPost with the posts from the cache |
179 | QList<BlogPost*>::Iterator it = mCreatePostCache.begin(); |
180 | QList<BlogPost*>::Iterator end = mCreatePostCache.end(); |
181 | for ( ; it != end; it++ ) { |
182 | q->createPost( *it ); |
183 | } |
184 | mCreatePostCache.clear(); |
185 | } |
186 | |
187 | void MovableTypePrivate::slotTriggerModifyPost() |
188 | { |
189 | kDebug(); |
190 | Q_Q( MovableType ); |
191 | |
192 | q->disconnect( q, SIGNAL(listedCategories(QList<QMap<QString,QString> >)), |
193 | q, SLOT(slotTriggerModifyPost()) ); |
194 | // now we can recall createPost with the posts from the cache |
195 | QList<BlogPost*>::Iterator it = mModifyPostCache.begin(); |
196 | QList<BlogPost*>::Iterator end = mModifyPostCache.end(); |
197 | for ( ; it != end; it++ ) { |
198 | q->modifyPost( *it ); |
199 | } |
200 | mModifyPostCache.clear(); |
201 | } |
202 | |
203 | void MovableTypePrivate::slotTriggerFetchPost() |
204 | { |
205 | kDebug(); |
206 | Q_Q( MovableType ); |
207 | |
208 | q->disconnect( q, SIGNAL(listedCategories(QList<QMap<QString,QString> >)), |
209 | q, SLOT(slotTriggerFetchPost()) ); |
210 | QList<BlogPost*>::Iterator it = mFetchPostCache.begin(); |
211 | QList<BlogPost*>::Iterator end = mFetchPostCache.end(); |
212 | for ( ; it != end; it++ ) { |
213 | q->fetchPost( *it ); |
214 | } |
215 | mFetchPostCache.clear(); |
216 | } |
217 | |
218 | MovableTypePrivate::MovableTypePrivate() |
219 | { |
220 | kDebug(); |
221 | } |
222 | |
223 | MovableTypePrivate::~MovableTypePrivate() |
224 | { |
225 | kDebug(); |
226 | } |
227 | |
228 | void MovableTypePrivate::slotCreatePost( const QList<QVariant> &result, const QVariant &id ) |
229 | { |
230 | Q_Q( MovableType ); |
231 | // reimplement from Blogger1 to chainload the categories stuff before emit() |
232 | kDebug(); |
233 | KBlog::BlogPost *post = mCallMap[ id.toInt() ]; |
234 | mCallMap.remove( id.toInt() ); |
235 | |
236 | kDebug(); |
237 | //array of structs containing ISO.8601 |
238 | // dateCreated, String userid, String postid, String content; |
239 | kDebug () << "TOP:" << result[0].typeName(); |
240 | if ( result[0].type() != QVariant::String && |
241 | result[0].type() != QVariant::Int ) { |
242 | kError() << "Could not read the postId, not a string or an integer." ; |
243 | emit q->errorPost( Blogger1::ParsingError, |
244 | i18n( "Could not read the postId, not a string or an integer." ), |
245 | post ); |
246 | return; |
247 | } |
248 | QString serverID; |
249 | if ( result[0].type() == QVariant::String ) { |
250 | serverID = result[0].toString(); |
251 | } |
252 | if ( result[0].type() == QVariant::Int ) { |
253 | serverID = QString::fromLatin1( "%1" ).arg( result[0].toInt() ); |
254 | } |
255 | post->setPostId( serverID ); |
256 | if ( mSilentCreationList.contains( post ) ) |
257 | { |
258 | // set the categories and publish afterwards |
259 | setPostCategories( post, !post->isPrivate() ); |
260 | } else { |
261 | kDebug() << "emitting createdPost()" |
262 | << "for title: \"" << post->title() |
263 | << "\" server id: " << serverID; |
264 | post->setStatus( KBlog::BlogPost::Created ); |
265 | emit q->createdPost( post ); |
266 | } |
267 | } |
268 | |
269 | void MovableTypePrivate::slotFetchPost( const QList<QVariant> &result, const QVariant &id ) |
270 | { |
271 | Q_Q( MovableType ); |
272 | kDebug(); |
273 | |
274 | KBlog::BlogPost *post = mCallMap[ id.toInt() ]; |
275 | mCallMap.remove( id.toInt() ); |
276 | |
277 | //array of structs containing ISO.8601 |
278 | // dateCreated, String userid, String postid, String content; |
279 | kDebug () << "TOP:" << result[0].typeName(); |
280 | if ( result[0].type() == QVariant::Map && |
281 | readPostFromMap( post, result[0].toMap() ) ) { |
282 | } else { |
283 | kError() << "Could not fetch post out of the result from the server." ; |
284 | post->setError( i18n( "Could not fetch post out of the result from the server." ) ); |
285 | post->setStatus( BlogPost::Error ); |
286 | emit q->errorPost( Blogger1::ParsingError, |
287 | i18n( "Could not fetch post out of the result from the server." ), post ); |
288 | } |
289 | if ( post->categories().isEmpty() ) { |
290 | QList<QVariant> args( defaultArgs( post->postId() ) ); |
291 | unsigned int i= mCallCounter++; |
292 | mCallMap[ i ] = post; |
293 | mXmlRpcClient->call( |
294 | QLatin1String("mt.getPostCategories" ), args, |
295 | q, SLOT(slotGetPostCategories(QList<QVariant>,QVariant)), |
296 | q, SLOT(slotError(int,QString,QVariant)), |
297 | QVariant( i ) ); |
298 | } else { |
299 | kDebug() << "Emitting fetchedPost()" ; |
300 | post->setStatus( KBlog::BlogPost::Fetched ); |
301 | emit q->fetchedPost( post ); |
302 | } |
303 | } |
304 | |
305 | void MovableTypePrivate::slotModifyPost( const QList<QVariant> &result, const QVariant &id ) |
306 | { |
307 | Q_Q( MovableType ); |
308 | // reimplement from Blogger1 |
309 | kDebug(); |
310 | KBlog::BlogPost *post = mCallMap[ id.toInt() ]; |
311 | mCallMap.remove( id.toInt() ); |
312 | |
313 | //array of structs containing ISO.8601 |
314 | // dateCreated, String userid, String postid, String content; |
315 | kDebug() << "TOP:" << result[0].typeName(); |
316 | if ( result[0].type() != QVariant::Bool && |
317 | result[0].type() != QVariant::Int ) { |
318 | kError() << "Could not read the result, not a boolean." ; |
319 | emit q->errorPost( Blogger1::ParsingError, |
320 | i18n( "Could not read the result, not a boolean." ), |
321 | post ); |
322 | return; |
323 | } |
324 | if ( mSilentCreationList.contains( post ) ) { |
325 | post->setStatus( KBlog::BlogPost::Created ); |
326 | mSilentCreationList.removeOne( post ); |
327 | emit q->createdPost( post ); |
328 | } else { |
329 | if ( !post->categories().isEmpty() ) { |
330 | setPostCategories( post, false ); |
331 | } |
332 | } |
333 | } |
334 | |
335 | void MovableTypePrivate::setPostCategories( BlogPost *post, bool publishAfterCategories ) |
336 | { |
337 | kDebug(); |
338 | Q_Q( MovableType ); |
339 | |
340 | unsigned int i = mCallCounter++; |
341 | mCallMap[ i ] = post; |
342 | mPublishAfterCategories[ i ] = publishAfterCategories; |
343 | QList<QVariant> catList; |
344 | QList<QVariant> args( defaultArgs( post->postId() ) ); |
345 | |
346 | // map the categoryId of the server to the name |
347 | QStringList categories = post->categories(); |
348 | for ( int j = 0; j < categories.count(); j++ ) { |
349 | for ( int k = 0; k < mCategoriesList.count(); k++ ) { |
350 | if ( mCategoriesList[k][QLatin1String("name" )] == categories[j] ) { |
351 | kDebug() << "Matched category with name: " << categories[ j ] << " and id: " << mCategoriesList[ k ][ QLatin1String("categoryId" ) ]; |
352 | QMap<QString,QVariant> category; |
353 | //the first in the QStringList of post->categories() |
354 | // is the primary category |
355 | category[QLatin1String("categoryId" )] = mCategoriesList[k][QLatin1String("categoryId" )].toInt(); |
356 | catList << QVariant( category ); |
357 | break; |
358 | } |
359 | if ( k == mCategoriesList.count() ) { |
360 | kDebug() << "Couldn't find categoryId for: " << categories[j]; |
361 | } |
362 | } |
363 | } |
364 | args << QVariant( catList ); |
365 | |
366 | mXmlRpcClient->call( |
367 | QLatin1String("mt.setPostCategories" ), args, |
368 | q, SLOT(slotSetPostCategories(QList<QVariant>,QVariant)), |
369 | q, SLOT(slotError(int,QString,QVariant)), |
370 | QVariant( i ) ); |
371 | } |
372 | |
373 | void MovableTypePrivate::slotGetPostCategories(const QList<QVariant>& result,const QVariant& id) |
374 | { |
375 | kDebug(); |
376 | Q_Q( MovableType ); |
377 | |
378 | int i = id.toInt(); |
379 | BlogPost* post = mCallMap[ i ]; |
380 | mCallMap.remove( i ); |
381 | |
382 | if ( result[ 0 ].type() != QVariant::List ) { |
383 | kError() << "Could not read the result, not a list. Category fetching failed! We will still emit fetched post now." ; |
384 | emit q->errorPost( Blogger1::ParsingError, |
385 | i18n( "Could not read the result - is not a list. Category fetching failed." ), post ); |
386 | |
387 | post->setStatus( KBlog::BlogPost::Fetched ); |
388 | emit q->fetchedPost( post ); |
389 | } else { |
390 | QList<QVariant> categoryList = result[ 0 ].toList(); |
391 | QList<QString> newCatList; |
392 | QList<QVariant>::ConstIterator it = categoryList.constBegin(); |
393 | QList<QVariant>::ConstIterator end = categoryList.constEnd(); |
394 | for ( ; it != end; it++ ) { |
395 | newCatList << ( *it ).toMap()[ QLatin1String("categoryName" ) ].toString(); |
396 | } |
397 | kDebug() << "categories list: " << newCatList; |
398 | post->setCategories( newCatList ); |
399 | post->setStatus( KBlog::BlogPost::Fetched ); |
400 | emit q->fetchedPost( post ); |
401 | } |
402 | } |
403 | |
404 | void MovableTypePrivate::slotSetPostCategories(const QList<QVariant>& result,const QVariant& id) |
405 | { |
406 | kDebug(); |
407 | Q_Q( MovableType ); |
408 | |
409 | int i = id.toInt(); |
410 | BlogPost* post = mCallMap[ i ]; |
411 | bool publish = mPublishAfterCategories[ i ]; |
412 | mCallMap.remove( i ); |
413 | mPublishAfterCategories.remove( i ); |
414 | |
415 | if ( result[0].type() != QVariant::Bool ) { |
416 | kError() << "Could not read the result, not a boolean. Category setting failed! We will still publish if now if necessary. " ; |
417 | emit q->errorPost( Blogger1::ParsingError, |
418 | i18n( "Could not read the result - is not a boolean value. Category setting failed. Will still publish now if necessary." ), |
419 | post ); |
420 | } |
421 | // Finally publish now, if the post was meant to be published in the beginning. |
422 | // The first boolean is necessary to only publish if the post is created, not |
423 | // modified. |
424 | if ( publish && !post->isPrivate() ) { |
425 | q->modifyPost( post ); |
426 | } |
427 | |
428 | // this is the end of the chain then |
429 | if ( !publish ) { |
430 | if ( mSilentCreationList.contains( post ) ) { |
431 | kDebug() << "emitting createdPost() for title: \"" |
432 | << post->title() << "\"" ; |
433 | post->setStatus( KBlog::BlogPost::Created ); |
434 | mSilentCreationList.removeOne( post ); |
435 | emit q->createdPost( post ); |
436 | } else { |
437 | kDebug() << "emitting modifiedPost() for title: \"" |
438 | << post->title() << "\"" ; |
439 | post->setStatus( KBlog::BlogPost::Modified ); |
440 | emit q->modifiedPost( post ); |
441 | } |
442 | } |
443 | } |
444 | |
445 | QList<QVariant> MovableTypePrivate::defaultArgs( const QString &id ) |
446 | { |
447 | Q_Q( MovableType ); |
448 | QList<QVariant> args; |
449 | if ( !id.isEmpty() ) { |
450 | args << QVariant( id ); |
451 | } |
452 | args << QVariant( q->username() ) |
453 | << QVariant( q->password() ); |
454 | return args; |
455 | } |
456 | |
457 | bool MovableTypePrivate::readPostFromMap( BlogPost *post, const QMap<QString, QVariant> &postInfo ) |
458 | { |
459 | |
460 | // FIXME: integrate error handling |
461 | kDebug() << "readPostFromMap()" ; |
462 | if ( !post ) { |
463 | return false; |
464 | } |
465 | QStringList mapkeys = postInfo.keys(); |
466 | kDebug() << endl << "Keys:" << mapkeys.join( QLatin1String(", " ) ); |
467 | kDebug() << endl; |
468 | |
469 | KDateTime dt = |
470 | KDateTime( postInfo[QLatin1String("dateCreated" )].toDateTime(), KDateTime::UTC ); |
471 | if ( dt.isValid() && !dt.isNull() ) { |
472 | post->setCreationDateTime( dt.toLocalZone() ); |
473 | } |
474 | |
475 | dt = |
476 | KDateTime( postInfo[QLatin1String("lastModified" )].toDateTime(), KDateTime::UTC ); |
477 | if ( dt.isValid() && !dt.isNull() ) { |
478 | post->setModificationDateTime( dt.toLocalZone() ); |
479 | } |
480 | |
481 | post->setPostId( postInfo[QLatin1String("postid" )].toString().isEmpty() ? postInfo[QLatin1String("postId" )].toString() : |
482 | postInfo[QLatin1String("postid" )].toString() ); |
483 | |
484 | QString title( postInfo[QLatin1String("title" )].toString() ); |
485 | QString description( postInfo[QLatin1String("description" )].toString() ); |
486 | QStringList categoryIdList = postInfo[QLatin1String("categories" )].toStringList(); |
487 | QStringList categories; |
488 | // since the metaweblog definition is ambigious, we try different |
489 | // category mappings |
490 | for ( int i = 0; i < categoryIdList.count(); i++ ) { |
491 | for ( int k = 0; k < mCategoriesList.count(); k++ ) { |
492 | if ( mCategoriesList[ k ][ QLatin1String("name" ) ] == categoryIdList[ i ] ) { |
493 | categories << mCategoriesList[ k ][ QLatin1String("name" ) ]; |
494 | } else if ( mCategoriesList[ k ][ QLatin1String("categoryId" ) ] == categoryIdList[ i ]) { |
495 | categories << mCategoriesList[ k ][ QLatin1String("name" ) ]; |
496 | } |
497 | } |
498 | } |
499 | |
500 | //TODO 2 new keys are: |
501 | // String mt_convert_breaks, the value for the convert_breaks field |
502 | post->setSlug( postInfo[QLatin1String("wp_slug" )].toString() ); |
503 | post->setAdditionalContent( postInfo[QLatin1String("mt_text_more" )].toString() ); |
504 | post->setTitle( title ); |
505 | post->setContent( description ); |
506 | post->setCommentAllowed( (bool)postInfo[QLatin1String("mt_allow_comments" )].toInt() ); |
507 | post->setTrackBackAllowed( (bool)postInfo[QLatin1String("mt_allow_pings" )].toInt() ); |
508 | post->setSummary( postInfo[QLatin1String("mt_excerpt" )].toString() ); |
509 | post->setTags( postInfo[QLatin1String("mt_keywords" )].toStringList() ); |
510 | post->setLink( postInfo[QLatin1String("link" )].toString() ); |
511 | post->setPermaLink( postInfo[QLatin1String("permaLink" )].toString() ); |
512 | QString postStatus = postInfo[QLatin1String("post_status" )].toString(); |
513 | if ( postStatus != QLatin1String("publish" ) && |
514 | !postStatus.isEmpty() ) { |
515 | /** |
516 | * Maybe this field wasn't set by server! so, on that situation, we will assume it as non-Private, |
517 | * The postStatus.isEmpty() check is for that! |
518 | * I found this field on Wordpress output! it's value can be: publish, private, draft (as i see) |
519 | */ |
520 | post->setPrivate( true ); |
521 | } |
522 | if ( !categories.isEmpty() ) { |
523 | kDebug() << "Categories:" << categories; |
524 | post->setCategories( categories ); |
525 | } |
526 | return true; |
527 | } |
528 | |
529 | void MovableTypePrivate::slotListTrackBackPings( |
530 | const QList<QVariant> &result, const QVariant &id ) |
531 | { |
532 | Q_Q( MovableType ); |
533 | kDebug() << "slotTrackbackPings()" ; |
534 | BlogPost *post = mCallMap[ id.toInt() ]; |
535 | mCallMap.remove( id.toInt() ); |
536 | QList<QMap<QString,QString> > trackBackList; |
537 | if ( result[0].type() != QVariant::List ) { |
538 | kError() << "Could not fetch list of trackback pings out of the" |
539 | << "result from the server." ; |
540 | emit q->error( MovableType::ParsingError, |
541 | i18n( "Could not fetch list of trackback pings out of the " |
542 | "result from the server." ) ); |
543 | return; |
544 | } |
545 | const QList<QVariant> trackBackReceived = result[0].toList(); |
546 | QList<QVariant>::ConstIterator it = trackBackReceived.begin(); |
547 | QList<QVariant>::ConstIterator end = trackBackReceived.end(); |
548 | for ( ; it != end; ++it ) { |
549 | QMap<QString,QString> tping; |
550 | kDebug() << "MIDDLE:" << ( *it ).typeName(); |
551 | const QMap<QString, QVariant> trackBackInfo = ( *it ).toMap(); |
552 | tping[ QLatin1String("title" ) ] = trackBackInfo[ QLatin1String("pingTitle" )].toString(); |
553 | tping[ QLatin1String("url" ) ] = trackBackInfo[ QLatin1String("pingURL" )].toString(); |
554 | tping[ QLatin1String("ip" ) ] = trackBackInfo[ QLatin1String("pingIP" )].toString(); |
555 | trackBackList << tping; |
556 | } |
557 | kDebug() << "Emitting listedTrackBackPings()" ; |
558 | emit q->listedTrackBackPings( post, trackBackList ); |
559 | } |
560 | |
561 | bool MovableTypePrivate::readArgsFromPost( QList<QVariant> *args, const BlogPost &post ) |
562 | { |
563 | //TODO 2 new keys are: |
564 | // String mt_convert_breaks, the value for the convert_breaks field |
565 | // array mt_tb_ping_urls, the list of TrackBack ping URLs for this entry |
566 | if ( !args ) { |
567 | return false; |
568 | } |
569 | QMap<QString, QVariant> map; |
570 | map[QLatin1String("categories" )] = post.categories(); |
571 | map[QLatin1String("description" )] = post.content(); |
572 | if ( !post.additionalContent().isEmpty() ) { |
573 | map[QLatin1String("mt_text_more" )] = post.additionalContent(); |
574 | } |
575 | map[QLatin1String("title" )] = post.title(); |
576 | map[QLatin1String("dateCreated" )] = post.creationDateTime().dateTime().toUTC(); |
577 | map[QLatin1String("mt_allow_comments" )] = (int)post.isCommentAllowed(); |
578 | map[QLatin1String("mt_allow_pings" )] = (int)post.isTrackBackAllowed(); |
579 | map[QLatin1String("mt_excerpt" )] = post.summary(); |
580 | map[QLatin1String("mt_keywords" )] = post.tags().join( QLatin1String("," ) ); |
581 | //map["mt_tb_ping_urls"] check for that, i think this should only be done on the server. |
582 | *args << map; |
583 | *args << QVariant( !post.isPrivate() ); |
584 | return true; |
585 | } |
586 | |
587 | #include "moc_movabletype.cpp" |
588 | |