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 231 by douglas, 2003-08-05T20:36:00-07:00

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines