[Amarok] [BAD EMAIL] fix SqlPodcastMeta copy constructor, partial rewri
Bart Cerneels
bart.cerneels at kde.org
Wed Nov 18 12:06:41 CET 2009
PodcastReader creates channels and episode objects from the base class
and then passes this to PodcastProvider::add[Episode|Channel]. It
creates objects from it's own type using the copy constructor and then
returns a pointer to this new object.
They will probably also be used for synchronization between channels.
There are other ways to do this but a copy constructor is certainly
the cleanest.
Bart
On Wed, Nov 18, 2009 at 11:49, Maximilian Kossick
<maximilian.kossick at googlemail.com> wrote:
> bart, why do these classes have a copy constructor at all?
>
>
> ---------- Forwarded message ----------
> From: .mail.kde.org Mathias Panzenböck <panzi at panzi>
> Date: Wed, Nov 18, 2009 at 10:51 AM
> Subject: [Amarok] [BAD EMAIL] fix SqlPodcastMeta copy constructor,
> partial rewri
> To: kde-commits at kde.org
>
>
> commit 6569866efd63a698a63ecefbb381cff03fd8f3dd
> Author: Mathias Panzenböck <panzi at panzi.(none)>
> AuthorDate: Sun Nov 15 19:07:39 2009 +0100
> Commit: Mathias Panzenböck <panzi at panzi.(none)>
> CommitDate: Sun Nov 15 19:07:39 2009 +0100
>
> fix SqlPodcastMeta copy constructor, partial rewrite of PodcastReader
>
> In the copy constructor of SqlPodcastMeta where not all fields copied.
> Started a partial rewrite of PodcastReader. Currently there is a strange
> bug where the subscriptions are doubled on each feed update.
> Made HTML generated by PodcastCategory more nice.
>
> diff --git a/src/browsers/playlistbrowser/PodcastCategory.cpp
> b/src/browsers/playlistbrowser/PodcastCategory.cpp
> index a72db3c..969de87 100644
> --- a/src/browsers/playlistbrowser/PodcastCategory.cpp
> +++ b/src/browsers/playlistbrowser/PodcastCategory.cpp
> @@ -40,6 +40,7 @@
> #include <QToolBar>
> #include <QVBoxLayout>
> #include <QWebFrame>
> +#include <QTextDocument>
> #include <qnamespace.h>
>
> #include <KAction>
> @@ -154,12 +155,30 @@ PodcastCategory::~PodcastCategory()
> void
> PodcastCategory::showInfo( const QModelIndex & index )
> {
> - QString description = index.data( ShortDescriptionRole ).toString();
> - description.replace( QRegExp("\n "), "\n" );
> - description.replace( QRegExp("\n+"), "\n" );
> + QString title = index.data( Qt::DisplayRole ).toString();
> + QString description =
> + "<html>"
> + " <head>"
> + " <title>";
> + description += Qt::escape(title);
> + description += "</title>"
> + " <style type=\"text/css\">h1
> {text-align:center; font-size: 1em;}</style>"
> + " </head>"
> + " <body>"
> + " <h1>";
> + description += Qt::escape(title);
> + description += "</h1>";
> + description += index.data( ShortDescriptionRole ).toString();
> + description +=
> + " </body>"
> + "</html>";
> +
> + qDebug("\n");
> + qDebug() << description;
> + qDebug("\n");
>
> QVariantMap map;
> - map["service_name"] = "Podcasts";
> + map["service_name"] = title;
> map["main_info"] = description;
> The::infoProxy()->setInfo( map );
> }
> diff --git a/src/context/applets/info/InfoApplet.cpp
> b/src/context/applets/info/InfoApplet.cpp
> index 7c58812..01f483e 100644
> --- a/src/context/applets/info/InfoApplet.cpp
> +++ b/src/context/applets/info/InfoApplet.cpp
> @@ -90,11 +90,9 @@ void InfoApplet::dataUpdated( const QString& name,
> const Plasma::DataEngine::Dat
>
> if ( m_initialized )
> {
> - if ( !data[ "main_info" ].toString().isEmpty() )
> + QString currentHtml = data[ "main_info" ].toString();
> + if ( !currentHtml.isEmpty() )
> {
> -
> - QString currentHtml = data[ "main_info" ].toString();
> -
> QColor highlight( App::instance()->palette().highlight().color() );
> highlight.setHsvF( highlight.hueF(), 0.3, .95, highlight.alphaF() );
> currentHtml = currentHtml.replace( "{text_color}",
> App::instance()->palette().brush( QPalette::Text ).color().name() );
> @@ -106,9 +104,9 @@ void InfoApplet::dataUpdated( const QString& name,
> const Plasma::DataEngine::Dat
> }
> else
> {
> - QString html = s_defaultHtml;
> - html = html.replace( "%%SUBJECT_NAME%%", data[
> "subject_name" ].toString() );
> - m_webView->setHtml( html );
> + currentHtml = s_defaultHtml;
> + currentHtml = currentHtml.replace( "%%SUBJECT_NAME%%",
> data[ "subject_name" ].toString() );
> + m_webView->setHtml( currentHtml );
> }
>
> m_webView->page()->setLinkDelegationPolicy(
> QWebPage::DelegateAllLinks );
> diff --git a/src/podcasts/PodcastReader.cpp b/src/podcasts/PodcastReader.cpp
> index 9b503b7..042413f 100644
> --- a/src/podcasts/PodcastReader.cpp
> +++ b/src/podcasts/PodcastReader.cpp
> @@ -23,6 +23,7 @@
> #include <kurl.h>
> #include <KDateTime>
>
> +#include <QTextDocument>
> #include <QDate>
> #include <time.h>
>
> @@ -33,8 +34,6 @@ PodcastReader::PodcastReader( PodcastProvider *
> podcastProvider )
> , m_feedType( UnknownFeedType )
> , m_podcastProvider( podcastProvider )
> , m_transferJob( 0 )
> - , m_current( 0 )
> - , m_parsingImage( false )
> {}
>
> PodcastReader::~PodcastReader()
> @@ -61,7 +60,7 @@ PodcastReader::read( const KUrl &url )
> connect( m_transferJob, SIGNAL( data( KIO::Job *, const QByteArray & ) ),
> SLOT( slotAddData( KIO::Job *, const QByteArray & ) ) );
>
> - connect( m_transferJob, SIGNAL( result( KJob * ) ),
> + connect( m_transferJob, SIGNAL( result( KJob * ) ),
> SLOT( downloadResult( KJob * ) ) );
>
> connect( m_transferJob, SIGNAL( redirection( KIO::Job *, const KUrl & ) ),
> @@ -96,7 +95,6 @@ PodcastReader::update( PodcastChannelPtr channel )
> {
> DEBUG_BLOCK
> m_channel = channel;
> - m_current = static_cast<PodcastMetaCommon *>(channel.data());
>
> return read( m_channel->url() );
> }
> @@ -107,9 +105,7 @@ PodcastReader::slotAddData( KIO::Job *job, const
> QByteArray &data )
> DEBUG_BLOCK
> Q_UNUSED( job )
>
> - QXmlStreamReader::addData( data );
> - //parse some more data
> - read();
> + qxml::addData( data );
> }
>
> void
> @@ -146,206 +142,369 @@ PodcastReader::downloadResult( KJob * job )
>
> The::statusBar()->longMessage( errorMessage, StatusBar::Sorry );
> }
> - //parse some more data
> +
> + // parse data
> read();
> }
>
> -bool
> -PodcastReader::read()
> +QString
> +PodcastReader::readInnerXml()
> {
> - DEBUG_BLOCK
> - bool result = true;
> + QString xml;
> + int level = 1;
>
> while ( !atEnd() )
> {
> - if( !error() )
> - {
> - readNext();
> - }
> - else if ( error() == PrematureEndOfDocumentError )
> - {
> - debug() << "recovering from PrematureEndOfDocumentError for "
> - << QXmlStreamReader::name().toString() << " at "
> - << QXmlStreamReader::lineNumber();
> - readNext();
> - }
> - else
> - {
> - debug() << "some other error occurred: " << errorString();
> - m_transferJob->kill();
> - m_transferJob = 0;
> - emit finished( this );
> - }
> + switch ( nextToken() ) {
> + case Invalid:
> + // this should not happen
> + debug() << "*** Invalid *** " << errorString();
> + return xml;
> +
> + case StartElement:
> + ++ level;
> + xml += QString("<%1").arg(qxml::name().toString());
> +
> + foreach( const QXmlStreamAttribute& attr,
> attributes() ) {
> + xml += QString(" %1=\"%2\"")
> + .arg(attr.name().toString())
> +
> .arg(Qt::escape(attr.value().toString()));
> + }
> + xml += '>';
> + break;
> +
> + case EndElement:
> + -- level;
> + if (level == 0)
> + return xml;
> + xml += QString("</%1>").arg(qxml::name().toString());
> + break;
> +
> + case Characters:
> + xml += text();
> +
> + default:
> + break;
> + }
> + }
> +
> + return xml;
> +}
>
> - if( m_feedType == UnknownFeedType )
> - {
> - //Pre Channel
> - if( isStartElement() )
> - {
> - debug() << "Initial StartElement: " <<
> QXmlStreamReader::name().toString();
> - debug() << "version: " << attributes().value (
> "version" ).toString();
> - if( QXmlStreamReader::name() == "rss" &&
> attributes().value ( "version" ) == "2.0" )
> - {
> - m_feedType = Rss20FeedType;
> - }
> - else if( QXmlStreamReader::name() == "html" )
> - {
> - m_feedType = ErrorPageType;
> - raiseError( i18n( "An HTML page was received.
> Expected an RSS 2.0 feed" ) );
> - result = false;
> - break;
> - }
> - else
> - {
> - //TODO: change this string once we support more
> - raiseError( i18n( "%1 is not an RSS version 2.0
> feed.", m_url.url() ) );
> - result = false;
> - break;
> - }
> - }
> - else if( tokenType() != QXmlStreamReader::StartDocument )
> - {
> - debug() << "some weird thing happend at line: "
> - << QXmlStreamReader::lineNumber();
> - debug() << "\terror: " << QXmlStreamReader::name().toString();
> - debug() << "\ttoken type: " << tokenString();
> - }
> - }
> - else
> - {
> - if( isStartElement() )
> - {
> - if( QXmlStreamReader::name() == "item" )
> - {
> - debug() << "new episode";
> - m_current = new Meta::PodcastEpisode( m_channel );
> - }
> - else if( QXmlStreamReader::name() == "enclosure" )
> - {
> - m_urlString =
> QXmlStreamReader::attributes().value( QString(), QString("url")
> ).toString();
> - }
> - else if( QXmlStreamReader::name() == "image" )
> - {
> - m_parsingImage = true;
> - }
> - else if( QXmlStreamReader::name() == "channel" )
> - {
> - if( !m_current )
> - {
> - debug() << "new channel";
> - m_channel = new Meta::PodcastChannel();
> - m_channel->setUrl( m_url );
> - m_channel->setSubscribeDate( QDate::currentDate() );
> - /* add this new channel to the provider, we
> get a pointer to a
> - * PodcastChannelPtr of the correct type which
> we will use from now on.
> - */
> - m_channel = m_podcastProvider->addChannel( m_channel );
> -
> - m_current =
> static_cast<Meta::PodcastMetaCommon *>( m_channel.data() );
> - }
> - }
> - m_currentTag = QXmlStreamReader::name().toString();
> - }
> - else if( isEndElement() )
> - {
> - if (QXmlStreamReader::name() == "item")
> - {
> - commitEpisode();
> - }
> - else if( QXmlStreamReader::name() == "channel" )
> - {
> - commitChannel();
> - emit finished( this );
> - break;
> - }
> - else if( QXmlStreamReader::name() == "title")
> - {
> - if( !m_parsingImage )
> - {
> - // Remove redundant whitespace from the title.
> - m_current->setTitle( m_titleString.simplified() );
> - }
> - //TODO save image data
> - m_titleString.clear();
> - }
> - else if( QXmlStreamReader::name() == "description" )
> - {
> - m_current->setDescription( m_descriptionString );
> - m_descriptionString.clear();
> - }
> - else if( QXmlStreamReader::name() == "guid" )
> - {
> - static_cast<PodcastEpisode
> *>(m_current)->setGuid( m_guidString );
> - m_guidString.clear();
> - }
> - else if( QXmlStreamReader::name() == "enclosure" )
> - {
> - static_cast<PodcastEpisode
> *>(m_current)->setUidUrl( KUrl( m_urlString ) );
> - m_urlString.clear();
> - }
> - else if( QXmlStreamReader::name() == "link" )
> - {
> - if( !m_parsingImage )
> - m_channel->setWebLink( KUrl( m_linkString ) );
> - //TODO save image data
> - m_linkString.clear();
> - }
> - else if( QXmlStreamReader::name() == "pubDate")
> - {
> - PodcastEpisode * episode =
> dynamic_cast<PodcastEpisode *>(m_current);
> - if( episode )
> - episode->setPubDate( parsePubDate( m_pubDateString ) );
> - m_pubDateString.clear();
> - }
> - else if( QXmlStreamReader::name() == "image" )
> - {
> - m_parsingImage = false;
> - }
> - else if( QXmlStreamReader::name() == "url" && m_parsingImage )
> - {
> - if( m_channel )
> - m_channel->setImageUrl( KUrl( m_urlString ) );
> - m_urlString.clear();
> - }
> - }
> - else if( isCharacters() && !isWhitespace() )
> - {
> - if( m_currentTag == "title" )
> - m_titleString += text().toString();
> - else if( m_currentTag == "link" )
> - m_linkString += text().toString();
> - else if( m_currentTag == "description" )
> - m_descriptionString += text().toString();
> - else if( m_currentTag == "pubDate" )
> - m_pubDateString += text().toString();
> - else if( m_currentTag == "guid" )
> - m_guidString += text().toString();
> - else if( m_currentTag == "url" )
> - m_urlString += text().toString();
> - }
> - }
> - }
> +QXmlStreamReader::TokenType
> +PodcastReader::nextRawToken()
> +{
> + TokenType token = NoToken;
> +
> + for (int repeat = 0; repeat < 3; ++ repeat) {
> + token = readNext();
>
> - if ( error() )
> - {
> - if ( error() == QXmlStreamReader::PrematureEndOfDocumentError)
> - {
> - debug() << "waiting for data at line " << lineNumber();
> - }
> - else
> - {
> - debug() << "XML ERROR: " << error() << " at line: " << lineNumber()
> - << ": " << columnNumber()
> - << "\n\t" << errorString();
> - debug() << "\tname = " << QXmlStreamReader::name().toString()
> - << " tokenType = " << tokenString();
> -
> - if( m_channel )
> - commitChannel();
> - emit finished( this );
> - }
> - }
> - return result;
> + if ( error() != PrematureEndOfDocumentError )
> + break;
> +
> + debug() << "recovering from PrematureEndOfDocumentError for "
> + << qxml::name().toString() << " at "
> + << qxml::lineNumber();
> + }
> +
> + if( error() ) {
> + throw XmlParseError( errorString() );
> + }
> +
> + return token;
> +}
> +
> +QXmlStreamReader::TokenType
> +PodcastReader::nextToken()
> +{
> + TokenType token = NoToken;
> +
> + do {
> + token = nextRawToken();
> +
> + switch ( token ) {
> + case Invalid:
> + case StartDocument:
> + case EndDocument:
> + case StartElement:
> + case EndElement:
> + return token;
> +
> + case Characters:
> + if ( !isWhitespace() )
> + return token;
> + break;
> +
> + case NoToken:
> + case Comment:
> + case DTD:
> + case EntityReference:
> + case ProcessingInstruction:
> + // ignore
> + break;
> + }
> + } while ( !atEnd() );
> +
> + return token;
> +}
> +
> +void
> +PodcastReader::expect(TokenType expected, TokenType got) {
> + if ( got != expected )
> + throw ParseError( i18n( "expected token %1, but got
> token %2", expected, got ) );
> +}
> +
> +void
> +PodcastReader::expect(TokenType expected) {
> + expect( expected, nextToken() );
> +}
> +
> +void
> +PodcastReader::expectName(const QString& name) {
> + if ( qxml::name() != name )
> + throw ParseError( i18n( "expected element name %1, but
> got element name %2",
> + name, qxml::name().toString() ) );
> +}
> +
> +void
> +PodcastReader::expectStart(const QString& name) {
> + expect(StartElement);
> + expectName(name);
> +}
> +
> +void
> +PodcastReader::expectEnd(const QString& name) {
> + expect(EndElement);
> + expectName(name);
> +}
> +
> +QString
> +PodcastReader::readTextContent() {
> + QString text = readElementText();
> +
> + if ( error() )
> + throw ParseError( errorString() );
> +
> + return text;
> +}
> +
> +bool
> +PodcastReader::read()
> +{
> + DEBUG_BLOCK
> +
> + try {
> + m_feedType = UnknownFeedType;
> +
> + expect(StartDocument);
> + expect(StartElement);
> +
> + QStringRef version = attributes().value( "version" );
> +
> + debug() << "Initial StartElement: " << qxml::name().toString();
> + debug() << "version: " << version.toString();
> +
> + if ( qxml::name() == "rss" && version == "2.0" ) {
> + m_feedType = Rss20FeedType;
> + }
> + else if ( qxml::name() == "html" || qxml::name() == "HTML" ) {
> + m_feedType = ErrorPageType;
> + throw ParseError( i18n( "An HTML page was
> received. Expected an RSS 2.0 feed" ) );
> + }
> + else {
> + // TODO: change this string once we support more
> + throw ParseError( i18n( "%1 is not an RSS
> version 2.0 feed.", m_url.url() ) );
> + }
> +
> + // rss 2.0 specifies exactly one channel element per feed
> + readChannel();
> +
> + expect(EndElement);
> + expect(EndDocument);
> + }
> + catch (XmlParseError& e) {
> + debug() << "XML ERROR: " << error() << " at line: " <<
> lineNumber()
> + << ": " << columnNumber()
> + << "\n\t" << errorString();
> + debug() << "\tname = " << qxml::name().toString()
> + << " tokenType = " << tokenString();
> +
> + if (m_transferJob) {
> + m_transferJob->kill();
> + m_transferJob = NULL;
> + }
> +
> + emit finished( this );
> + return false;
> + }
> + catch (ParseError& e) {
> + debug() << "error parsing podcast feed: " << e.message();
> +
> + raiseError( e.message() );
> +
> + if (m_transferJob) {
> + m_transferJob->kill();
> + m_transferJob = NULL;
> + }
> +
> + emit finished( this );
> + return false;
> + }
> +
> + emit finished( this );
> + return true;
> +}
> +
> +KUrl
> +PodcastReader::readImage() {
> + expectName("image");
> +
> + KUrl url;
> +
> + for (TokenType token = nextToken(); token != EndElement; token
> = nextToken()) {
> + // elements: url, title, link
> + expect( token, StartElement );
> +
> + if ( qxml::name() == "url" ) {
> + url = KUrl( readTextContent() );
> + }
> + else if ( qxml::name() == "link" || qxml::name() == "title" ) {
> + // not supported but well known
> + skipElement();
> + }
> + else {
> + debug() << "skipping unsupported image
> element: " << qxml::name().toString();
> + skipElement();
> + }
> + }
> + expectName("image");
> +
> + return url;
> +}
> +
> +void
> +PodcastReader::readChannel() {
> + DEBUG_BLOCK
> +
> + expectStart("channel");
> +
> + DescriptionType hasDescription = NoDescription;
> + m_channel = new Meta::PodcastChannel();
> + m_channel->setUrl( m_url );
> + m_channel->setSubscribeDate( QDate::currentDate() );
> + /* add this new channel to the provider, we get a pointer to a
> + * PodcastChannelPtr of the correct type which we will use from now on.
> + */
> + m_channel = m_podcastProvider->addChannel( m_channel );
> +
> + for (TokenType token = nextToken(); token != EndElement; token
> = nextToken()) {
> + // required elements: title, link, description
> + // optional elements: language, copyright, pubDate,
> category, image, ...
> +
> + expect( token, StartElement );
> +
> + if ( qxml::name() == "title" ) {
> + // Remove redundant whitespace from the title.
> + m_channel->setTitle( readTextContent().simplified() );
> + }
> + else if ( qxml::name() == "description" ) {
> + if ( hasDescription <= RssDescription ) {
> + m_channel->setDescription( readTextContent() );
> + hasDescription = RssDescription;
> + }
> + }
> + else if ( qxml::name() == "summary" && namespaceUri()
> == "http://www.itunes.com/dtds/podcast-1.0.dtd" ) {
> + if ( hasDescription <= ItunesSummary ) {
> + m_channel->setDescription( readTextContent() );
> + hasDescription = ItunesSummary;
> + }
> + }
> + else if ( qxml::name() == "body" ) {
> + if ( hasDescription <= HtmlBody ) {
> + m_channel->setDescription( readInnerXml() );
> + hasDescription = HtmlBody;
> + }
> + }
> + else if ( qxml::name() == "link" ) {
> + m_channel->setWebLink( KUrl( readTextContent() ) );
> + }
> + else if ( qxml::name() == "image" ) {
> + // TODO save image data
> + m_channel->setImageUrl( readImage() );
> + }
> + else if ( qxml::name() == "item" ) {
> + Meta::PodcastEpisodePtr item = readItem();
> +
> + if (
> !m_podcastProvider->possiblyContainsTrack( item->uidUrl() ) ) {
> + Meta::PodcastEpisodePtr episode =
> m_channel->addEpisode( item );
> + // also let the provider know an
> episode has been added
> + // TODO: change into a signal
> + m_podcastProvider->addEpisode( episode );
> + }
> + }
> + else {
> + debug() << "skipping unsupported channel
> element: " << qxml::name().toString();
> + skipElement();
> + }
> + }
> +
> + expectName("channel");
> +}
> +
> +Meta::PodcastEpisodePtr
> +PodcastReader::readItem() {
> + DEBUG_BLOCK
> +
> + expectName("item");
> +
> + Meta::PodcastEpisodePtr item( new Meta::PodcastEpisode( m_channel ) );
> + DescriptionType hasDescription = NoDescription;
> +
> + for (TokenType token = nextToken(); token != EndElement; token
> = nextToken()) {
> + // elements: title, link, description, author, category,
> + // comments, enclosure, guid, pubDate, source
> + // extension elements: body, itunes:summary
> +
> + if ( qxml::name() == "title" ) {
> + item->setTitle( readTextContent().simplified() );
> + }
> + else if ( qxml::name() == "description" ) {
> + if ( hasDescription <= RssDescription ) {
> + item->setDescription( readTextContent() );
> + hasDescription = RssDescription;
> + }
> + }
> + else if ( qxml::name() == "summary" && namespaceUri()
> == "http://www.itunes.com/dtds/podcast-1.0.dtd" ) {
> + if ( hasDescription <= ItunesSummary ) {
> + item->setDescription( readTextContent() );
> + hasDescription = ItunesSummary;
> + }
> + }
> + else if ( qxml::name() == "body" ) {
> + if ( hasDescription <= HtmlBody ) {
> + item->setDescription( readInnerXml() );
> + hasDescription = HtmlBody;
> + }
> + }
> + else if ( qxml::name() == "enclosure" ) {
> + item->setUidUrl( KUrl( attributes().value(
> "url" ).toString() ) );
> + skipElement();
> + }
> + else if ( qxml::name() == "guid" ) {
> + item->setGuid( readTextContent() );
> + }
> + else if ( qxml::name() == "pubDate" ) {
> + item->setPubDate( parsePubDate( readTextContent() ) );
> + }
> + else {
> + debug() << "skipping unsupported item element:
> " << qxml::name().toString();
> + skipElement();
> + }
> + }
> +
> + expectName("item");
> +
> + return item;
> }
>
> QDateTime
> @@ -365,23 +524,20 @@ PodcastReader::parsePubDate( const QString &dateString )
> }
>
> void
> -PodcastReader::readUnknownElement()
> +PodcastReader::skipElement()
> {
> DEBUG_BLOCK
> Q_ASSERT ( isStartElement() );
>
> - debug() << "unknown element: " << QXmlStreamReader::name().toString();
> -
> - while ( !atEnd() )
> - {
> - readNext();
> -
> - if ( isEndElement() )
> - break;
> + int level = 1;
>
> - if ( isStartElement() )
> - readUnknownElement();
> - }
> + while (level > 0) {
> + switch ( nextToken() ) {
> + case StartElement: ++ level; break;
> + case EndElement: -- level; break;
> + default: break;
> + }
> + }
> }
>
> void
> @@ -407,43 +563,6 @@ PodcastReader::slotPermanentRedirection( KIO::Job
> * job, const KUrl & fromUrl,
> m_channel->setUrl( m_url );
> }
>
> -void
> -PodcastReader::commitChannel()
> -{
> - Q_ASSERT( m_channel );
> - //TODO: we probably need to notify the provider here to we are
> done updating the channel
> -// emit finished( this );
> -}
> -
> -void
> -PodcastReader::commitEpisode()
> -{
> - DEBUG_BLOCK
> - Q_ASSERT( m_current );
> - PodcastEpisodePtr item = PodcastEpisodePtr(
> static_cast<PodcastEpisode *>(m_current) );
> -//
> -// PodcastEpisodePtr episodeMatch = podcastEpisodeCheck( item );
> -// if( episodeMatch == item )
> -// {
> -// debug() << "commit episode " << item->title();
> -//
> -// Q_ASSERT( m_channel );
> -// //make a copy of the pointer and add that to the channel
> -// m_channel->addEpisode( PodcastEpisodePtr( item ) );
> -// }
> -
> - if( !m_podcastProvider->possiblyContainsTrack( item->uidUrl() ) )
> - {
> - Meta::PodcastEpisodePtr episode = PodcastEpisodePtr( item );
> - episode = m_channel->addEpisode( episode );
> - //also let the provider know an episode has been added
> - //TODO: change into a signal
> - m_podcastProvider->addEpisode( episode );
> - }
> -
> - m_current = static_cast<PodcastMetaCommon *>( m_channel.data() );
> -}
> -
> Meta::PodcastEpisodePtr
> PodcastReader::podcastEpisodeCheck( Meta::PodcastEpisodePtr episode )
> {
> diff --git a/src/podcasts/PodcastReader.h b/src/podcasts/PodcastReader.h
> index 7e58159..939048c 100644
> --- a/src/podcasts/PodcastReader.h
> +++ b/src/podcasts/PodcastReader.h
> @@ -24,6 +24,7 @@
> #include <QXmlStreamReader>
> #include <QObject>
>
> +
> namespace KIO
> {
> class Job;
> @@ -63,26 +64,64 @@ class PodcastReader : public QObject, public
> QXmlStreamReader
> void downloadResult( KJob * );
>
> private:
> + typedef QXmlStreamReader qxml;
> +
> + /** internally used exception class */
> + class ParseError {
> + public:
> + ParseError(const QString& message)
> + : m_message(message) {}
> +
> + const QString& message() const { return m_message; }
> +
> + private:
> + QString m_message;
> + };
> +
> + class XmlParseError : public ParseError {
> + public:
> + XmlParseError(const QString& message)
> + : ParseError(message) {}
> + };
> +
> + /** This method wraps readNext() and tries to fix the
> PrematureEndOfDocumentError. */
> + TokenType nextRawToken();
> +
> + /** Like nextRawToken() but skips Comments, DTDs,
> EntityReferences,
> + * ProcessingInstructions and ignorable whitespaces. */
> + TokenType nextToken();
> +
> + static void expect(TokenType expected, TokenType got);
> +
> + void expect(TokenType token);
> + void expectName(const QString& name);
> + void expectStart(const QString& name);
> + void expectEnd(const QString& name);
> +
> + /** Read the inner xml of an element as a string. This
> is used to read the
> + * contents of a <body> element, which contains
> xhtml data. */
> + QString readInnerXml();
> +
> + /** Read text content of an element. Raises error if
> non text content (elements) is read. */
> + QString readTextContent();
> +
> + void readChannel();
> + Meta::PodcastEpisodePtr readItem();
> + KUrl readImage();
> +
> + /** There usually are 3 kinds of descriptions. Usually
> a <body> element contains
> + * the most detailed description followed by
> <itunes:summary> and the standard
> + * <description>. */
> + enum DescriptionType { NoDescription = 0,
> RssDescription = 1, ItunesSummary = 2, HtmlBody = 3 };
> enum FeedType { UnknownFeedType, ErrorPageType, Rss20FeedType };
>
> FeedType m_feedType;
> KUrl m_url;
> PodcastProvider * m_podcastProvider;
> KIO::TransferJob *m_transferJob;
> - Meta::PodcastMetaCommon *m_current;
> Meta::PodcastChannelPtr m_channel;
>
> - QString m_currentTag;
> - QString m_titleString;
> - QString m_linkString;
> - QString m_descriptionString;
> - QString m_urlString;
> - QString m_guidString;
> - QString m_pubDateString;
> -
> - bool m_parsingImage;
> -
> - void readUnknownElement();
> + void skipElement();
>
> QDateTime parsePubDate( const QString &datestring );
>
> @@ -92,9 +131,6 @@ class PodcastReader : public QObject, public QXmlStreamReader
> * same pointer as the argument.
> */
> Meta::PodcastEpisodePtr podcastEpisodeCheck(
> Meta::PodcastEpisodePtr episode );
> -
> - void commitChannel();
> - void commitEpisode();
> };
>
> #endif
> diff --git a/src/podcasts/sql/SqlPodcastMeta.cpp
> b/src/podcasts/sql/SqlPodcastMeta.cpp
> index d719ad1..bc25d1c 100644
> --- a/src/podcasts/sql/SqlPodcastMeta.cpp
> +++ b/src/podcasts/sql/SqlPodcastMeta.cpp
> @@ -121,11 +121,11 @@ Meta::SqlPodcastEpisode::SqlPodcastEpisode(
> const QStringList &result, Meta::Sql
> }
> }
>
> +// XXX: why do PodcastMetaCommon and PodcastEpisode not have an
> apropriate copy constructor?
> Meta::SqlPodcastEpisode::SqlPodcastEpisode( Meta::PodcastEpisodePtr episode )
> : Meta::PodcastEpisode()
> , m_dbId( 0 )
> {
> - m_url = KUrl( episode->uidUrl() );
> m_channel = SqlPodcastChannelPtr::dynamicCast( episode->channel() );
>
> if ( !m_channel && episode->channel()) {
> @@ -133,10 +133,31 @@ Meta::SqlPodcastEpisode::SqlPodcastEpisode(
> Meta::PodcastEpisodePtr episode )
> debug() << episode->channel()->title();
> }
>
> - m_localUrl = episode->localUrl();
> + // PodcastMetaCommon
> m_title = episode->title();
> + m_description = episode->description();
> + m_keywords = episode->keywords();
> + m_subtitle = episode->subtitle();
> + m_summary = episode->summary();
> + m_author = episode->author();
> +
> + // PodcastEpisode
> m_guid = episode->guid();
> + m_url = KUrl( episode->uidUrl() );
> + m_localUrl = episode->localUrl();
> +// m_mimeType = episode->mimeType();
> m_pubDate = episode->pubDate();
> + m_duration = episode->duration();
> + m_fileSize = episode->filesize();
> + m_sequenceNumber = episode->sequenceNumber();
> + m_isNew = episode->isNew();
> +
> + // I'm not sure about this:
> + m_albumPtr = episode->album();
> + m_artistPtr = episode->artist();
> + m_composerPtr = episode->composer();
> + m_genrePtr = episode->genre();
> + m_yearPtr = episode->year();
>
> //commit to the database
> updateInDb();
> _______________________________________________
> Amarok-devel mailing list
> Amarok-devel at kde.org
> https://mail.kde.org/mailman/listinfo/amarok-devel
>
More information about the Amarok-devel
mailing list