/* This file is part of KBugBuster. Copyright (c) 2002,2003 Cornelius Schumacher 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 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, USA. As a special exception, permission is given to link this program with any edition of TQt, and distribute the resulting executable, without including the source code for TQt in the source distribution. */ #include "bugserver.h" #include "kbbprefs.h" #include "rdfprocessor.h" #include "bugcache.h" #include "bugcommand.h" #include "mailsender.h" #include "bugserverconfig.h" #include "htmlparser.h" #include #include #include BugServer::BugServer() { init(); } BugServer::BugServer( const BugServerConfig &cfg ) : mServerConfig( cfg ) { init(); } void BugServer::init() { mCache = new BugCache( identifier() ); TQString commandsFile = locateLocal( "appdata", identifier() + "commands" ); mCommandsFile = new KSimpleConfig( commandsFile ); TQString bugzilla = mServerConfig.bugzillaVersion(); if ( bugzilla == "TDE" ) mProcessor = new DomProcessor( this ); else if ( bugzilla == "KDE" ) mProcessor = new DomProcessor( this ); else if ( bugzilla == "2.10" ) mProcessor = new HtmlParser_2_10( this ); else if ( bugzilla == "2.14.2" ) mProcessor = new HtmlParser_2_14_2( this ); else if ( bugzilla == "2.17.1" ) mProcessor = new HtmlParser_2_17_1( this ); else mProcessor = new HtmlParser( this ); loadCommands(); } BugServer::~BugServer() { saveCommands(); delete mProcessor; delete mCommandsFile; delete mCache; } void BugServer::setServerConfig( const BugServerConfig &cfg ) { mServerConfig = cfg; } BugServerConfig &BugServer::serverConfig() { return mServerConfig; } TQString BugServer::identifier() { TQString id = mServerConfig.baseUrl().host(); return id; } Processor *BugServer::processor() const { return mProcessor; } KURL BugServer::packageListUrl() { KURL url = mServerConfig.baseUrl(); mProcessor->setPackageListQuery( url ); return url; } KURL BugServer::bugListUrl( const Package &product, const TQString &component ) { KURL url = mServerConfig.baseUrl(); mProcessor->setBugListQuery( url, product, component ); return url; } KURL BugServer::bugDetailsUrl( const Bug &bug ) { KURL url = mServerConfig.baseUrl(); mProcessor->setBugDetailsQuery( url, bug ); return url; } KURL BugServer::bugLink( const Bug &bug ) { KURL url = mServerConfig.baseUrl(); url.setFileName( "show_bug.cgi" ); url.setQuery( "id=" + bug.number() ); kdDebug() << "URL: " << url.url() << endl; return url; } KURL BugServer::attachmentViewLink( const TQString &id ) { KURL url = mServerConfig.baseUrl(); url.setFileName( "attachment.cgi" ); url.setQuery( "id=" + id + "&action=view" ); return url; } KURL BugServer::attachmentEditLink( const TQString &id ) { KURL url = mServerConfig.baseUrl(); url.setFileName( "attachment.cgi" ); url.setQuery( "id=" + id + "&action=edit" ); return url; } Bug::Status BugServer::bugStatus( const TQString &str ) { if ( str == "UNCONFIRMED" ) { return Bug::Unconfirmed; } else if ( str == "NEW" ) { return Bug::New; } else if ( str == "ASSIGNED" ) { return Bug::Assigned; } else if ( str == "REOPENED" ) { return Bug::Reopened; } else if ( str == "RESOLVED" ) { return Bug::Closed; } else if ( str == "VERIFIED" ) { return Bug::Closed; } else if ( str == "CLOSED" ) { return Bug::Closed; } else { return Bug::StatusUndefined; } } Bug::Severity BugServer::bugSeverity( const TQString &str ) { if ( str == "critical" ) { return Bug::Critical; } else if ( str == "grave" ) { return Bug::Grave; } else if ( str == "major" ) { return Bug::Major; } else if ( str == "crash" ) { return Bug::Crash; } else if ( str == "normal" ) { return Bug::Normal; } else if ( str == "minor" ) { return Bug::Minor; } else if ( str == "wishlist" ) { return Bug::Wishlist; } else { return Bug::SeverityUndefined; } } void BugServer::readConfig( TDEConfig * /*config*/ ) { } void BugServer::writeConfig( TDEConfig * /*config*/ ) { } bool BugServer::queueCommand( BugCommand *cmd ) { // mCommands[bug] is a TQPtrList. Get or create, set to autodelete, then append command. mCommands[cmd->bug().number()].setAutoDelete( true ); TQPtrListIterator cmdIt( mCommands[cmd->bug().number()] ); for ( ; cmdIt.current(); ++cmdIt ) if ( cmdIt.current()->type() == cmd->type() ) return false; mCommands[cmd->bug().number()].append( cmd ); return true; } TQPtrList BugServer::queryCommands( const Bug &bug ) const { CommandsMap::ConstIterator it = mCommands.find( bug.number() ); if (it == mCommands.end()) return TQPtrList(); else return *it; } bool BugServer::hasCommandsFor( const Bug &bug ) const { CommandsMap::ConstIterator it = mCommands.find( bug.number() ); return it != mCommands.end(); } void BugServer::sendCommands( MailSender *mailer, const TQString &senderName, const TQString &senderEmail, bool sendBCC, const TQString &recipient ) { // Disable mail commands for non-TDE servers if ( mServerConfig.baseUrl() != KURL( "http://bugs.trinitydesktop.org" ) ) return; TQString controlText; // For each bug that has commands..... CommandsMap::ConstIterator it; for(it = mCommands.begin(); it != mCommands.end(); ++it ) { Bug bug; Package pkg; // And for each command.... TQPtrListIterator cmdIt( *it ); for ( ; cmdIt.current() ; ++cmdIt ) { BugCommand* cmd = cmdIt.current(); bug = cmd->bug(); if (!cmd->package().isNull()) pkg = cmd->package(); if (!cmd->controlString().isNull()) { kdDebug() << "control@bugs.trinitydesktop.org: " << cmd->controlString() << endl; controlText += cmd->controlString() + "\n"; } else { kdDebug() << cmd->mailAddress() << ": " << cmd->mailText() << endl; // ### hm, should probably re-use the existing mailer instance and // implement message queueing for smtp MailSender *directMailer = mailer->clone(); #if 0 connect( directMailer, TQT_SIGNAL( status( const TQString & ) ), this, TQT_SIGNAL( infoMessage( const TQString & ) ) ); #endif if (!directMailer->send( senderName, senderEmail, cmd->mailAddress(), cmd->bug().title().prepend( "Re: " ), cmd->mailText(), sendBCC, recipient )) { delete mailer; return; } } } if (!bug.isNull()) { mCommandsFile->deleteGroup( bug.number(), true ); // done, remove command mCache->invalidateBugDetails( bug ); if ( !pkg.isNull() ) { mCache->invalidateBugList( pkg, TQString() ); // the status of the bug comes from the buglist... TQStringList::ConstIterator it2; for (it2 = pkg.components().begin();it2 != pkg.components().end();++it2) { mCache->invalidateBugList( pkg, (*it2) ); // the status of the bug comes from the buglist... } } } } if (!controlText.isEmpty()) { kdDebug() << "control@bugs.trinitydesktop.org doesn't work anymore" << endl; #if 0 if ( !mailer->send( senderName, senderEmail, "control@bugs.trinitydesktop.org", i18n("Mail generated by KBugBuster"), controlText, sendBCC, recipient )) return; #endif } else { delete mailer; } mCommands.clear(); } void BugServer::clearCommands( const TQString &bug ) { mCommands.remove( bug ); mCommandsFile->deleteGroup( bug, true ); } bool BugServer::commandsPending() const { if ( mCommands.count() > 0 ) return true; else return false; } TQStringList BugServer::listCommands() const { TQStringList result; CommandsMap::ConstIterator it; for(it = mCommands.begin(); it != mCommands.end(); ++it ) { TQPtrListIterator cmdIt( *it ); for ( ; cmdIt.current() ; ++cmdIt ) { BugCommand* cmd = cmdIt.current(); if (!cmd->controlString().isNull()) result.append( i18n("Control command: %1").arg(cmd->controlString()) ); else result.append( i18n("Mail to %1").arg(cmd->mailAddress()) ); } } return result; } TQStringList BugServer::bugsWithCommands() const { TQStringList bugs; CommandsMap::ConstIterator it; for(it = mCommands.begin(); it != mCommands.end(); ++it ) { bugs.append( it.key() ); } return bugs; } void BugServer::saveCommands() const { CommandsMap::ConstIterator it; for(it = mCommands.begin(); it != mCommands.end(); ++it ) { mCommandsFile->setGroup( it.key() ); TQPtrListIterator cmdIt( *it ); for ( ; cmdIt.current() ; ++cmdIt ) { BugCommand* cmd = cmdIt.current(); cmd->save( mCommandsFile ); } } mCommandsFile->sync(); } void BugServer::loadCommands() { mCommands.clear(); TQStringList bugs = mCommandsFile->groupList(); TQStringList::ConstIterator it; for( it = bugs.begin(); it != bugs.end(); ++it ) { mCommandsFile->setGroup( *it ); TQMap entries = mCommandsFile->entryMap ( *it ); TQMap::ConstIterator it; for( it = entries.begin(); it != entries.end(); ++it ) { TQString type = it.key(); BugCommand *cmd = BugCommand::load( mCommandsFile, type ); if ( cmd ) { mCommands[cmd->bug().number()].setAutoDelete(true); mCommands[cmd->bug().number()].append(cmd); } } } } void BugServer::setPackages( const Package::List &packages ) { mPackages = packages; } const Package::List &BugServer::packages() const { return mPackages; } void BugServer::setBugs( const Package &pkg, const TQString &component, const Bug::List &bugs ) { TQPair pkg_key = TQPair(pkg, component); mBugs[ pkg_key ] = bugs; } const Bug::List &BugServer::bugs( const Package &pkg, const TQString &component ) { TQPair pkg_key = TQPair(pkg, component); return mBugs[ pkg_key ]; } void BugServer::setBugDetails( const Bug &bug, const BugDetails &details ) { mBugDetails[ bug ] = details; } const BugDetails &BugServer::bugDetails( const Bug &bug ) { return mBugDetails[ bug ]; }