Edgewall Software

Ticket #4087: spamfilter_log-base64content-r5329.diff

File spamfilter_log-base64content-r5329.diff, 5.7 kB (added by cboos, 16 months ago)

Encode content to base64 before storing it in the db

  • tracspamfilter/model.py

     
    1111# individuals. For the exact contribution history, see the revision 
    1212# history and logs, available at http://projects.edgewall.com/trac/. 
    1313 
     14import binascii 
     15 
    1416from datetime import datetime, timedelta 
    1517from time import mktime 
    1618 
    1719from trac.db import Column, Index, Table 
     20from trac.util.text import to_unicode 
    1821 
    1922__all__ = ['LogEntry'] 
    2023 
     
    6669    exists = property(fget=lambda self: self.id is not None, 
    6770                      doc='Whether this log entry exists in the database') 
    6871 
     72    def _encode_content(cls, content): 
     73        """Take a `basestring` content and return a plain text encoding.""" 
     74        return to_unicode(content).encode('utf-8').encode('base64') 
     75 
     76    _encode_content = classmethod(_encode_content) 
     77 
     78    def _decode_content(cls, content): 
     79        """Revert the encoding done by `_encode_content` and return an unicode 
     80        string""" 
     81        try: 
     82            return to_unicode(content.decode('base64')) 
     83        except (UnicodeEncodeError, binascii.Error): 
     84            # cope with legacy content (stored before base64 encoding) 
     85            return to_unicode(content) 
     86 
     87    _decode_content = classmethod(_decode_content) 
     88 
    6989    def get_next(self, db=None): 
    7090        """Return the next log entry in reverse chronological order (i.e. the 
    7191        next older entry.)""" 
     
    7999        row = cursor.fetchone() 
    80100        if not row: 
    81101            return None 
     102        return self.__class__._from_db(self.env, row) 
    82103 
    83         obj = self.__class__(self.env, *row[1:]) 
    84         obj.id = row[0] 
    85         return obj 
    86  
    87104    def get_previous(self, db=None): 
    88         """Return the previous log entry in reverse chronological order (i.e. the 
    89         next younger entry.)""" 
     105        """Return the previous log entry in reverse chronological order 
     106        (i.e. the next younger entry.)""" 
    90107        if not db: 
    91108            db = self.env.get_db_cnx() 
    92109 
     
    97114        row = cursor.fetchone() 
    98115        if not row: 
    99116            return None 
     117        return self.__class__._from_db(self.env, row) 
    100118 
    101         obj = self.__class__(self.env, *row[1:]) 
    102         obj.id = row[0] 
    103         return obj 
    104  
    105119    def insert(self, db=None): 
    106120        """Insert a new log entry into the database.""" 
    107121        if not db: 
     
    112126 
    113127        assert not self.exists, 'Cannot insert existing log entry' 
    114128 
     129        content = self._encode_content(self.content) 
     130 
    115131        cursor = db.cursor() 
    116132        cursor.execute("INSERT INTO spamfilter_log (time,path,author," 
    117133                       "authenticated,ipnr,headers,content,rejected," 
    118134                       "karma,reasons) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s," 
    119135                       "%s)", (int(self.time), self.path, self.author, 
    120136                       int(bool(self.authenticated)), self.ipnr, self.headers, 
    121                        self.content, int(bool(self.rejected)), int(self.karma), 
     137                       content, int(bool(self.rejected)), int(self.karma), 
    122138                       '\n'.join(self.reasons))) 
    123139        self.id = db.get_last_id(cursor, 'spamfilter_log') 
    124140        if handle_ta: 
     
    138154            if hasattr(self, name): 
    139155                setattr(self, name, value) 
    140156 
     157        content = self._encode_content(self.content) 
     158         
    141159        cursor = db.cursor() 
    142160        cursor.execute("UPDATE spamfilter_log SET time=%s,path=%s,author=%s," 
    143161                       "authenticated=%s,ipnr=%s,headers=%s,content=%s," 
    144162                       "rejected=%s,karma=%s,reasons=%s WHERE id=%s", ( 
    145163                       int(self.time), self.path, self.author, 
    146164                       int(bool(self.authenticated)), self.ipnr, self.headers, 
    147                        self.content, int(bool(self.rejected)), int(self.karma), 
     165                       content, int(bool(self.rejected)), int(self.karma), 
    148166                       '\n'.join(self.reasons), self.id)) 
    149167        if handle_ta: 
    150168            db.commit() 
     
    170188            db = env.get_db_cnx() 
    171189 
    172190        cursor = db.cursor() 
    173         cursor.execute("SELECT time,path,author,authenticated,ipnr,headers," 
     191        cursor.execute("SELECT id,time,path,author,authenticated,ipnr,headers," 
    174192                       "content,rejected,karma,reasons FROM spamfilter_log " 
    175193                       "WHERE id=%s", (int(id),)) 
    176194        row = cursor.fetchone() 
    177195        if not row: 
    178196            return None 
     197        return cls._from_db(env, row) 
    179198 
    180         obj = cls(env, *row) 
    181         obj.id = id 
    182         return obj 
    183  
    184199    fetch = classmethod(fetch) 
    185200 
    186201    def count(cls, env, db=None): 
     
    247262                       "content,rejected,karma,reasons FROM spamfilter_log " 
    248263                       "%s ORDER BY time DESC %s" % (where, extra), params) 
    249264        for row in cursor: 
    250             obj = cls(env, *row[1:]) 
    251             obj.id = row[0] 
    252             yield obj 
     265            yield cls._from_db(env, row) 
    253266 
    254267    select = classmethod(select) 
    255268 
     269    def _from_db(cls, env, row): 
     270        """Create a new LogEntry from a row from the `spamfilter_log` table.""" 
     271        fields = list(row[1:]) 
     272        fields[6] = cls._decode_content(fields[6]) 
     273        obj = cls(env, *fields) 
     274        obj.id = row[0] 
     275        return obj 
    256276 
     277    _from_db = classmethod(_from_db) 
     278 
    257279class Bayes(object): 
    258280 
    259281    table = Table('spamfilter_bayes', key='word')[ 
  • setup.py

     
    1515from setuptools import setup, find_packages 
    1616 
    1717PACKAGE = 'TracSpamFilter' 
    18 VERSION = '0.2' 
     18VERSION = '0.2.1' 
    1919 
    2020setup( 
    2121    name = PACKAGE,