/* Copyright (c) 2005 by Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US */ #include "nntpjobs.h" #include "kngroup.h" #include "kngroupmanager.h" #include "knserverinfo.h" #include #include #include KNode::GroupListJob::GroupListJob( KNJobConsumer *c, KNServerInfo::Ptr a, KNJobItem::Ptr i, bool incremental ) : KNJobData( KNJobData::JTFetchGroups, c, a, i ), mIncremental( incremental ) { } void KNode::GroupListJob::execute() { mGroupList.clear(); KNGroupListData::Ptr target = boost::static_pointer_cast( data() ); KUrl destination = baseUrl(); QStringList query; if ( target->getDescriptions ) query << "desc=true"; if ( mIncremental ) query << QString( "since=%1%2%3+000000" ) .arg( target->fetchSince.year() % 100, 2, 10, QChar( '0' ) ) .arg( target->fetchSince.month(), 2, 10, QChar( '0' ) ) .arg( target->fetchSince.day(), 2, 10, QChar( '0' ) ); destination.setQuery( query.join( "&" ) ); KIO::ListJob* job = KIO::listDir( destination, KIO::HideProgressInfo, true ); connect( job, SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)), SLOT(slotEntries(KIO::Job*,KIO::UDSEntryList)) ); connect( job, SIGNAL(result(KJob*)), SLOT(slotResult(KJob*)) ); setupKIOJob( job ); } void KNode::GroupListJob::slotEntries( KIO::Job * job, const KIO::UDSEntryList & list ) { Q_UNUSED( job ); KNGroupListData::Ptr target = boost::static_pointer_cast( data() ); QString name, desc; bool subscribed; KNGroup::Status access; for( KIO::UDSEntryList::ConstIterator it = list.begin(); it != list.end(); ++it ) { access = KNGroup::unknown; name = (*it).stringValue( KIO::UDSEntry::UDS_NAME ); desc = (*it).stringValue( KIO::UDSEntry::UDS_EXTRA ); int value = (*it).numberValue( KIO::UDSEntry::UDS_ACCESS, -1 ); if ( value != -1 ) { if( value & S_IWOTH ) access = KNGroup::postingAllowed; else if ( value & S_IWGRP ) access = KNGroup::moderated; else access = KNGroup::readOnly; } if ( name.isEmpty() ) continue; if ( target->subscribed.contains( name ) ) { target->subscribed.removeAll( name ); // group names are unique, we wont find it again anyway... subscribed = true; } else { subscribed = false; } kDebug() << "Found group " << name; if ( mIncremental ) mGroupList.append(KNGroupInfo( name, desc, true, subscribed, access ) ); else target->groups->append(KNGroupInfo( name, desc, false, subscribed, access ) ); } } void KNode::GroupListJob::slotResult( KJob * job ) { if ( job->error() ) setError( job->error(), job->errorString() ); else { KNGroupListData::Ptr target = boost::static_pointer_cast( data() ); // TODO: use thread weaver here? if ( mIncremental ) { setStatus( i18n("Loading group list from disk...") ); if ( !target->readIn( this ) ) { setError( KIO::ERR_COULD_NOT_READ, i18n("Unable to read the group list file") ); emitFinished(); return; } target->merge( &mGroupList ); } setStatus( i18n("Writing group list to disk...") ); if ( !target->writeOut() ) setError( KIO::ERR_COULD_NOT_WRITE, i18n("Unable to write the group list file") ); } emitFinished(); } KNode::GroupLoadJob::GroupLoadJob( KNJobConsumer *c, KNServerInfo::Ptr a, KNJobItem::Ptr i ) : KNJobData( KNJobData::JTLoadGroups, c, a, i ) { } void KNode::GroupLoadJob::execute( ) { KNGroupListData::Ptr target = boost::static_pointer_cast( data() ); setStatus( i18n("Loading group list from disk...") ); // TODO: use the thread weaver here if ( !target->readIn( this ) ) setError( KIO::ERR_COULD_NOT_READ, i18n("Unable to read the group list file") ); emitFinished(); } KNode::ArticleListJob::ArticleListJob( KNJobConsumer *c, KNServerInfo::Ptr a, KNJobItem::Ptr i, bool silent ) : KNJobData( JTfetchNewHeaders, c, a, i ), mSilent( silent ) { } void KNode::ArticleListJob::execute() { mArticleList.clear(); KNGroup::Ptr target = boost::static_pointer_cast( data() ); KUrl destination = baseUrl(); destination.setPath( target->groupname() ); QStringList query; query << "first=" + QString::number( target->lastNr() + 1 ); if ( target->lastNr() <= 0 ) // first fetch query << "max=" + QString::number( target->maxFetch() ); destination.setQuery( query.join( "&" ) ); KIO::ListJob* job = KIO::listDir( destination, KIO::HideProgressInfo, true ); connect( job, SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)), SLOT(slotEntries(KIO::Job*,KIO::UDSEntryList)) ); connect( job, SIGNAL(result(KJob*)), SLOT(slotResult(KJob*)) ); setupKIOJob( job ); } void KNode::ArticleListJob::slotEntries( KIO::Job * job, const KIO::UDSEntryList & list ) { Q_UNUSED( job ); mArticleList += list; } void KNode::ArticleListJob::slotResult( KJob * _job ) { Q_ASSERT( mJob == _job ); KIO::Job *job = static_cast( _job ); if ( job->error() ) setError( job->error(), job->errorString() ); else { createProgressItem(); KNGroup::Ptr target = boost::static_pointer_cast( data() ); target->setLastFetchCount( 0 ); setStatus( i18n("Sorting...") ); if ( job->metaData().contains( "FirstSerialNumber" ) ) { int firstSerNum = job->metaData()["FirstSerialNumber"].toInt(); target->setFirstNr( firstSerNum ); } target->insortNewHeaders( mArticleList, this ); if ( job->metaData().contains( "LastSerialNumber" ) ) { int lastSerNum = job->metaData()["LastSerialNumber"].toInt(); target->setLastNr( lastSerNum ); } } setComplete(); emitFinished(); } KNode::ArticleFetchJob::ArticleFetchJob( KNJobConsumer *c, KNServerInfo::Ptr a, KNJobItem::Ptr i, bool parse ) : KNJobData( JTfetchArticle, c, a, i ), mParseArticle( parse ) { } void KNode::ArticleFetchJob::execute() { KNRemoteArticle::Ptr target = boost::static_pointer_cast( data() ); KUrl url = baseUrl(); url.addPath( boost::static_pointer_cast( target->collection() )->groupname() ); // By default, fetch articles by their server-side Id. // (some server does not understand the "ARTICLE " command correctly (bug #193550)) if ( target->articleNumber() != -1 ) { url.addPath( QString::number( target->articleNumber() ) ); } else { // User asked to fetch a message by its msg-id url.addPath( target->messageID()->as7BitString( false ) ); } KIO::Job* job = KIO::storedGet( url, KIO::NoReload, KIO::HideProgressInfo ); connect( job, SIGNAL(result(KJob*)), SLOT(slotResult(KJob*)) ); setupKIOJob( job ); } void KNode::ArticleFetchJob::slotResult( KJob * job ) { if ( job->error() ) setError( job->error(), job->errorString() ); else { KNRemoteArticle::Ptr target = boost::static_pointer_cast( data() ); KIO::StoredTransferJob *j = static_cast( job ); QByteArray buffer = j->data(); buffer.replace( "\r\n", "\n" ); // TODO: do this in the io-slave? target->setContent( buffer ); if ( mParseArticle ) target->parse(); } emitFinished(); } KNode::ArticlePostJob::ArticlePostJob( KNJobConsumer *c, KNServerInfo::Ptr a, KNJobItem::Ptr i ) : KNJobData( JTpostArticle, c, a, i ) { } void KNode::ArticlePostJob::execute( ) { KNLocalArticle::Ptr target = boost::static_pointer_cast( data() ); KUrl url = baseUrl(); KIO::Job* job = KIO::storedPut( target->encodedContent( true ), url, -1, KIO::Overwrite | KIO::HideProgressInfo ); connect( job, SIGNAL(result(KJob*)), SLOT(slotResult(KJob*)) ); setupKIOJob( job ); } void KNode::ArticlePostJob::slotResult( KJob * job ) { if ( job->error() ) { QString hostname = job->errorText(); switch ( job->error() ) { case KIO::ERR_WRITE_ACCESS_DENIED: setError( job->error(), i18n( "The server %1 does not allow you to post articles to it.", hostname ) ); break; case KIO::ERR_COULD_NOT_WRITE: setError( job->error(), i18n( "The posting of this article to the server %1 failed.\n" "Please check that you are not trying to post to a read-only group.", hostname ) ); break; default: setError( job->error(), job->errorString() ); } } emitFinished(); }