/** * SUPPORTCommand.cc * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. * * $Id: SUPPORTCommand.cc,v 1.9 2007/08/28 16:10:11 dan_karrels Exp $ */ #include #include #include #include "StringTokenizer.h" #include "ELog.h" #include "cservice.h" const char SUPPORTCommand_cc_rcsId[] = "$Id: SUPPORTCommand.cc,v 1.9 2007/08/28 16:10:11 dan_karrels Exp $" ; namespace gnuworld { using std::string ; using std::endl ; using std::ends ; using std::stringstream ; bool SUPPORTCommand::Exec( iClient* theClient, const string& Message ) { bot->incStat("COMMANDS.SUPPORT"); StringTokenizer st( Message ) ; if( st.size() < 3 ) { Usage(theClient); return true; } sqlUser* theUser = bot->isAuthed(theClient, true); if (!theUser) { return false; } string support = st[2]; /* * First, check they can type the command correctly. */ char supportChar = '?'; if (string_lower(support) == "no") { supportChar = 'N'; } else if (string_lower(support) == "yes") { supportChar = 'Y'; } else { bot->Notice(theClient, "Valid SUPPORT choices are YES and NO."); return false; } /* * Next, check to see if this channel is actually pending. */ string channelName = st[1]; stringstream theQuery; theQuery << "SELECT channels.id FROM pending,channels" << " WHERE lower(channels.name) = '" << escapeSQLChars(string_lower(channelName)) << "'" << " AND channels.id = pending.channel_id" << " AND pending.status = 0" << ends; #ifdef LOG_SQL elog << "SUPPORTCommand::sqlQuery> " << theQuery.str().c_str() << endl; #endif if( !bot->SQLDb->Exec( theQuery, true ) ) //if( PGRES_TUPLES_OK != status ) { elog << "SUPPORTCommand> SQL Error: " << bot->SQLDb->ErrorMessage() << endl ; return false ; } if (bot->SQLDb->Tuples() <= 0) { bot->Notice(theClient, "The channel %s doesn't appear to have a pending application. Please ensure you have spelt the name correctly.", channelName.c_str()); return false; } /* * So it is, lets check they haven't already voiced their support about this channel. */ unsigned int channel_id = atoi(bot->SQLDb->GetValue(0, 0)); stringstream supQuery; supQuery << "SELECT support FROM supporters" << " WHERE channel_id = " << channel_id << " AND user_id = " << theUser->getID() << ends; #ifdef LOG_SQL elog << "SUPPORTCommand::sqlQuery> " << supQuery.str().c_str() << endl; #endif if( !bot->SQLDb->Exec( supQuery, true ) ) //if( PGRES_TUPLES_OK != status ) { elog << "SUPPORTCommand> SQL Error: " << bot->SQLDb->ErrorMessage() << endl ; return false ; } if (bot->SQLDb->Tuples() <= 0) { bot->Notice(theClient, "You don't appear to be listed as a supporter in %s, please ensure you have spelt the channel name correctly.", channelName.c_str()); return false; } string currentSupport = bot->SQLDb->GetValue(0, 0); if ((currentSupport == "Y") || (currentSupport == "N")) { bot->Notice(theClient, "You have already made your decision on supporting %s, you cannot change it.", channelName.c_str()); return false; } /* * Save the changes. */ stringstream updateQuery; updateQuery << "UPDATE supporters SET support = '" << supportChar << "'" << ", last_updated = date_part('epoch', CURRENT_TIMESTAMP)::int" << " WHERE channel_id = " << channel_id << " AND user_id = " << theUser->getID() << ends; #ifdef LOG_SQL elog << "SUPPORTCommand::sqlQuery> " << updateQuery.str().c_str() << endl; #endif if( !bot->SQLDb->Exec( updateQuery ) ) //if( PGRES_COMMAND_OK != status ) { elog << "SUPPORTCommand> SQL Error: " << bot->SQLDb->ErrorMessage() << endl ; bot->Notice(theClient, "An Error occured whilst processing your support. Please contact a CService Administrator."); return false ; } bot->Notice(theClient, "Done. Set your support for %s to %s.", channelName.c_str(), support.c_str()); bot->logDebugMessage("%s has set their support for %s to %c.", theUser->getUserName().c_str(), channelName.c_str(), supportChar); /* * Right, now if they've voted "YES", and there are 10 supporters who have said YES * we move this to traffic check stage. */ if (supportChar == 'Y') { /* * Check to see if all people have said 'Yes'. */ stringstream tenQuery; tenQuery << "SELECT support FROM supporters" << " WHERE channel_id = " << channel_id << ends; #ifdef LOG_SQL elog << "SUPPORTCommand::sqlQuery> " << tenQuery.str().c_str() << endl; #endif if( !bot->SQLDb->Exec( tenQuery, true ) ) // if( PGRES_TUPLES_OK != status ) { elog << "SUPPORTCommand> SQL Error: " << bot->SQLDb->ErrorMessage() << endl ; return false ; } bool allSupporting = true; /* * Iterate over the results, if just one of the * supporter records isn't a Y, then its not * yet passed. */ string support; int supporterCount = bot->SQLDb->Tuples(); if (supporterCount < bot->RequiredSupporters) return false; for (int i = 0 ; i < supporterCount; i++) { support = bot->SQLDb->GetValue(i,0); if (support != "Y") allSupporting = false; } if (allSupporting) { stringstream updatePendingQuery; updatePendingQuery << "UPDATE pending SET status = '1'," << " last_updated = date_part('epoch', CURRENT_TIMESTAMP)::int," << " check_start_ts = date_part('epoch', CURRENT_TIMESTAMP)::int" << " WHERE channel_id = " << channel_id << " AND status = '0'" << ends; #ifdef LOG_SQL elog << "SUPPORTCommand::sqlQuery> " << updatePendingQuery.str().c_str() << endl; #endif bot->SQLDb->Exec( updatePendingQuery.str().c_str() ) ; bot->logDebugMessage("%s has just made it to traffic check phase with %i supporters.", channelName.c_str(), supporterCount); } return true; } /* * Now, if they don't support it - deny this application, and do all sorts * of other stuff. */ if (supportChar == 'N') { /* * Reject the application. */ stringstream updatePendingQuery; updatePendingQuery << "UPDATE pending SET status = '9'," << " last_updated = date_part('epoch', CURRENT_TIMESTAMP)::int," << " decision_ts = date_part('epoch', CURRENT_TIMESTAMP)::int," << " decision = '--AUTOMATIC (REGPROC)-- NON-SUPPORT'" << " WHERE channel_id = " << channel_id << " AND status = '0'" << ends; #ifdef LOG_SQL elog << "SUPPORTCommand::sqlQuery> " << updatePendingQuery.str().c_str() << endl; #endif bot->SQLDb->Exec( updatePendingQuery.str().c_str() ) ; bot->logDebugMessage("%s has just been declined due to non-support.", channelName.c_str()); /* * Now, add some non-support entries. * First, get the username and email address of the channel manager. */ stringstream mgrQuery; mgrQuery << "SELECT user_name,email FROM users,pending" << " WHERE pending.manager_id = users.id " << " AND pending.channel_id = " << channel_id << " AND pending.status = '9'" << ends; #ifdef LOG_SQL elog << "SUPPORTCommand::sqlQuery> " << mgrQuery.str().c_str() << endl; #endif if( !bot->SQLDb->Exec( mgrQuery, true ) ) // if( PGRES_TUPLES_OK != status ) { elog << "SUPPORTCommand> SQL Error: " << bot->SQLDb->ErrorMessage() << endl ; return false ; } // TODO: Comparing unsigned against 0 if(bot->SQLDb->Tuples() > 0) { string managerName = bot->SQLDb->GetValue(0,0); string managerEmail = bot->SQLDb->GetValue(0,1); int noregTime = bot->JudgeDaySeconds * bot->NoRegDaysOnNOSupport; static const char* cmdHeader = "INSERT INTO noreg (user_name,email,channel_name,type,expire_time,created_ts,set_by,reason) VALUES "; stringstream noregQuery; noregQuery << cmdHeader << "('', '','" << escapeSQLChars(channelName) << "'," // << "1, (date_part('epoch', CURRENT_TIMESTAMP)::int + (86400*3)), date_part('epoch', CURRENT_TIMESTAMP)::int, '* REGPROC', '-NON SUPPORT-'" << "1, (date_part('epoch', CURRENT_TIMESTAMP)::int + (" << noregTime << ")), date_part('epoch', CURRENT_TIMESTAMP)::int, '* REGPROC', '-NON SUPPORT-'" << ")" << ends; #ifdef LOG_SQL elog << "SUPPORTCommand::sqlQuery> " << noregQuery.str().c_str() << endl; #endif bot->SQLDb->Exec( noregQuery.str().c_str() ) ; /* * Add a user-based noreg entry too. */ stringstream usernoregQuery; usernoregQuery << cmdHeader << "('" << escapeSQLChars(managerName) << "', '" << escapeSQLChars(managerEmail) << "', " << "'', " //<< "1, (date_part('epoch', CURRENT_TIMESTAMP)::int + (86400*3)), date_part('epoch', CURRENT_TIMESTAMP)::int, '* REGPROC', '-NON SUPPORT-'" << "1, (date_part('epoch', CURRENT_TIMESTAMP)::int + (" << noregTime << ")), date_part('epoch', CURRENT_TIMESTAMP)::int, '* REGPROC', '-NON SUPPORT-'" << ")" << ends; #ifdef LOG_SQL elog << "SUPPORTCommand::sqlQuery> " << usernoregQuery.str().c_str() << endl; #endif bot->SQLDb->Exec( usernoregQuery.str().c_str() ) ; /* * Sigh, and a channel-log entry! */ stringstream clogQuery; clogQuery << "INSERT INTO channellog (ts, channelid, event, message, last_updated) VALUES (" << "date_part('epoch', CURRENT_TIMESTAMP)::int, " << channel_id << ", " << "1, 'Non-support by " << escapeSQLChars(theUser->getUserName()) << "', " << "date_part('epoch', CURRENT_TIMESTAMP)::int)" << ends; #ifdef LOG_SQL elog << "SUPPORTCommand::sqlQuery> " << clogQuery.str().c_str() << endl; #endif bot->SQLDb->Exec( clogQuery.str().c_str() ) ; } } return true ; } } // namespace gnuworld.