• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

akregator

  • sources
  • kde-4.12
  • kdepim
  • akregator
  • export
akregatorstorageexporter.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of akregatorstorageexporter
3  *
4  * Copyright (C) 2009 Frank Osterfeld <osterfeld@kde.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  */
22 #include "feedstorage.h"
23 #include "storage.h"
24 #include "storagefactory.h"
25 #include "storagefactoryregistry.h"
26 #include "plugin.h"
27 
28 #include <syndication/atom/constants.h>
29 #include <syndication/constants.h>
30 
31 #include <QCoreApplication>
32 #include <QDateTime>
33 #include <QDebug>
34 #include <QFile>
35 #include <QIODevice>
36 #include <QStringList>
37 #include <QXmlStreamWriter>
38 #include <QVariant>
39 
40 #include <KComponentData>
41 #include <KGlobal>
42 #include <KPluginLoader>
43 #include <KService>
44 #include <KServiceTypeTrader>
45 #include <KUrl>
46 
47 #include <iostream>
48 
49 #include <cassert>
50 
51 using namespace Akregator;
52 using namespace Akregator::Backend;
53 
54 namespace {
55  static QString akregatorNamespace() {
56  return QString::fromLatin1("http://akregator.kde.org/StorageExporter#");
57  }
58 
59  enum TextMode {
60  PlainText,
61  Html
62  };
63 
64  enum Status
65  {
66  Deleted=0x01,
67  Trash=0x02,
68  New=0x04,
69  Read=0x08,
70  Keep=0x10
71  };
72 
73  class Element
74  {
75  public:
76  Element( const QString& ns_, const QString& name_ ) : ns( ns_ ), name( name_ ), qualifiedName( ns + QLatin1Char(':') + name )
77  {
78  }
79 
80  const QString ns;
81  const QString name;
82  const QString qualifiedName;
83 
84  void writeStartElement( QXmlStreamWriter& writer ) const
85  {
86  if ( !ns.isNull() )
87  writer.writeStartElement( ns, name );
88  else
89  writer.writeStartElement( name );
90  }
91 
92  void write( const QVariant& value , QXmlStreamWriter& writer, TextMode mode = PlainText ) const
93  {
94  const QVariant qv( value );
95  Q_ASSERT( qv.canConvert( QVariant::String ) );
96  const QString str = qv.toString();
97  if ( str.isEmpty() )
98  return;
99 
100  if ( ns.isEmpty() )
101  writer.writeStartElement( name );
102  else
103  writer.writeStartElement( ns, name );
104  if ( mode == Html )
105  {
106  writer.writeAttribute( QLatin1String("type"), QLatin1String("html") );
107  }
108  writer.writeCharacters( str );
109  writer.writeEndElement();
110  }
111  };
112 
113  struct Elements
114  {
115  Elements() : atomNS( Syndication::Atom::atom1Namespace() ),
116  akregatorNS(akregatorNamespace() ),
117  commentNS( Syndication::commentApiNamespace() ),
118  title( atomNS, QLatin1String("title") ),
119  summary( atomNS, QLatin1String("summary") ),
120  content( atomNS, QLatin1String("content") ),
121  link( atomNS, QLatin1String("link") ),
122  language( atomNS, QLatin1String("language") ),
123  feed( atomNS, QLatin1String("feed") ),
124  guid( atomNS, QLatin1String("id") ),
125  published( atomNS, QLatin1String("published") ),
126  updated( atomNS, QLatin1String("updated") ),
127  commentsCount( Syndication::slashNamespace(), QLatin1String("comments") ),
128  commentsFeed( commentNS, QLatin1String("commentRss") ),
129  commentPostUri( commentNS, QLatin1String("comment") ),
130  commentsLink( akregatorNS, QLatin1String("commentsLink") ),
131  hash( akregatorNS, QLatin1String("hash") ),
132  guidIsHash( akregatorNS, QLatin1String("idIsHash") ),
133  name( atomNS, QLatin1String("name") ),
134  uri( atomNS, QLatin1String("uri") ),
135  email( atomNS, QLatin1String("email") ),
136  author( atomNS, QLatin1String("author") ),
137  category( atomNS, QLatin1String("category") ),
138  entry( atomNS, QLatin1String("entry") ),
139  itemProperties( akregatorNS, QLatin1String("itemProperties") ),
140  readStatus( akregatorNS, QLatin1String("readStatus") ),
141  deleted( akregatorNS, QLatin1String("deleted") ),
142  important( akregatorNS, QLatin1String("important") )
143 
144  {}
145  const QString atomNS;
146  const QString akregatorNS;
147  const QString commentNS;
148  const Element title;
149  const Element summary;
150  const Element content;
151  const Element link;
152  const Element language;
153  const Element feed;
154  const Element guid;
155  const Element published;
156  const Element updated;
157  const Element commentsCount;
158  const Element commentsFeed;
159  const Element commentPostUri;
160  const Element commentsLink;
161  const Element hash;
162  const Element guidIsHash;
163  const Element name;
164  const Element uri;
165  const Element email;
166  const Element author;
167  const Element category;
168  const Element entry;
169  const Element itemProperties;
170  const Element readStatus;
171  const Element deleted;
172  const Element important;
173  static const Elements instance;
174  };
175 
176  const Elements Elements::instance;
177 
178  void writeAttributeIfNotEmpty( const QString& ns, const QString& element, const QVariant& value, QXmlStreamWriter& writer )
179  {
180  const QString text = value.toString();
181  if ( text.isEmpty() )
182  return;
183  writer.writeAttribute( ns, element, text );
184  }
185 
186  void writeAttributeIfNotEmpty( const QString& element, const QVariant& value, QXmlStreamWriter& writer )
187  {
188  const QString text = value.toString();
189  if ( text.isEmpty() )
190  return;
191  writer.writeAttribute( element, text );
192  }
193 
194  void writeEnclosure( const QString& url, const QString& type, int length, QXmlStreamWriter& writer )
195  {
196  Elements::instance.link.writeStartElement( writer );
197  writer.writeAttribute( QLatin1String("rel"), QLatin1String("enclosure") );
198  writeAttributeIfNotEmpty( QLatin1String("href"), url, writer );
199  writeAttributeIfNotEmpty( QLatin1String("type"), type, writer );
200  if ( length > 0 )
201  writer.writeAttribute( QLatin1String("length"), QString::number( length ) );
202  writer.writeEndElement();
203  }
204 
205  void writeLink( const QString& url, QXmlStreamWriter& writer )
206  {
207  if ( url.isEmpty() )
208  return;
209  Elements::instance.link.writeStartElement( writer );
210  writer.writeAttribute( QLatin1String("rel"), QLatin1String("alternate") );
211  writeAttributeIfNotEmpty( QLatin1String("href"), url, writer );
212  writer.writeEndElement();
213  }
214 
215  void writeAuthor( const QString& name, const QString& uri, const QString& email, QXmlStreamWriter& writer )
216  {
217  if ( name.isEmpty() && uri.isEmpty() && email.isEmpty() )
218  return;
219 
220  const QString atomNS = Syndication::Atom::atom1Namespace();
221  Elements::instance.author.writeStartElement( writer );
222  Elements::instance.name.write( name, writer );
223  Elements::instance.uri.write( uri, writer );
224  Elements::instance.email.write( email, writer );
225  writer.writeEndElement(); // </author>
226  }
227 
228  static void writeItem( FeedStorage* storage, const QString& guid, QXmlStreamWriter& writer ) {
229  Elements::instance.entry.writeStartElement( writer );
230  Elements::instance.guid.write( guid, writer );
231 
232  const uint published = storage->pubDate( guid );
233  if ( published > 0 ) {
234  const QString pdStr = QDateTime::fromTime_t( published ).toString( Qt::ISODate );
235  Elements::instance.published.write( pdStr, writer );
236  }
237 
238  const int status = storage->status( guid );
239 
240  Elements::instance.itemProperties.writeStartElement( writer );
241 
242  if ( status & Deleted ) {
243  Elements::instance.deleted.write( QString::fromLatin1("true"), writer );
244  writer.writeEndElement(); // </itemProperties>
245  writer.writeEndElement(); // </item>
246  return;
247  }
248 
249  Elements::instance.hash.write( QString::number( storage->hash( guid ) ), writer );
250  if ( storage->guidIsHash( guid ) )
251  Elements::instance.guidIsHash.write( QString::fromLatin1("true"), writer );
252  if ( status & New )
253  Elements::instance.readStatus.write( QString::fromLatin1("new"), writer );
254  else if ( ( status & Read ) == 0 )
255  Elements::instance.readStatus.write( QString::fromLatin1("unread"), writer );
256  if ( status & Keep )
257  Elements::instance.important.write( QString::fromLatin1("true"), writer );
258  writer.writeEndElement(); // </itemProperties>
259 
260  Elements::instance.title.write( storage->title( guid ), writer, Html );
261  writeLink( storage->guidIsPermaLink( guid ) ? guid : storage->link( guid ), writer );
262 
263  Elements::instance.summary.write( storage->description( guid ), writer, Html );
264  Elements::instance.content.write( storage->content( guid ), writer, Html );
265  writeAuthor( storage->authorName( guid ),
266  storage->authorUri( guid ),
267  storage->authorEMail( guid ),
268  writer );
269 
270  if ( const int commentsCount = storage->comments( guid ) )
271  Elements::instance.commentsCount.write( QString::number( commentsCount ), writer );
272 
273  Elements::instance.commentsLink.write( storage->commentsLink( guid ), writer );
274 
275  bool hasEnc = false;
276  QString encUrl, encType;
277  int encLength = 0;
278  storage->enclosure( guid, hasEnc, encUrl, encType, encLength );
279  if ( hasEnc )
280  writeEnclosure( encUrl, encType, encLength, writer );
281  writer.writeEndElement(); // </item>
282  }
283 
284  static void serialize( FeedStorage* storage, const QString& url, QIODevice* device ) {
285  assert( storage );
286  assert( device );
287  QXmlStreamWriter writer( device );
288  writer.setAutoFormatting( true );
289  writer.setAutoFormattingIndent( 2 );
290  writer.writeStartDocument();
291 
292  Elements::instance.feed.writeStartElement( writer );
293 
294  writer.writeDefaultNamespace( Syndication::Atom::atom1Namespace() );
295  writer.writeNamespace( Syndication::commentApiNamespace(), QLatin1String("comment"));
296  writer.writeNamespace( akregatorNamespace(), QLatin1String("akregator") );
297  writer.writeNamespace( Syndication::itunesNamespace(), QLatin1String("itunes") );
298 
299  Elements::instance.title.write( QString::fromLatin1("Akregator Export for %1").arg( url ), writer, Html );
300 
301 
302  Q_FOREACH( const QString& i, storage->articles() )
303  writeItem( storage, i, writer );
304  writer.writeEndElement(); // </feed>
305  writer.writeEndDocument();
306  }
307 
308  static void serialize( Storage* storage, const QString& url, QIODevice* device ) {
309  serialize( storage->archiveFor( url ), url, device );
310  }
311 
312  static KService::List queryStoragePlugins() {
313  return KServiceTypeTrader::self()->query( QLatin1String("Akregator/Plugin"),
314  QString::fromLatin1( "[X-KDE-akregator-framework-version] == %1 and [X-KDE-akregator-plugintype] == 'storage' and [X-KDE-akregator-rank] > 0" ).arg( QString::number( AKREGATOR_PLUGIN_INTERFACE_VERSION ) ) );
315  }
316 
317  static Plugin* createFromService( const KService::Ptr& service )
318  {
319  KPluginLoader loader( *service );
320  KPluginFactory* factory = loader.factory();
321  if ( !factory ) {
322  qCritical() << QString::fromLatin1( " Could not create plugin factory for: %1\n"
323  " Error message: %2" ).arg( service->library(), loader.errorString() );
324  return 0;
325  }
326  return factory->create<Akregator::Plugin>();
327  }
328 
329  static void printUsage() {
330  std::cout << "akregatorstorageexporter [--base64] url" << std::endl;
331  }
332 }
333 
334 
335 int main( int argc, char** argv ) {
336  KGlobal::setActiveComponent( KComponentData( "akregatorstorageexporter" ) );
337  const QString backend = QString::fromLatin1( "metakit" );
338 
339  if ( argc < 2 ) {
340  printUsage();
341  return 1;
342  }
343 
344  const bool base64 = qstrcmp( argv[1], "--base64" ) == 0;
345 
346  if ( base64 && argc < 3 ) {
347  printUsage();
348  return 1;
349  }
350 
351  const int pos = base64 ? 2 : 1;
352  const QString url = KUrl::fromEncoded( base64 ? QByteArray::fromBase64( argv[pos] ) : QByteArray( argv[pos] ) ).toString();
353 
354  Q_FOREACH( const KService::Ptr& i, queryStoragePlugins() )
355  if ( Plugin* const plugin = createFromService( i ) )
356  plugin->initialize();
357 
358  const StorageFactory* const storageFactory = StorageFactoryRegistry::self()->getFactory( backend );
359  if ( !storageFactory ) {
360  qCritical( "Could not create storage factory for %s.", qPrintable( backend ) );
361  return 1;
362  }
363 
364  Storage* const storage = storageFactory->createStorage( QStringList() );
365  if ( !storage ) {
366  qCritical( "Could not create storage object for %s.", qPrintable( backend ) );
367  return 1;
368  }
369 
370  QFile out;
371  if ( !out.open( stdout, QIODevice::WriteOnly ) ) {
372  qCritical( "Could not open stdout for writing: %s", qPrintable( out.errorString() ) );
373  return 1;
374  }
375 
376  serialize( storage, url, &out );
377 
378  return 0;
379 }
storagefactoryregistry.h
Akregator::Backend::FeedStorage::hash
virtual uint hash(const QString &guid) const =0
TextMode
TextMode
Definition: akregatorstorageexporter.cpp:59
Akregator::Backend::FeedStorage::articles
virtual QStringList articles(const QString &tagID=QString()) const =0
returns the guids of all articles in this storage.
Akregator::Backend::FeedStorage::status
virtual int status(const QString &guid) const =0
AKREGATOR_PLUGIN_INTERFACE_VERSION
#define AKREGATOR_PLUGIN_INTERFACE_VERSION
Definition: plugin.h:37
Akregator::Backend::FeedStorage::authorName
virtual QString authorName(const QString &guid) const =0
Akregator::Backend::FeedStorage::guidIsHash
virtual bool guidIsHash(const QString &guid) const =0
uint
unsigned int uint
Definition: article.h:39
plugin.h
Status
Status
Definition: akregatorstorageexporter.cpp:64
Akregator::Backend::Storage
Storage is the main interface to the article archive.
Definition: storage.h:43
Akregator::Backend::StorageFactoryRegistry::self
static StorageFactoryRegistry * self()
Definition: storagefactoryregistry.cpp:43
Akregator::Plugin
Definition: plugin.h:41
Akregator::New
article was fetched in the last fetch of it's feed and not read yet.
Definition: types.h:33
Akregator::Backend::FeedStorage::content
virtual QString content(const QString &guid) const =0
Akregator::Backend::FeedStorage::title
virtual QString title(const QString &guid) const =0
Akregator::Backend::FeedStorage::comments
virtual int comments(const QString &guid) const =0
Akregator::Backend::StorageFactory
Definition: storagefactory.h:37
Akregator::Read
article is read
Definition: types.h:32
Akregator::Backend::FeedStorage
Definition: feedstorage.h:66
storagefactory.h
storage.h
main
int main(int argc, char **argv)
Definition: akregatorstorageexporter.cpp:335
Akregator::Backend::StorageFactoryRegistry::getFactory
StorageFactory * getFactory(const QString &typestr)
Definition: storagefactoryregistry.cpp:64
Akregator::Backend::FeedStorage::pubDate
virtual uint pubDate(const QString &guid) const =0
Akregator::Backend::FeedStorage::guidIsPermaLink
virtual bool guidIsPermaLink(const QString &guid) const =0
Akregator::Backend::FeedStorage::enclosure
virtual void enclosure(const QString &guid, bool &hasEnclosure, QString &url, QString &type, int &length) const =0
Akregator::Backend::StorageFactory::createStorage
virtual Storage * createStorage(const QStringList &params) const =0
creates a storage object with given parameters
Akregator::Backend::FeedStorage::authorUri
virtual QString authorUri(const QString &guid) const =0
Akregator::Backend::FeedStorage::authorEMail
virtual QString authorEMail(const QString &guid) const =0
Akregator::Backend::Storage::archiveFor
virtual FeedStorage * archiveFor(const QString &url)=0
Akregator::Backend::FeedStorage::commentsLink
virtual QString commentsLink(const QString &guid) const =0
Akregator::Backend::FeedStorage::link
virtual QString link(const QString &guid) const =0
feedstorage.h
Akregator::Backend::FeedStorage::description
virtual QString description(const QString &guid) const =0
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:58:14 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akregator

Skip menu "akregator"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal