/* * GnuDialer - Complete, free predictive dialer * * Complete, free predictive dialer for contact centers. * * Copyright (C) 2005, GnuDialer Project * * Heath Schultz * Richard Lyman * * This program is free software, distributed under the terms of * the GNU General Public License. */ #include #include #include #include #include #include #include #include "agent.h" #include "call.h" #include "abnhelper.h" #ifndef QUEUE #define QUEUE class Setting { public: Setting(const std::string & rawSetting) { // std::cout << "Setting Constructor called!" << std::endl; // format: ;:setting:asdf:jklsemicolon:qwerty std::string tempSetting = rawSetting.substr(10,rawSetting.length()-10); std::stringstream SettingStream; SettingStream << tempSetting; for (std::string tempLine; std::getline(SettingStream,tempLine,':'); ) { itsWords.push_back(tempLine); } } void Set(const std::string & rawSetting) { std::vector tempWords; // format: ;:setting:asdf:jklsemicolon:qwerty std::string tempSetting = rawSetting.substr(10,rawSetting.length()-10); std::stringstream SettingStream; SettingStream << tempSetting; for (std::string tempLine; std::getline(SettingStream,tempLine,':'); ) { tempWords.push_back(tempLine); } itsWords = tempWords; } int WordCount()const { return itsWords.size() - 1; } const std::string & GetType()const { return itsWords.at(0); } const std::string & GetWord(int whichWord)const { return itsWords.at(whichWord + 1); } // took out const and and string //std::string & GetAttribute(std::string & attribute) { std::string GetAttribute(const std::string & attribute) { notFound = "Not Found"; for (int i = 0; i < itsWords.size(); i++) { if (itsWords.at(i) == attribute) { return itsWords.at(i+1); } } return notFound; } const bool AttributeExists(const std::string & attribute) { for (std::vector::iterator it = itsWords.begin(); it != itsWords.end(); it++) { if ((*it) == attribute) { return true; } } return false; } const bool AttributeExists(const std::string & field, const std::string & value) { for (int i = 0; i < itsWords.size() - 1; i++) { if (itsWords.at(i) == field && itsWords.at(i+1) == value) { return true; } } return false; } int SetAttribute(const std::string & field, const std::string & value) { int counter = 0, indexOfValue = 0; while (counter < itsWords.size()) { if (itsWords.at(counter) == field) { indexOfValue = counter + 1; } counter++; } if (indexOfValue) { if (indexOfValue < itsWords.size()) { itsWords.at(indexOfValue) = value; return 1; } else { return -1; } } else { return 0; } } int AddAttribute(const std::string & field, const std::string & value) { if (field.empty() == false && value.empty() == false) { itsWords.push_back(field); itsWords.push_back(value); return 1; } else { return -1; } } int SupAttribute(const std::string & field, const std::string & value) { int res = SetAttribute(field,value); if (res == -1) { return -1; } else { if (res == 0) { if (AddAttribute(field,value) == 1) { return 2; } else { return -1; } } else { return 1; } } } void DelAttribute(const std::string & field) { std::vector tempWords; for (int i = 0; i < itsWords.size(); i++) { if (itsWords.at(i) != field) { tempWords.push_back(itsWords.at(i)); } else { i++; } } itsWords = tempWords; } std::string GetAttr() { return std::string("hello"); } //const std::string & GetWord(const std::string & type, int whichWord) { std::string GetWord(const std::string & type, int whichWord) { notFound = "Not Found"; for (int i = 0; i < itsWords.size(); i++) { if (itsWords.at(i) == type) { return GetWord(whichWord); } } return notFound; } const std::string & Get()const { return itsWords.at(1); } const int GetInt()const { return atoi(itsWords.at(1).c_str()); } double GetFloat()const { return atof(itsWords.at(1).c_str()); } bool GetBool()const { if (itsWords.at(1) == "true") return true; else if (itsWords.at(1) == "false") return false; else if (itsWords.at(1) == "0") return true; else return false; } ~Setting() {} private: std::vector itsWords; std::string notFound; }; const Setting ReturnSetting(const std::string & rawSetting) { Setting TheSetting(rawSetting); return TheSetting; } class Queue { public: Queue() { changed = false; } ~Queue() {} //bool ParseQueue(std::string name, AgentList TheAgents) { bool ParseQueue(const std::string & name) { itsName = name; int pos = 0, tempMemberNumber = 0; itsAbnHelper.Read(name); std::ifstream QueueIn; QueueIn.open("/etc/asterisk/queues.conf"); // if (!QueueIn) { // throw xFileOpenError("queues.conf"); // } for (std::string tempLine; std::getline(QueueIn,tempLine,'\n');) { if (tempLine.length() > 1) { if (tempLine.find("[" + name + "]",0) != std::string::npos) { if (tempLine[0] == '[') { while (std::getline(QueueIn,tempLine,'\n')) { if (tempLine.length() > 1) if (tempLine[0] == '[') break; else { if (tempLine.find(";:setting:",0) != std::string::npos) itsSettings.push_back(ReturnSetting(tempLine)); else { if (tempLine.find("Agent/",0) != std::string::npos) { pos = tempLine.find("Agent/",0) + 6; tempLine = tempLine.substr(pos,tempLine.length()-pos); tempMemberNumber = atoi(tempLine.c_str()); itsMembersNumbers.push_back(tempMemberNumber); } else { otherSettings.push_back(tempLine); } } } } } } } } QueueIn.close(); time_t raw; tm * ptm; time(&raw); ptm = localtime(&raw); // return ptm->tm_wday; std::string timestamp = itos(ptm->tm_year) + "-" + itos(ptm->tm_mon) + "-" + itos(ptm->tm_mday); // std::cout << "Got here" << std::endl; //// if (GetSetting("resetabandons").Get() != timestamp) { // std::cout << "Got here" << std::endl; //// SetSetting("resetabandons",timestamp); //// SetSetting("abandons","0"); //// SetSetting("calls","0"); //// } // std::cout << "Got here" << std::endl; // std::cout << "Just got done reading and we have " << itsMembersNumbers.size() << " agents." << std::endl; // Write(); } void WriteAbn() { itsAbnHelper.Write(itsName); } const std::string & GetCalls()const { return itsAbnHelper.GetCalls(); } const std::string & GetTotalCalls()const { return itsAbnHelper.GetTotalCalls(); } const std::string & GetAbandons()const { return itsAbnHelper.GetAbandons(); } const std::string & GetTotalAbandons()const { return itsAbnHelper.GetTotalAbandons(); } const std::string & GetDateString()const { return itsAbnHelper.GetDateString(); } int OccurencesOf(const std::string & type)const { int occurences = 0; for (int i = 0; i < itsSettings.size(); i++) { if (itsSettings.at(i).GetType() == type) { occurences++; } } return occurences; } void AddTalkTime(const long int & theTime) { SetSetting("talktime",itos(GetSetting("talktime").GetInt() + theTime)); } int SettingCount()const { return itsSettings.size(); } Setting GetSetting(int whichSetting)const { return itsSettings.at(whichSetting); } // took const out after the func Setting & GetSetting(const int & whichSetting, const std::string & type) { int occurence = 0; for (int i = 0; i < itsSettings.size(); i++) { if (itsSettings.at(i).GetType() == type) { occurence++; } if (occurence == whichSetting + 1) { return itsSettings.at(i); } } } const bool DelSetting(const int & whichSetting, const std::string & type) { int occurence = 0; std::vector tempSettings; for (int i = 0; i < itsSettings.size(); i++) { if (itsSettings.at(i).GetType() == type) { occurence++; } if (occurence != whichSetting + 1) { tempSettings.push_back(itsSettings.at(i)); } } if (itsSettings.size() == tempSettings.size()) { return false; } else { itsSettings = tempSettings; return true; } } const bool DelSetting(const std::string & type) { std::vector tempSettings; for (std::vector::iterator it = itsSettings.begin(); it != itsSettings.end(); it++) { if (it->GetType() != type) { tempSettings.push_back((*it)); } } if (itsSettings.size() == tempSettings.size()) { return false; } else { itsSettings = tempSettings; return true; } } int GetSettingNumber(const int & whichSetting, const std::string & type)const { int occurence = 0; for (int i = 0; i < itsSettings.size(); i++) { if (itsSettings.at(i).GetType() == type) { occurence++; } if (occurence == whichSetting + 1) { return i; } } } // took const out afterward here as well const bool SettingExists(const std::string & type, const std::string & field, const std::string & value) { for (int i = 0; i < itsSettings.size(); i++) { if (itsSettings.at(i).GetType() == type) { // return itsSettings.at(i).AttributeExists(field,value); if (itsSettings.at(i).AttributeExists(field,value)) { return true; } } } return false; } void DelSetting(const std::string & type, const std::string & field, const std::string & value) { std::vector tempSettings; for (std::vector::iterator it = itsSettings.begin(); it != itsSettings.end(); it++) { if (it->GetType() != type) { tempSettings.push_back((*it)); } else { if (!it->AttributeExists(field, value)) { tempSettings.push_back((*it)); } } } itsSettings = tempSettings; } const Setting & GetSetting(const std::string & type) { return GetSetting(0,type); } int GetSettingNumber(const std::string & type) { return GetSettingNumber(0,type); } void SetSetting(const std::string & type, const std::string & rawSetting) { itsSettings.at(GetSettingNumber(type)).Set(";:setting:" + type + ":" + rawSetting); changed = true; } void AddSetting(const std::string & type, const std::string & settingString) { itsSettings.push_back(ReturnSetting(";:setting:" + type + ":" + settingString)); } void SupSetting(const std::string & type, const std::string & settingString) { bool exists = false; for (int i = 0; i < itsSettings.size(); i++) { if (itsSettings.at(i).GetType() == type && exists == false) { exists = true; } } if (!exists) AddSetting(type,settingString); } // void SetName(std::string name) { itsName = name; } std::string GetName()const { return itsName; } int GetMemberNumber(int whichMember)const { return itsMembersNumbers.at(whichMember); } std::string GetMemberName(int whichMember)const { return itsMembersNames.at(whichMember); } bool HasMemberNumber(int whichMember)const { // bool hasMember = false; // for (int i = 0; i < itsMembersNumbers.size(); i++) { // if (itsMembersNumbers.at(i) == whichMember) { // hasMember = true; // break; // } // } // std::cout << "Number of Agents: "; // std::cout << itsMembersNumbers.size() << std::endl; for (int i = 0; i < itsMembersNumbers.size(); i++) { if (itsMembersNumbers.at(i) == whichMember) { return true; } } return false; // return false; // if (whichMember < 17) return true; // else return false; // return hasMember; } void dumpAllAgents() { std::cout << "Member List: " << std::endl; // for (int i = 0; i < itsMembersNumbers.size(); i++) { // std::cout << itsMembersNumbers.at(i) << std::endl; // } std::cout << "Number of Agents: " << std::endl; std::cout << itsMembersNumbers.size() << std::endl; } void IncrementAbandons() { // std::ostringstream AbandonStream; // AbandonStream << GetSetting("abandons").GetInt() + 1; // SetSetting("abandons",AbandonStream.str()); // Write(); itsAbnHelper.IncrementAbandons(); } void WriteCalls() { itsAbnHelper.Write(itsName); } void AddCallsDialed(const int & calls) { // std::cout << "before: " << GetSetting("calls").Get() << std::endl; // std::ostringstream CallStream; // CallStream << GetSetting("calls").GetInt() + calls; // SetSetting("calls",CallStream.str()); // std::cout << "after: " << GetSetting("calls").Get() << std::endl;; //// Write(); itsAbnHelper.AddCallsDialed(calls); } int size()const { return itsMembersNumbers.size(); } void Write() { std::stable_sort(itsMembersNumbers.begin(),itsMembersNumbers.end()); std::stringstream QueueStream; std::ifstream QueuesIn; QueuesIn.open("/etc/asterisk/queues.conf"); if (!QueuesIn) std::cout << "Write failed!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; for (std::string tempLine; tempLine.find("[" + itsName + "]",0) == std::string::npos; ) { std::getline(QueuesIn,tempLine,'\n'); QueueStream << tempLine << std::endl; } // std::cout << "[" << itsName << "]" << std::endl; for (int i = 0; i < otherSettings.size(); i++) { QueueStream << otherSettings.at(i) << std::endl; } for (int i = 0; i < itsMembersNumbers.size(); i++) { QueueStream << "member => Agent/"; QueueStream << itsMembersNumbers.at(i) << std::endl; } for (int i = 0; i < itsSettings.size(); i++) { QueueStream << ";:setting:" << itsSettings.at(i).GetType(); for (int j = 0; j < itsSettings.at(i).WordCount(); j++) { QueueStream << ":" << itsSettings.at(i).GetWord(j); } QueueStream << std::endl; } QueueStream << std::endl; for (std::string tempLine; std::getline(QueuesIn,tempLine,'\n'); ) { if (tempLine[0] == '[') { QueueStream << tempLine << std::endl; break; } } for (std::string tempLine; std::getline(QueuesIn,tempLine,'\n'); ) { QueueStream << tempLine << std::endl; } QueuesIn.close(); std::ofstream QueuesOut; QueuesOut.open("/etc/asterisk/queues.conf"); if (!QueuesOut) std::cout << "Error writing!" << std::endl; for (std::string tempLine; std::getline(QueueStream,tempLine,'\n'); ) { QueuesOut << tempLine << std::endl; } QueuesOut.close(); } int GetAvailAgents(const AgentList & TheAgents)const { timeval tv; gettimeofday(&tv,NULL); int availAgents = 0; for (int i = 0; i < TheAgents.size(); i++) { if (TheAgents.at(i).GetStatus() > 0 && tv.tv_sec % 1000000 - TheAgents.at(i).GetStatus() > 5) { if (HasMemberNumber(TheAgents.at(i).GetNumber())) { availAgents++; } } } return availAgents; } // std::string LeastRecent(AgentList & TheAgents) { // dumpAllAgents(); // timeval tv; // gettimeofday(&tv,NULL); // int lowestTime = 999999, agentNum = 0; // std::system("/usr/bin/clear"); // std::cout << "Agents..." << std::endl; // for (int i = 0; i < TheAgents.size(); i++) { // if (HasMemberNumber(TheAgents.at(i).GetNumber()) && TheAgents.at(i).GetStatus() != -2) { // if (TheAgents.at(i).GetStatus() > 0) { // std::cout << TheAgents.at(i).GetNumber() << ": waiting " << tv.tv_sec % 1000000 - TheAgents.at(i).GetStatus() << std::endl; // } else { // std::cout << TheAgents.at(i).GetNumber() << ": on call " << tv.tv_sec % 1000000 - TheAgents.at(i).GetCalltime() << std::endl; // } // } // } // // don't forget to remove this ............................. // std::cout << std::endl; // for (int i = 0; i < TheAgents.size(); i++) { // if (HasMemberNumber(TheAgents.at(i).GetNumber())) { // if (TheAgents.at(i).GetStatus() < lowestTime && \ // tv.tv_sec % 1000000 - TheAgents.at(i).GetStatus() > 5 && \ // TheAgents.at(i).GetStatus() > 0) { //The Agents Waittime: ... //1: 452910 //current lowest time: 452910 //current lowest agent: 1 //The Agents Waittime: ... //2: -2 //current lowest time: 4294967294 //current lowest agent: 2 //2 //// std::cout << TheAgents.at(i).GetNumber() << ": " << TheAgents.at(i).GetStatus() << std::endl; //// std::cout << "current lowest time: " << lowestTime << std::endl; //// std::cout << "current lowest agent: " << agentNum << std::endl; // lowestTime = TheAgents.at(i).GetStatus(); // agentNum = TheAgents.at(i).GetNumber(); //// std::cout << "current lowest time: " << lowestTime << std::endl; //// std::cout << "current lowest agent: " << agentNum << std::endl; // } // } // } // We set them on wait in case the call doesn't // actually get to them, in which case there // will be no corresponding "Unlink" action, and // thus they won't get anymore calls until they // log in again. // TheAgents.where(agentNum).SetOnWait(false); // std::ostringstream AgentStream; // AgentStream << agentNum; // return AgentStream.str(); // } private: std::string itsName; std::vector itsMembersNumbers; std::vector itsMembersNames, otherSettings; std::vector itsSettings; bool changed; CallCache itsCalls; AbnHelper itsAbnHelper; }; Queue ReturnQueue(std::string name) { Queue TheQueue; TheQueue.ParseQueue(name); return TheQueue; } class QueueList { public: QueueList() {} ~QueueList() {} void ParseQueues() { // std::cout << "Got here beginning of ParseQueues" << std::endl; ItsQueues.clear(); // TheAgents.ParseAgentList(); std::vector queueNames; // std::cout << "Got here 1" << std::endl; std::ifstream QueuesIn; QueuesIn.open("/etc/asterisk/queues.conf"); for (std::string tempLine; std::getline(QueuesIn,tempLine,'\n');) { if (tempLine.length() > 1 && tempLine.find("default",0) == std::string::npos) { if (tempLine[0] == '[' && tempLine.find("general") == std::string::npos) { queueNames.push_back(tempLine.substr(1,tempLine.find("]",0)-1)); // std::cout << "pushing back..." << std::endl; } } } QueuesIn.close(); // std::cout << "Actual push_backs now..." << std::endl; for (int i = 0; i < queueNames.size(); i++) { // std::cout << "pushnig back" << std::endl; ItsQueues.push_back(ReturnQueue(queueNames.at(i))); } // std::cout << "Got to end of ParseQueues" << std::endl; // std::cout << "size of queues " << ItsQueues.size() << std::endl; } Queue at(int whichQueue)const { return ItsQueues.at(whichQueue); } int size() { return ItsQueues.size(); } Queue where(const std::string & queue) { for (int i = 0; i < ItsQueues.size(); i++) { if (ItsQueues.at(i).GetName() == queue) { return ItsQueues.at(i); } } } std::string LeastRecent(std::string name, AgentList & TheAgents) { //dumpAllAgents(); Queue tempQueue; for (int i = 0; i < ItsQueues.size(); i++) { if (name == ItsQueues.at(i).GetName()) { tempQueue = ItsQueues.at(i); break; } } timeval tv; gettimeofday(&tv,NULL); int lowestTime = 999999, agentNum = 0; // std::system("/usr/bin/clear"); std::cout << "Agents on " << name << ":" << std::endl; for (int i = 0; i < TheAgents.size(); i++) { if (tempQueue.HasMemberNumber(TheAgents.at(i).GetNumber()) && TheAgents.at(i).GetStatus() != -2) { if (TheAgents.at(i).GetStatus() > 0) { if (tv.tv_sec % 1000000 - TheAgents.at(i).GetStatus() > 5) { std::cout << TheAgents.at(i).GetNumber() << ": waiting " << tv.tv_sec % 1000000 - TheAgents.at(i).GetStatus() << std::endl; } else { std::cout << TheAgents.at(i).GetNumber() << ": wrapup " << tv.tv_sec % 1000000 - TheAgents.at(i).GetStatus() << std::endl; } } else { std::cout << TheAgents.at(i).GetNumber() << ": on call " << tv.tv_sec % 1000000 - TheAgents.at(i).GetCalltime() << std::endl; } } } // don't forget to remove this ............................. std::cout << std::endl; // working right here for (int i = 0; i < TheAgents.size(); i++) { if (tempQueue.HasMemberNumber(TheAgents.at(i).GetNumber())) { if (TheAgents.at(i).GetStatus() < lowestTime && \ tv.tv_sec % 1000000 - TheAgents.at(i).GetStatus() > 5 && \ TheAgents.at(i).GetStatus() > 0) { //The Agents Waittime: ... //1: 452910 //current lowest time: 452910 //current lowest agent: 1 //The Agents Waittime: ... //2: -2 //current lowest time: 4294967294 //current lowest agent: 2 //2 // std::cout << TheAgents.at(i).GetNumber() << ": " << TheAgents.at(i).GetStatus() << std::endl; // std::cout << "current lowest time: " << lowestTime << std::endl; // std::cout << "current lowest agent: " << agentNum << std::endl; lowestTime = TheAgents.at(i).GetStatus(); agentNum = TheAgents.at(i).GetNumber(); // std::cout << "current lowest time: " << lowestTime << std::endl; // std::cout << "current lowest agent: " << agentNum << std::endl; } } } // We set them on wait in case the call doesn't // actually get to them, in which case there // will be no corresponding "Unlink" action, and // thus they won't get anymore calls until they // log in again. TheAgents.where(agentNum).SetOnWait(false,false,TheAgents); std::ostringstream AgentStream; AgentStream << agentNum; return AgentStream.str(); } Queue & rWhere(const std::string & queue) { for (int i = 0; i < ItsQueues.size(); i++) { if (ItsQueues.at(i).GetName() == queue) { return ItsQueues.at(i); } } } bool exists(const std::string & name) { for (int i = 0; i < ItsQueues.size(); i++) { if (ItsQueues.at(i).GetName() == name) { return true; } } return false; } private: std::vector ItsQueues; //AgentList TheAgents; }; #endif