// Windows XP FAQ Poll // // Douglas Thrift // // Poller.cpp #include "Poller.h" Poller::Poller() { string mailbox = session->list("\"\" \"" + account.getMailbox() + "\""); if (mailbox.find(account.getMailbox()) == string::npos) { cerr << program << ": Mailbox does not exist: " << account.getMailbox() << "\n"; exit(1); } } Poller::~Poller() { if (!nodelete) { session->expunge(); } } void Poller::poll(bool nodelete, const string& file) { this->nodelete = nodelete; this->file = file; load(); ballots(); approvals(); save(); } void Poller::load() { ifstream fin(file.c_str()); if (!fin.is_open()) { fin.clear(); ofstream fout(file.c_str()); fout << "_find_\n" << "reply=0\n" << "news=0\n" << "sig=0\n" << "search=0\n" << "link=0\n" << "browse=0\n" << "other=0\n" << "_help_\n" << "solved=0\n" << "note=0\n" << "link=0\n" << "news=0\n" << "lazy=0\n" << "_improve_\n" << "nothing=0\n" << "links=0\n" << "suggest=0\n"; fout.close(); fin.open(file.c_str()); } while (fin.good()) { enum { FIND, HELP, IMPROVE } type; string vote; unsigned count; string text; fin.peek() != '_' ? getline(fin, vote, '=') : getline(fin, vote); if (debug) cerr << "vote = " << vote << "\n"; if (vote == "_find_") { type = FIND; continue; } else if (vote == "_help_") { type = HELP; continue; } else if (vote == "_improve_") { type = IMPROVE; continue; } else if (vote == "approved" || vote == "approve") { getline(fin, text); } else { fin >> count; fin.get(); } fin.peek(); switch (type) { case FIND: if (vote == "reply") { find.reply = count; } else if (vote == "news") { find.news = count; } else if (vote == "sig") { find.sig = count; } else if (vote == "search") { find.search = count; } else if (vote == "link") { find.link = count; } else if (vote == "browse") { find.browse = count; } else if (vote == "other") { find.other = count; } else if (vote == "approved") { find.approved.push_back(text); } else if (vote == "approve") { find.approve.push_back(text); } break; case HELP: if (vote == "solved") { help.solved = count; } else if (vote == "note") { help.note = count; } else if (vote == "link") { help.link = count; } else if (vote == "news") { help.news = count; } else if (vote == "lazy") { help.lazy = count; } break; case IMPROVE: if (vote == "nothing") { improve.nothing = count; } else if (vote == "links") { improve.links = count; } else if (vote == "suggest") { improve.suggest = count; } else if (vote == "approved") { improve.approved.push_back(text); } else if (vote == "approve") { improve.approve.push_back(text); } break; } } fin.close(); } void Poller::save() { unsigned index; ofstream fout(file.c_str()); fout << "_find_\n" << "reply=" << find.reply << "\n" << "news=" << find.news << "\n" << "sig=" << find.sig << "\n" << "search=" << find.search << "\n" << "link=" << find.link << "\n" << "browse=" << find.browse << "\n" << "other=" << find.other << "\n"; for (index = 0; index < find.approved.size(); index++) { fout << "approved=" << find.approved[index] << "\n"; } for (index = 0; index < find.approve.size(); index++) { fout << "approve=" << find.approve[index] << "\n"; } fout << "_help_\n" << "solved=" << help.solved << "\n" << "note=" << help.note << "\n" << "link=" << help.link << "\n" << "news=" << help.news << "\n" << "lazy=" << help.lazy << "\n" << "_improve_\n" << "nothing=" << improve.nothing << "\n" << "links=" << improve.links << "\n" << "suggest=" << improve.suggest << "\n"; for (index = 0; index < improve.approved.size(); index++) { fout << "approved=" << improve.approved[index] << "\n"; } for (index = 0; index < improve.approve.size(); index++) { fout << "approve=" << improve.approve[index] << "\n"; } fout.close(); } void Poller::ballots() { session->select('\"' + account.getMailbox() + '\"'); stringstream search; search << session->search(string("ALL HEADER X-Mailer \"WinXPFAQPoll 1.0 ") + "(Perl)\" SUBJECT \"Windows XP FAQ | Poll Ballot\" UNDELETED FROM \"" + "Windows XP FAQ | Poll\""); search.ignore(9); search.peek(); while (search.good()) { unsigned message; search >> message; if (debug) cerr << "message = " << message << "\n"; messages.push(message); search.get(); search.peek(); } if (!messages.empty()) { unsigned message = messages.front(); messages.pop(); ballot(message); } } void Poller::ballot(unsigned message) { cout << "Checking message: " << message << "..." << flush; ostringstream number; number << message; stringstream buffer; buffer << session->fetch(number.str() + " BODY.PEEK[2]"); if (session->successful()) { buffer.ignore(string::npos, '\n'); bool approved = session->fetch(number.str() + " FLAGS").find("\\Flagge" + string("d")) != string::npos; while (buffer.peek() != '\n' && buffer.good()) { enum { FIND, HELP, IMPROVE } type; string vote; getline(buffer, vote); if (debug) cerr << "vote = " << vote << "\n"; if (vote == "_find_") { type = FIND; continue; } else if (vote == "_help_") { type = HELP; continue; } else if (vote == "_improve_") { type = IMPROVE; continue; } buffer.peek(); switch (type) { case FIND: if (vote == "reply") { find.reply++; } else if (vote == "news") { find.news++; } else if (vote == "sig") { find.sig++; } else if (vote == "search") { find.search++; } else if (vote == "link") { find.link++; } else if (vote == "browse") { find.browse++; } else if (vote == "other") { find.other++; string text; getline(buffer, text); if (approved) { find.approved.push_back(text); } else { find.approve.push_back(text); submit("find", text); } } break; case HELP: if (vote == "solved") { help.solved++; } else if (vote == "note") { help.note++; } else if (vote == "link") { help.link++; } else if (vote == "news") { help.news++; } else if (vote == "lazy") { help.lazy++; } break; case IMPROVE: if (vote == "nothing") { improve.nothing++; } else if (vote == "links") { improve.links++; } else if (vote == "suggest") { improve.suggest++; string text; getline(buffer, text); if (approved) { improve.approved.push_back(text); } else { improve.approve.push_back(text); submit("improve", text); } } break; } } session->store(number.str() + " +FLAGS (\\Deleted)"); cout << "done.\n"; } else { cout << "cancelled.\n"; } if (!messages.empty()) { unsigned message = messages.front(); messages.pop(); ballot(message); } } void Poller::submit(const string& type, const string& text) { ostringstream message; message << "From: \"Windows XP FAQ | Poll\" <" << account.getEmail() << ">\n" << "To: \"" << account.getName() << "\" <" << account.getEmail() << ">\n" << "Subject: Windows XP FAQ | Poll Submit\n" << "Content-Type: text/plain charset=\"us-ascii\"\n" << "Content-Transfer-Encoding: 7bit\n" << "X-Mailer: WinXPFAQPoll 1.0\n" << "X-WinXPFAQPoll-Submit-Type: " << type << "\n" << "X-WinXPFAQPoll-Submit-Text: " << text << "\n\n"; if (type == "find") { message << "How did you find this page?\n" << " I arrived here by entirely different means:\n"; } else if (type == "improve") { message << "How could I improve this site?\n" << " I have my own completely insane suggestion:\n"; } message << " " << text << "\n\n" << "Flag this message to approve the voter\'s possibly objectionable\n" << "input or delete it to disapprove.\n\n" << "This message will be marked deleted when it is processed.\n"; ostringstream length; length << (message.str().length() + 16); session->append('\"' + account.getMailbox() + "\" {" + length.str() + '}', message.str()); session->noop(); } void Poller::approvals() { // } void Poller::approval(unsigned message) { // }