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 119 by douglas, 2003-04-01T14:49:17-08:00 vs.
Revision 128 by douglas, 2003-04-03T20:59:00-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;
# Line 26 | Line 34 | void Poller::poll(bool nodelete, const s
34  
35          load();
36  
37 <        //
37 >        ballots();
38 >        approvals();
39  
40 < //      save();
40 >        save();
41   }
42  
43   void Poller::load()
# Line 36 | Line 45 | void Poller::load()
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"
# Line 62 | Line 73 | void Poller::load()
73                  fin.open(file.c_str());
74          }
75  
76 <        do
76 >        while (fin.good())
77          {
78                  enum { FIND, HELP, IMPROVE } type;
79                  string vote;
80                  unsigned count;
81                  string text;
82  
83 <                getline(fin, vote, '=');
83 >                fin.peek() != '_' ? getline(fin, vote, '=') : getline(fin, vote);
84                  if (debug) cerr << "vote = " << vote << "\n";
85  
86                  if (vote == "_find_")
# Line 97 | Line 108 | void Poller::load()
108                          fin.get();
109                  }
110  
111 +                fin.peek();
112 +
113                  switch (type)
114                  {
115                  case FIND:
# Line 183 | Line 196 | void Poller::load()
196                          break;
197                  }
198          }
186        while (fin.good());
199  
200          fin.close();
201   }
202  
203   void Poller::save()
204   {
205 +        unsigned index;
206          ofstream fout(file.c_str());
207  
208 <        //
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