ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/proj/trunk/WinXPFAQPoll/Poller.cpp
(Generate patch)

Comparing trunk/WinXPFAQPoll/Poller.cpp (file contents):
Revision 118 by douglas, 2003-04-01T13:41:03-08:00 vs.
Revision 129 by douglas, 2003-04-03T21:13:24-08:00

# Line 19 | Line 19 | Poller::Poller()
19          }
20   }
21  
22 + Poller::~Poller()
23 + {
24 +        if (!nodelete)
25 +        {
26 +                session->expunge();
27 +        }
28 + }
29 +
30   void Poller::poll(bool nodelete, const string& file)
31   {
32          this->nodelete = nodelete;
33 +        this->file = file;
34 +
35 +        load();
36 +
37 +        ballots();
38 +        approvals();
39 +
40 +        save();
41 + }
42 +
43 + void Poller::load()
44 + {
45 +        ifstream fin(file.c_str());
46 +        if (!fin.is_open())
47 +        {
48 +                fin.clear();
49 +
50 +                ofstream fout(file.c_str());
51 +
52 +                fout << "_find_\n"
53 +                        << "reply=0\n"
54 +                        << "news=0\n"
55 +                        << "sig=0\n"
56 +                        << "search=0\n"
57 +                        << "link=0\n"
58 +                        << "browse=0\n"
59 +                        << "other=0\n"
60 +                        << "_help_\n"
61 +                        << "solved=0\n"
62 +                        << "note=0\n"
63 +                        << "link=0\n"
64 +                        << "news=0\n"
65 +                        << "lazy=0\n"
66 +                        << "_improve_\n"
67 +                        << "nothing=0\n"
68 +                        << "links=0\n"
69 +                        << "suggest=0\n";
70 +
71 +                fout.close();
72 +
73 +                fin.open(file.c_str());
74 +        }
75 +
76 +        while (fin.good())
77 +        {
78 +                enum { FIND, HELP, IMPROVE } type;
79 +                string vote;
80 +                unsigned count;
81 +                string text;
82 +
83 +                fin.peek() != '_' ? getline(fin, vote, '=') : getline(fin, vote);
84 +                if (debug) cerr << "vote = " << vote << "\n";
85 +
86 +                if (vote == "_find_")
87 +                {
88 +                        type = FIND;
89 +                        continue;
90 +                }
91 +                else if (vote == "_help_")
92 +                {
93 +                        type = HELP;
94 +                        continue;
95 +                }
96 +                else if (vote == "_improve_")
97 +                {
98 +                        type = IMPROVE;
99 +                        continue;
100 +                }
101 +                else if (vote == "approved" || vote == "approve")
102 +                {
103 +                        getline(fin, text);
104 +                }
105 +                else
106 +                {
107 +                        fin >> count;
108 +                        fin.get();
109 +                }
110 +
111 +                if (fin.peek() == EOF) fin.get();
112 +
113 +                switch (type)
114 +                {
115 +                case FIND:
116 +                        if (vote == "reply")
117 +                        {
118 +                                find.reply = count;
119 +                        }
120 +                        else if (vote == "news")
121 +                        {
122 +                                find.news = count;
123 +                        }
124 +                        else if (vote == "sig")
125 +                        {
126 +                                find.sig = count;
127 +                        }
128 +                        else if (vote == "search")
129 +                        {
130 +                                find.search = count;
131 +                        }
132 +                        else if (vote == "link")
133 +                        {
134 +                                find.link = count;
135 +                        }
136 +                        else if (vote == "browse")
137 +                        {
138 +                                find.browse = count;
139 +                        }
140 +                        else if (vote == "other")
141 +                        {
142 +                                find.other = count;
143 +                        }
144 +                        else if (vote == "approved")
145 +                        {
146 +                                find.approved.push_back(text);
147 +                        }
148 +                        else if (vote == "approve")
149 +                        {
150 +                                find.approve.push_back(text);
151 +                        }
152 +                        break;
153 +                case HELP:
154 +                        if (vote == "solved")
155 +                        {
156 +                                help.solved = count;
157 +                        }
158 +                        else if (vote == "note")
159 +                        {
160 +                                help.note = count;
161 +                        }
162 +                        else if (vote == "link")
163 +                        {
164 +                                help.link = count;
165 +                        }
166 +                        else if (vote == "news")
167 +                        {
168 +                                help.news = count;
169 +                        }
170 +                        else if (vote == "lazy")
171 +                        {
172 +                                help.lazy = count;
173 +                        }
174 +                        break;
175 +                case IMPROVE:
176 +                        if (vote == "nothing")
177 +                        {
178 +                                improve.nothing = count;
179 +                        }
180 +                        else if (vote == "links")
181 +                        {
182 +                                improve.links = count;
183 +                        }
184 +                        else if (vote == "suggest")
185 +                        {
186 +                                improve.suggest = count;
187 +                        }
188 +                        else if (vote == "approved")
189 +                        {
190 +                                improve.approved.push_back(text);
191 +                        }
192 +                        else if (vote == "approve")
193 +                        {
194 +                                improve.approve.push_back(text);
195 +                        }
196 +                        break;
197 +                }
198 +        }
199 +
200 +        fin.close();
201 + }
202 +
203 + void Poller::save()
204 + {
205 +        unsigned index;
206 +        ofstream fout(file.c_str());
207 +
208 +        fout << "_find_\n"
209 +                << "reply=" << find.reply << "\n"
210 +                << "news=" << find.news << "\n"
211 +                << "sig=" << find.sig << "\n"
212 +                << "search=" << find.search << "\n"
213 +                << "link=" << find.link << "\n"
214 +                << "browse=" << find.browse << "\n"
215 +                << "other=" << find.other << "\n";
216 +
217 +        for (index = 0; index < find.approved.size(); index++)
218 +        {
219 +                fout << "approved=" << find.approved[index] << "\n";
220 +        }
221 +
222 +        for (index = 0; index < find.approve.size(); index++)
223 +        {
224 +                fout << "approve=" << find.approve[index] << "\n";
225 +        }
226 +
227 +        fout << "_help_\n"
228 +                << "solved=" << help.solved << "\n"
229 +                << "note=" << help.note << "\n"
230 +                << "link=" << help.link << "\n"
231 +                << "news=" << help.news << "\n"
232 +                << "lazy=" << help.lazy << "\n"
233 +                << "_improve_\n"
234 +                << "nothing=" << improve.nothing << "\n"
235 +                << "links=" << improve.links << "\n"
236 +                << "suggest=" << improve.suggest << "\n";
237 +
238 +        for (index = 0; index < improve.approved.size(); index++)
239 +        {
240 +                fout << "approved=" << improve.approved[index] << "\n";
241 +        }
242 +
243 +        for (index = 0; index < improve.approve.size(); index++)
244 +        {
245 +                fout << "approve=" << improve.approve[index] << "\n";
246 +        }
247 +
248 +        fout.close();
249 + }
250 +
251 + void Poller::ballots()
252 + {
253 +        session->select('\"' + account.getMailbox() + '\"');
254 +
255 +        stringstream search;
256 +        search << session->search(string("ALL HEADER X-Mailer \"WinXPFAQPoll 1.0 ")
257 +                + "(Perl)\" SUBJECT \"Windows XP FAQ | Poll Ballot\" FROM \"Windows XP"
258 +                + " FAQ | Poll\"");
259 +
260 +        search.ignore(9);
261 +        search.peek();
262 +
263 +        while (search.good())
264 +        {
265 +                unsigned message;
266 +                search >> message;
267 +
268 +                if (debug) cerr << "message = " << message << "\n";
269 +                messages.push(message);
270 +
271 +                search.get();
272 +                search.peek();
273 +        }
274 +
275 +        if (!messages.empty())
276 +        {
277 +                unsigned message = messages.front();
278 +                messages.pop();
279 +
280 +                ballot(message);
281 +        }
282 +
283 +        if (submits.size() > 0)
284 +        {
285 +                cout << "Sending submits..." << flush;
286 +
287 +                for (unsigned index = 0; index < submits.size(); index++)
288 +                {
289 +                        submit(submits[index].first, submits[index].second);
290 +                }
291 +
292 +                submits.clear();
293 +
294 +                cout << "done.\n";
295 +        }
296 + }
297 +
298 + void Poller::ballot(unsigned message)
299 + {
300 +        cout << "Checking message: " << message << "..." << flush;
301 +
302 +        ostringstream number;
303 +        number << message;
304 +
305 +        stringstream buffer;
306 +
307 +        buffer << session->fetch(number.str() + " BODY.PEEK[2]");
308 +
309 +        if (session->successful() && session->fetch(number.str() + " FLAGS").find(
310 +                "\\Deleted") == string::npos)
311 +        {
312 +                buffer.ignore(string::npos, '\n');
313 +
314 +                bool approved = session->fetch(number.str() + " FLAGS").find("\\Flagge"
315 +                        + string("d")) != string::npos;
316 +
317 +                while (buffer.peek() != '\n' && buffer.good())
318 +                {
319 +                        enum { FIND, HELP, IMPROVE } type;
320 +                        string vote;
321 +
322 +                        getline(buffer, vote);
323 +                        if (debug) cerr << "vote = " << vote << "\n";
324 +
325 +                        if (vote == "_find_")
326 +                        {
327 +                                type = FIND;
328 +                                continue;
329 +                        }
330 +                        else if (vote == "_help_")
331 +                        {
332 +                                type = HELP;
333 +                                continue;
334 +                        }
335 +                        else if (vote == "_improve_")
336 +                        {
337 +                                type = IMPROVE;
338 +                                continue;
339 +                        }
340 +
341 +                        buffer.peek();
342 +
343 +                        switch (type)
344 +                        {
345 +                        case FIND:
346 +                                if (vote == "reply")
347 +                                {
348 +                                        find.reply++;
349 +                                }
350 +                                else if (vote == "news")
351 +                                {
352 +                                        find.news++;
353 +                                }
354 +                                else if (vote == "sig")
355 +                                {
356 +                                        find.sig++;
357 +                                }
358 +                                else if (vote == "search")
359 +                                {
360 +                                        find.search++;
361 +                                }
362 +                                else if (vote == "link")
363 +                                {
364 +                                        find.link++;
365 +                                }
366 +                                else if (vote == "browse")
367 +                                {
368 +                                        find.browse++;
369 +                                }
370 +                                else if (vote == "other")
371 +                                {
372 +                                        find.other++;
373 +
374 +                                        string text;
375 +                                        getline(buffer, text);
376 +
377 +                                        if (approved)
378 +                                        {
379 +                                                find.approved.push_back(text);
380 +                                        }
381 +                                        else
382 +                                        {
383 +                                                find.approve.push_back(text);
384 +
385 +                                                submits.push_back(pair<string, string>("find", text));
386 +                                        }
387 +                                }
388 +                                break;
389 +                        case HELP:
390 +                                if (vote == "solved")
391 +                                {
392 +                                        help.solved++;
393 +                                }
394 +                                else if (vote == "note")
395 +                                {
396 +                                        help.note++;
397 +                                }
398 +                                else if (vote == "link")
399 +                                {
400 +                                        help.link++;
401 +                                }
402 +                                else if (vote == "news")
403 +                                {
404 +                                        help.news++;
405 +                                }
406 +                                else if (vote == "lazy")
407 +                                {
408 +                                        help.lazy++;
409 +                                }
410 +                                break;
411 +                        case IMPROVE:
412 +                                if (vote == "nothing")
413 +                                {
414 +                                        improve.nothing++;
415 +                                }
416 +                                else if (vote == "links")
417 +                                {
418 +                                        improve.links++;
419 +                                }
420 +                                else if (vote == "suggest")
421 +                                {
422 +                                        improve.suggest++;
423 +
424 +                                        string text;
425 +                                        getline(buffer, text);
426 +
427 +                                        if (approved)
428 +                                        {
429 +                                                improve.approved.push_back(text);
430 +                                        }
431 +                                        else
432 +                                        {
433 +                                                improve.approve.push_back(text);
434 +
435 +                                                submits.push_back(pair<string, string>("improve",
436 +                                                        text));
437 +                                        }
438 +                                }
439 +                                break;
440 +                        }
441 +                }
442 +
443 +                session->store(number.str() + " +FLAGS (\\Deleted)");
444 +
445 +                cout << "done.\n";
446 +        }
447 +        else
448 +        {
449 +                cout << "cancelled.\n";
450 +        }
451 +
452 +        if (!messages.empty())
453 +        {
454 +                unsigned message = messages.front();
455 +                messages.pop();
456 +
457 +                ballot(message);
458 +        }
459 + }
460 +
461 + void Poller::submit(const string& type, const string& text)
462 + {
463 +        ostringstream message;
464 +
465 +        message << "From: \"Windows XP FAQ | Poll\" <" << account.getEmail()
466 +                << ">\n"
467 +                << "To: \"" << account.getName() << "\" <" << account.getEmail()
468 +                << ">\n"
469 +                << "Subject: Windows XP FAQ | Poll Submit\n"
470 +                << "Content-Type: text/plain charset=\"us-ascii\"\n"
471 +                << "Content-Transfer-Encoding: 7bit\n"
472 +                << "X-Mailer: WinXPFAQPoll 1.0\n"
473 +                << "X-WinXPFAQPoll-Submit-Type: " << type << "\n"
474 +                << "X-WinXPFAQPoll-Submit-Text: " << text << "\n\n";
475 +
476 +        if (type == "find")
477 +        {
478 +                message << "How did you find this page?\n"
479 +                        << "    I arrived here by entirely different means:\n";
480 +        }
481 +        else if (type == "improve")
482 +        {
483 +                message << "How could I improve this site?\n"
484 +                        << "    I have my own completely insane suggestion:\n";
485 +        }
486 +
487 +        message << "    " << text << "\n\n"
488 +                << "Flag this message to approve the voter\'s possibly objectionable\n"
489 +                << "input or delete it to disapprove.\n\n"
490 +                << "This message will be marked deleted when it is processed.\n";
491 +
492 +        ostringstream length;
493 +        length << (message.str().length() + 16);
494 +
495 +        session->append('\"' + account.getMailbox() + "\" {" + length.str() + '}',
496 +                message.str());
497 +
498 +        session->noop();
499 + }
500 +
501 + void Poller::approvals()
502 + {
503 +        unsigned index;
504 +
505 +        session->check();
506 +
507 +        for (index = find.approve.size(); index > 0; index--)
508 +        {
509 +                cout << "Checking find: " << index << "..." << flush;
510 +
511 +                switch (approval("find", find.approve[index - 1]))
512 +                {
513 +                case true:
514 +                        find.approved.push_back(find.approve[index - 1]);
515 +                case false:
516 +                        find.approve.erase(find.approve.begin() + (index - 1));
517 +                        break;
518 +                default:
519 +                        break;
520 +                }
521 +        }
522 +
523 +        for (index = improve.approve.size(); index > 0; index--)
524 +        {
525 +                cout << "Checking improve: " << index << "..." << flush;
526 +
527 +                switch (approval("improve", improve.approve[index - 1]))
528 +                {
529 +                case true:
530 +                        improve.approved.push_back(improve.approve[index - 1]);
531 +                case false:
532 +                        improve.approve.erase(improve.approve.begin() + (index - 1));
533 +                        break;
534 +                default:
535 +                        break;
536 +                }
537 +        }
538 +
539 +        if (find.disapprove.size() > 0 || improve.disapprove.size() > 0)
540 +        {
541 +                cout << "Sending disapprovals..." << flush;
542 +
543 +                ostringstream message;
544 +
545 +                message << "From: \"Windows XP FAQ | Poll\" <" << account.getEmail()
546 +                        << ">\n"
547 +                        << "To: \"" << account.getName() << "\" <" << account.getEmail()
548 +                        << ">\n"
549 +                        << "Subject: Windows XP FAQ | Poll Disapprovals\n"
550 +                        << "Content-Type: multipart/mixed;\n"
551 +                        << "    boundary=\"----=_NextPart_WinXPFAQPoll_0\"\n"
552 +                        << "Content-Transfer-Encoding: 7bit\n"
553 +                        << "X-Mailer: WinXPFAQPoll 1.0\n\n"
554 +                        << "This is a multi-part message in MIME format.\n\n"
555 +                        << "------=_NextPart_WinXPFAQPoll_0\n"
556 +                        << "Content-Type: text/plain charset=\"us-ascii\"\n"
557 +                        << "Content-Transfer-Encoding: 7bit\n\n"
558 +                        << "Apparently these answers where disapproved:\n\n";
559 +
560 +                unsigned extra = 0;
561 +
562 +                for (index = 0; index < find.disapprove.size(); index++, extra += 4)
563 +                {
564 +                        message << "How did you find this page?\n"
565 +                                << "    I arrived here by entirely different means:\n"
566 +                                << "    " << find.disapprove[index] << "\n\n";
567 +                }
568 +
569 +                for (index = 0; index < improve.disapprove.size(); index++, extra += 4)
570 +                {
571 +                        message << "How could I improve this site?\n"
572 +                                << "    I have my own completely insane suggestion:\n"
573 +                                << "    " << improve.disapprove[index] << "\n\n";
574 +                }
575 +
576 +                message << "Make sure there were no errors.\n\n"
577 +                        << "------=_NextPart_WinXPFAQPoll_0\n"
578 +                        << "Content-Type: text/plain;\n"
579 +                        << "    name=\"disapprove.dat\"\n"
580 +                        << "Content-Transfer-Encoding: 7bit\n"
581 +                        << "Content-Disposition: attachment;\n"
582 +                        << "    filename=\"disapprove.dat\"\n\n";
583 +
584 +                if (find.disapprove.size() > 0)
585 +                {
586 +                        message << "_find_\n";
587 +                        extra++;
588 +                }
589 +
590 +                for (index = 0; index < find.disapprove.size(); index++, extra += 1)
591 +                {
592 +                        message << find.disapprove[index] << "\n";
593 +                }
594 +
595 +                if (improve.disapprove.size() > 0)
596 +                {
597 +                        message << "_improve_\n";
598 +                        extra++;
599 +                }
600 +
601 +                for (index = 0; index < improve.disapprove.size(); index++, extra += 1)
602 +                {
603 +                        message << improve.disapprove[index] << "\n";
604 +                }
605 +
606 +                message << "\n------=_NextPart_WinXPFAQPoll_0--\n";
607 +
608 +                ostringstream length;
609 +                length << (message.str().length() + 26 + extra);
610 +
611 +                session->append('\"' + account.getMailbox() + "\" {" + length.str() +
612 +                        '}', message.str());
613 +                
614 +                session->noop();
615 +
616 +                cout << "done.\n";
617 +        }
618 + }
619 +
620 + short Poller::approval(const string& type, const string& text)
621 + {
622 +        short answer = -1;
623 +
624 +        stringstream search;
625 +        search << session->search(string("ALL HEADER X-Mailer \"WinXPFAQPoll 1.0")
626 +                + "\" SUBJECT \"Windows XP FAQ | Poll Submit\" FROM \"Windows XP FAQ |"
627 +                + " Poll\" HEADER X-WinXPFAQPoll-Submit-Type \"" + type + "\" HEADER X"
628 +                + "-WinXPFAQPoll-Submit-Text \"" + text + '\"');
629 +
630 +        search.ignore(9);
631 +        search.peek();
632 +
633 +        if (search.good())
634 +        {
635 +                unsigned message;
636 +                search >> message;
637 +
638 +                if (debug) cerr << "message = " << message << "\n";
639 +
640 +                ostringstream number;
641 +                number << message;
642 +
643 +                if (session->fetch(number.str() + " FLAGS").find("\\Deleted") !=
644 +                        string::npos)
645 +                {
646 +                        answer = false;
647 +                }
648 +                else if (session->fetch(number.str() + " FLAGS").find("\\Flagged") !=
649 +                        string::npos)
650 +                {
651 +                        answer = true;
652 +
653 +                        session->store(number.str() + " +FLAGS (\\Deleted)");
654 +                }
655 +        }
656 +        else
657 +        {
658 +                answer = false;
659 +        }
660 +
661 +        switch (answer)
662 +        {
663 +        case true:
664 +                cout << "approved.\n";
665 +                break;
666 +        case false:
667 +                if (type == "find")
668 +                {
669 +                        find.disapprove.push_back(text);
670 +                }
671 +                else if (type == "improve")
672 +                {
673 +                        improve.disapprove.push_back(text);
674 +                }
675 +                cout << "disapproved.\n";
676 +                break;
677 +        default:
678 +                cout << "cancelled.\n";
679 +                break;
680 +        }
681 +
682 +        return answer;
683   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines