| 1 |
""" |
|---|
| 2 |
Exitcode: |
|---|
| 3 |
0 - no error, message is not a spam |
|---|
| 4 |
1 - error, unable to analyze the message |
|---|
| 5 |
2 - no error, the message is a spam |
|---|
| 6 |
""" |
|---|
| 7 |
|
|---|
| 8 |
from optparse import OptionParser |
|---|
| 9 |
from logging import (INFO, WARNING, ERROR, |
|---|
| 10 |
getLogger, Formatter, StreamHandler, error) |
|---|
| 11 |
from antispam.analyzer import Analyzer |
|---|
| 12 |
from sys import stdin, exit, stdout |
|---|
| 13 |
from antispam.error import writeError |
|---|
| 14 |
|
|---|
| 15 |
class Application(Analyzer): |
|---|
| 16 |
def __init__(self): |
|---|
| 17 |
Analyzer.__init__(self) |
|---|
| 18 |
try: |
|---|
| 19 |
self.parseOptions() |
|---|
| 20 |
self.setupLog() |
|---|
| 21 |
self.loadConfig(self.options.config) |
|---|
| 22 |
except Exception, err: |
|---|
| 23 |
writeError(getLogger(), err, "Error on initialization") |
|---|
| 24 |
exit(1) |
|---|
| 25 |
|
|---|
| 26 |
def setupLog(self): |
|---|
| 27 |
if self.options.debug: |
|---|
| 28 |
level = INFO |
|---|
| 29 |
elif self.options.verbose: |
|---|
| 30 |
level = WARNING |
|---|
| 31 |
else: |
|---|
| 32 |
level = ERROR |
|---|
| 33 |
log = getLogger() |
|---|
| 34 |
formatter = Formatter('%(message)s') |
|---|
| 35 |
handler = StreamHandler(stdout) |
|---|
| 36 |
handler.setLevel(level) |
|---|
| 37 |
handler.setFormatter(formatter) |
|---|
| 38 |
log.setLevel(level) |
|---|
| 39 |
log.addHandler(handler) |
|---|
| 40 |
|
|---|
| 41 |
def parseOptions(self): |
|---|
| 42 |
parser = OptionParser(usage="%prog [options] message.txt") |
|---|
| 43 |
|
|---|
| 44 |
parser.add_option("-c", "--config", help="Configuration filename", |
|---|
| 45 |
type="str", default=None) |
|---|
| 46 |
parser.add_option("-v", "--verbose", help="Enable verbose mode (set log level to WARNING)", |
|---|
| 47 |
action="store_true") |
|---|
| 48 |
parser.add_option("-d", "--debug", help="Enable debug mode (set log level to INFO)", |
|---|
| 49 |
action="store_true") |
|---|
| 50 |
|
|---|
| 51 |
self.options, self.arguments = parser.parse_args() |
|---|
| 52 |
|
|---|
| 53 |
def displayScore(self, filename, score): |
|---|
| 54 |
message = "%s score: %+.2f" % (filename, score) |
|---|
| 55 |
if 0 < score: |
|---|
| 56 |
message += " ***SPAM***" |
|---|
| 57 |
print message |
|---|
| 58 |
|
|---|
| 59 |
def processFile(self, filename): |
|---|
| 60 |
try: |
|---|
| 61 |
message = self.parseFile(filename) |
|---|
| 62 |
score = self.computeScore(message) |
|---|
| 63 |
if 0 < score: |
|---|
| 64 |
self.exitcode = 2 |
|---|
| 65 |
self.displayScore(filename, score) |
|---|
| 66 |
except Exception, err: |
|---|
| 67 |
writeError(getLogger(), err, |
|---|
| 68 |
"Error while processing file %r" % filename) |
|---|
| 69 |
self.exitcode = 1 |
|---|
| 70 |
|
|---|
| 71 |
def processStdin(self): |
|---|
| 72 |
try: |
|---|
| 73 |
|
|---|
| 74 |
charset = "utf8" |
|---|
| 75 |
|
|---|
| 76 |
|
|---|
| 77 |
lines = [] |
|---|
| 78 |
try: |
|---|
| 79 |
while True: |
|---|
| 80 |
line = raw_input() |
|---|
| 81 |
line = line.rstrip() |
|---|
| 82 |
line = unicode(line, charset, "replace") |
|---|
| 83 |
lines.append(line) |
|---|
| 84 |
except (KeyboardInterrupt, EOFError): |
|---|
| 85 |
pass |
|---|
| 86 |
if not lines: |
|---|
| 87 |
error("Empty input, exit!") |
|---|
| 88 |
exit(1) |
|---|
| 89 |
|
|---|
| 90 |
message = self.parseLines(lines) |
|---|
| 91 |
score = self.computeScore(message) |
|---|
| 92 |
if 0 < score: |
|---|
| 93 |
self.exitcode = 2 |
|---|
| 94 |
self.displayScore("-stdin-", score) |
|---|
| 95 |
except Exception, err: |
|---|
| 96 |
writeError(getLogger(), err, "Error while processing stdin") |
|---|
| 97 |
self.exitcode = 1 |
|---|
| 98 |
|
|---|
| 99 |
def main(self): |
|---|
| 100 |
|
|---|
| 101 |
self.exitcode = 0 |
|---|
| 102 |
if self.arguments: |
|---|
| 103 |
for filename in self.arguments: |
|---|
| 104 |
self.processFile(filename) |
|---|
| 105 |
else: |
|---|
| 106 |
self.processStdin() |
|---|
| 107 |
|
|---|
| 108 |
|
|---|
| 109 |
exit(self.exitcode) |
|---|
| 110 |
|
|---|