survey.cpp

Go to the documentation of this file.
00001 /*
00002 #########################################################################
00003 #
00004 #  This file is part of trustyRC.
00005 #
00006 #  trustyRC, fully modular IRC robot 
00007 #  Copyright (C) 2006-2008 Nicoleau Fabien 
00008 #
00009 #  trustyRC is free software: you can redistribute it and/or modify
00010 #  it under the terms of the GNU General Public License as published by
00011 #  the Free Software Foundation, either version 3 of the License, or
00012 #  (at your option) any later version.
00013 #
00014 #  trustyRC is distributed in the hope that it will be useful,
00015 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 #  GNU General Public License for more details.
00018 #
00019 #  You should have received a copy of the GNU General Public License
00020 #  along with trustyRC.  If not, see <http://www.gnu.org/licenses/>.
00021 #
00022 #########################################################################
00023 */
00024 
00029 #include "survey.h"
00030 
00034 Survey::Survey(BotKernel*b)
00035 {
00036         this->author = "eponyme";
00037         this->description = "survey plugin";
00038         this->version = VERSION;
00039         this->name = "survey";
00040    this->surveys.clear();
00041    this->bindFunction("survey",IN_COMMAND_HANDLER,"launchSurvey",0,10);
00042    this->bindFunction("cancelsurvey",IN_COMMAND_HANDLER,"stopSurvey",0,10);
00043    this->addRequirement("admin");
00044 }
00045 
00054 bool Survey::launchSurvey(string channel,string question,unsigned int time,vector<string> answers)
00055 {
00056    if (!this->surveyRunning(channel)) {
00057       struct_survey newSurvey;
00058       newSurvey.channel = channel;
00059       newSurvey.question = question;
00060       newSurvey.time = time ;
00061       newSurvey.answers = answers;
00062       newSurvey.results.clear();
00063       newSurvey.functions.clear();
00064       newSurvey.countDown = NULL;
00065       for ( unsigned int i = 0 ; i < newSurvey.answers.size() ; i ++ ) {
00066          newSurvey.results.push_back(0) ;
00067       }
00068       newSurvey.voters.clear();
00069       this->surveys.push_back(newSurvey);
00070       return true;
00071    }
00072    return false;
00073 }
00074 
00080 vector<string> Survey::finishSurvey(string channel)
00081 {
00082    vector<string> back;
00083    vector<struct_survey>::iterator it = this->surveys.begin();
00084    while ( it != this->surveys.end() ) {
00085       if ( (*it).channel == channel ) { 
00086          for ( unsigned int i = 0 ; i < (*it).answers.size() ; i ++ ) {
00087             back.push_back("* "+(*it).answers[i]+" : "+Tools::intToStr((*it).results[i]));
00088          }
00089          this->surveys.erase(it); 
00090          return back; 
00091       }
00092       it++;
00093    }
00094    return back;
00095 }
00096 
00104 bool Survey::vote(string channel,string nick,string answer)
00105 {
00106    int id=-1;
00107    for ( unsigned int i = 0 ; i < this->surveys.size() ; i ++ ) {
00108       if ( this->surveys[i].channel == channel ) {
00109          if (!Tools::isInVector(surveys[i].voters,nick)) {
00110             id = this->getAnswerId(this->surveys[i].answers,answer);
00111             if ( id>=0 ) {
00112                this->surveys[i].results[id] ++ ;
00113                this->surveys[i].voters.push_back(nick) ;
00114                return true;
00115             }
00116             return false;
00117          }
00118          return false;
00119       }
00120    }
00121    return false;
00122 }
00123 
00129 bool Survey::stopSurvey(string channel)
00130 {
00131    vector<struct_survey>::iterator it = this->surveys.begin();
00132    while ( it != this->surveys.end() ) {
00133       if ( (*it).channel == channel ) { 
00134          this->surveys.erase(it); 
00135          return true; 
00136       }
00137       it++;
00138    }
00139    return false;
00140 }
00141 
00147 bool Survey::surveyRunning(string channel) {
00148    for ( unsigned int i = 0 ; i < this->surveys.size() ; i ++ ) {
00149       if ( this->surveys[i].channel == channel ) {
00150          return true;
00151       }
00152    }
00153    return false;
00154 }
00155 
00161 vector<plugin_function> Survey::getSurveyFunctions(string channel) {
00162    vector<plugin_function>  back;
00163    for ( unsigned int i = 0 ; i < this->surveys.size() ; i ++ ) {
00164       if ( this->surveys[i].channel == channel ) {
00165          return this->surveys[i].functions ;
00166       }
00167    }
00168    return back;
00169 }
00170 
00177 bool Survey::setSurveyFunctions(string channel,vector<plugin_function> functions)
00178 {
00179    for ( unsigned int i = 0 ; i < this->surveys.size() ; i ++ ) {
00180       if ( this->surveys[i].channel == channel ) {
00181          this->surveys[i].functions = functions;
00182          return true;
00183       }
00184    }
00185    return false;
00186 }
00187 
00193 plugin_function Survey::getCountDown(string channel) 
00194 {
00195    for ( unsigned int i = 0 ; i < this->surveys.size() ; i ++ ) {
00196       if ( this->surveys[i].channel == channel ) {
00197          return this->surveys[i].countDown ;
00198       }
00199    }
00200    return NULL;
00201 }
00202 
00209 bool Survey::setCountDown(string channel,plugin_function function)
00210 {
00211    for ( unsigned int i = 0 ; i < this->surveys.size() ; i ++ ) {
00212       if ( this->surveys[i].channel == channel ) {
00213          this->surveys[i].countDown = function;
00214          return true;
00215       }
00216    }
00217    return false;
00218 }
00219 
00226 int Survey::getAnswerId(vector<string>answers,string answer)
00227 {
00228    for (unsigned int i = 0 ; i < answers.size() ; i ++ ) {
00229       if (answers[i] == answer ) {
00230          return i;
00231       }
00232    }
00233    return -1;
00234 }
00235 
00236 extern "C"
00237 {
00238         Plugin *contruct_survey(BotKernel*b)
00239         {
00240                 return new Survey(b);
00241         }
00242         void destroy_survey(Plugin*p)
00243         {
00244                 delete p;
00245         }
00246    bool stopSurvey (Message*m,Plugin*p,BotKernel*b)
00247    {
00248       pPlugin * ppAdm = b->getPlugin("admin");
00249       Admin*adm = NULL;
00250       Survey * sv = (Survey*) p;
00251       if ((ppAdm!=NULL) && m->isPublic()) {
00252          adm = (Admin*)ppAdm->object ;
00253          if (adm->isSuperAdmin(m->getSender()) ) {
00254             vector<plugin_function> functions = sv->getSurveyFunctions(m->getSource());
00255             for(unsigned int i = 0 ; i < functions.size() ; i ++ ) {
00256                b->unregisterFunction(functions[i]);
00257             }
00258             b->unregisterFunction(sv->getCountDown(m->getSource()));
00259             if ( sv->stopSurvey(m->getSource()) ) {
00260                b->send(IRCProtocol::sendMsg(m->getSource(),"* Survey canceled "));
00261             }
00262             else {
00263                b->send(IRCProtocol::sendNotice(m->getNickSender(),"* No survey to cancel *"));
00264             }
00265          }
00266       }
00267       return true;
00268    }
00269         bool endSurvey (Message*m,Plugin*p,BotKernel*b)
00270    {
00271       Survey * sv = (Survey*) p;
00272       vector<plugin_function> functions = sv->getSurveyFunctions(m->getSource());
00273       for(unsigned int i = 0 ; i < functions.size() ; i ++ ) {
00274          b->unregisterFunction(functions[i]);
00275       }
00276       b->send(IRCProtocol::sendMsg(m->getSource(),"* Survey finished !, results :"));
00277       b->send(IRCProtocol::sendMsg(m->getSource(),sv->finishSurvey(m->getSource())));
00278       return true;
00279    }
00280         bool vote (Message*m,Plugin*p,BotKernel*b)
00281         {
00282       Survey * sv = (Survey*) p;
00283       if ( m->isPublic() ) {
00284          if (!sv->vote(m->getSource(),m->getNickSender(),m->getPart(3).substr(b->getCONFF()->getValue("kernel.command_prefix").length()+1))) {
00285             b->send(IRCProtocol::sendNotice(m->getNickSender(),"ERROR, already voted ?, wrong channel ?")) ;
00286          }
00287       }
00288                 return true;
00289         }
00290         bool launchSurvey (Message*m,Plugin*p,BotKernel*b)
00291         {
00292       Survey * sv = (Survey*) p;
00293                 ConfigurationFile * cf = b->getCONFF();
00294       vector<plugin_function> functions;
00295       vector<string> answers,tmpanswers;
00296       unsigned int duration;
00297       string prefix = b->getCONFF()->getValue("kernel.command_prefix") ;
00298       if(m->isPublic()) {
00299          vector<string> elems = Tools::stringToVector(m->getMessage(),">",0);
00300          if ( elems.size() == 4 ) {
00301             answers.clear();
00302             tmpanswers = Tools::stringToVector(elems[2]," ",0);
00303             for (unsigned int i = 0 ; i < tmpanswers.size();i++ ) {
00304                if ( (!Tools::isInVector(answers,tmpanswers[i])) && (tmpanswers[i]!="")) {
00305                   answers.push_back(tmpanswers[i]);
00306                }
00307             }
00308             duration = Tools::strtimeToSeconds(elems[3]) ;
00309             if((cf->getValue(p->getName()+".maxduration")=="")||(cf->getValue(p->getName()+".maxduration")=="0")||(Tools::strToUnsignedInt(cf->getValue(p->getName()+".maxduration"))>=duration)) {
00310                if((cf->getValue(p->getName()+".maxanswers")=="")||(cf->getValue(p->getName()+".maxanswers")=="0")||(Tools::strToUnsignedInt(cf->getValue(p->getName()+".maxanswers"))>=answers.size())) {
00311                   if ( sv->launchSurvey(m->getSource(),elems[1],Tools::strtimeToSeconds(elems[3]),answers) ) {
00312                      for (unsigned int i = 0 ; i < answers.size(); i ++ ) {
00313                         functions.push_back(b->registerFunction(answers[i],p,IN_COMMAND_HANDLER,"surveyAnswer",vote,0,10));
00314                      }
00315                      plugin_function func = b->addCountDown(p,endSurvey,m,duration,10);
00316                      if ( func == NULL ) {
00317                         sv->stopSurvey(m->getSource());
00318                         b->send(IRCProtocol::sendMsg(m->getSource(),"Error, too many count downs are running"));
00319                      }
00320                      else {
00321                         b->send(IRCProtocol::sendMsg(m->getSource(),"* Survey launched ("+Tools::intToStr(duration)+" seconds) : "+elems[1]));
00322                         b->send(IRCProtocol::sendMsg(m->getSource(),"* Possible answers are : "+prefix+Tools::vectorToString(answers," "+prefix,0)));
00323                         sv->setSurveyFunctions(m->getSource(),functions);
00324                         sv->setCountDown(m->getSource(),func);  
00325                      }
00326                   }
00327                   else {
00328                      b->send(IRCProtocol::sendNotice(m->getNickSender(),"Error while launching survey. One already launched ?")) ;
00329                   }
00330                }
00331                else {
00332                   b->send(IRCProtocol::sendNotice(m->getNickSender(),"Error : a survey can't have more thant "+cf->getValue(p->getName()+".maxanswers")+" answers.")) ;      
00333                }
00334             }
00335             else {
00336                b->send(IRCProtocol::sendNotice(m->getNickSender(),"Error : duration can't exceed "+cf->getValue(p->getName()+".maxduration")+" seconds.")) ;
00337             }
00338          }
00339       }
00340                 return true;
00341         }
00342 }

Generated on Sun Aug 16 15:28:29 2009 for trustyRC by  doxygen 1.5.8