#!/usr/bin/env python2.2

# version 0.0.1
# Author: Tjabo Kloppenburg, tk at  taponet.de
# Date  : 2002 Dec 01
# TISNOP is [not:)] a new mail filter written in python.

# TSNOP = This Is NOt Procmail

import re
import sys
import email

HEADER  = 1
DEVNULL = 2

class condition:
  def __init__( self, name, ctype, field, regexp ):
    self.name   = name
    self.ctype  = ctype
    self.field  = field
    self.regexp = regexp

  def test( self ):        # @@@999 too simple
    if (self.ctype == HEADER) and (len(self.field) == 0):
      print "header field name missing!"
      return 0
    return 1

# -----------------------------------------------------

class action:
  def __init__( self, name, atype, field, value ):
    self.name   = name
    self.atype  = atype
    self.field  = field
    self.value  = value

  def test( self ):
    return 1               # @@@999 test missing
# -----------------------------------------------------

class rule:
  def __init__( self, name, conditions, actions ):
    self.name   = name
    self.conditions = conditions
    self.actions    = actions
# -----------------------------------------------------

class tisnop:

  def __init__( self, content ):
    self.errors = []
    try:
      self.msg   = email.Parser.Parser().parsestr( content )
    except email.Errors.BoundaryError, m:
      self.errors.append( m )
      print m
      self.msg = None
    self.rules = []

  def getHeaderField( self, fieldName, default="" ):
    return self.msg.get( fieldName, default )

  def getPlaceholder( self, p, default="" ):
    if p == "%S": return self.getHeaderField( "Subject", default )
    if p == "%F": return self.getHeaderField( "From"   , default )
    if p == "%T": return self.getHeaderField( "To"     , default )
    if p == "%C": return self.getHeaderField( "Content-type", default )
    if p == "%D": return self.getHeaderField( "Date"   , default )
    return "unknown placeholder '%s'" % ( p )

  def insertPlaceholders( self, txt ):
    r = re.compile("(%[SFTCD])")
    max = 100
    erg = ""
    g = r.search( txt )
    while g and (max > 0):
      txt_pre = txt[ 0 : g.start()]
      txt_erp = txt[ g.end() : ]
      erg = erg + txt_pre
      erg = erg + self.getPlaceholder( g.group(1) )
      txt = txt_erp
      max -= 1
      g = r.search( txt )
    if not g:
      erg += txt
    return erg

  def addRule( self, name, conditions, actions ):
    a_rule = rule( name, conditions, actions )
    self.rules.append( a_rule )

  def action( self ):
    action_delete_message = 0
    
    if not self.msg:
      print self.errors
      return 0

    if self.msg.is_multipart():  # @@@999 not supported in this version
      print self.msg
      return 0

    a_rule_matched = 0
    num_rules = len( self.rules )
    i = 0
    while (i < num_rules ) and ( a_rule_matched == 0 ):
      a_rule = self.rules[ i ]
      conditions = a_rule.conditions
      num_matched_conditions = 0

      num_conditions = len( conditions )
      j = 0
      while (j < num_conditions ):
        con = conditions[ j ]
        if con.ctype == HEADER:
          val = self.msg.get( con.field, "" )
          if con.regexp.search( val ):
            num_matched_conditions += 1
        j += 1
        # end WHILE j

      if num_matched_conditions == num_conditions:
        a_rule_matched = 1
      else:
        i += 1
      # end WHILE i

    if a_rule_matched:
      matched_rule = self.rules[i]
      print "a rule matched:", matched_rule.name # actions = self.rules[ i ][1]
      actions = matched_rule.actions
      for a in actions:
        print " Action:", a.name
        if a.atype == HEADER:   # alter HEADER
          val = self.insertPlaceholders( a.value )
          del self.msg[ a.field ]
          self.msg[ a.field ] = val
        if a.atype == IDEVNULL: # forget mail :-)
          vaction_delete_message = 1
    else:
      print " no rule matched."

    if not action_delete_message:
      print self.msg

# -----------------------------------------------------

