Changeset 17737
- Timestamp:
- Oct 30, 2023, 12:26:06 PM (9 months ago)
- Location:
- plugins/trunk/spam-filter
- Files:
-
- 14 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
plugins/trunk/spam-filter/setup.py
r17736 r17737 52 52 extras_require={ 53 53 'dns': ['dnspython>=1.3.5'], 54 54 55 #'spambayes': ['spambayes'], 55 56 'pillow': ['pillow>=2'], … … 72 73 spamfilter.botscout = tracspamfilter.filters.botscout 73 74 spamfilter.fspamlist = tracspamfilter.filters.fspamlist 74 spamfilter.bayes = tracspamfilter.filters.bayes [spambayes]75 spamfilter.bayes = tracspamfilter.filters.bayes 75 76 spamfilter.extlinks = tracspamfilter.filters.extlinks 76 77 spamfilter.httpbl = tracspamfilter.filters.httpbl[dns] -
plugins/trunk/spam-filter/spambayes_/Options.py
r17736 r17737 28 28 29 29 # Grab the stuff from the core options class. 30 from spambayes .OptionsClass import *30 from spambayes.OptionsClass import * 31 31 32 32 # A little magic. We'd like to use ZODB as the default storage, -
plugins/trunk/spam-filter/spambayes_/__init__.py
r17736 r17737 3 3 import pkg_resources 4 4 5 __version__ = "3.1.0 internal"5 __version__ = "3.1.0 " 6 6 __date__ = "June 2, 2022" -
plugins/trunk/spam-filter/spambayes_/chi2.py
r17736 r17737 91 91 92 92 def main(): 93 from spambayes .Histogram import Hist93 from spambayes.Histogram import Hist 94 94 import sys 95 95 -
plugins/trunk/spam-filter/spambayes_/classifier.py
r17736 r17737 56 56 # XXX ---- ends ---- 57 57 58 from spambayes .Options import options59 from spambayes .chi2 import chi2Q60 from spambayes .safepickle import pickle_read, pickle_write58 from spambayes.Options import options 59 from spambayes.chi2 import chi2Q 60 from spambayes.safepickle import pickle_read, pickle_write 61 61 62 62 LN2 = math.log(2) # used frequently by chi-combining … … 547 547 # XXX Someone smarter than me, please figure out the right 548 548 # XXX way to do this. 549 from spambayes .FileCorpus import ExpiryFileCorpus, FileMessageFactory549 from spambayes.FileCorpus import ExpiryFileCorpus, FileMessageFactory 550 550 551 551 username = options["globals", "proxy_username"] … … 644 644 return ["url:non_resolving"] 645 645 646 from spambayes .tokenizer import Tokenizer646 from spambayes.tokenizer import Tokenizer 647 647 648 648 if options["URLRetriever", "x-only_slurp_base"]: -
plugins/trunk/spam-filter/spambayes_/mboxutils.py
r17736 r17737 119 119 120 120 from scripts.sb_imapfilter import IMAPSession, IMAPFolder 121 from spambayes import Stats, message122 from spambayes .Options import options121 from spambayes import Stats, message 122 from spambayes.Options import options 123 123 124 124 sesion = IMAPSession(parts['server']) -
plugins/trunk/spam-filter/spambayes_/safepickle.py
r17736 r17737 13 13 import filelock 14 14 15 from spambayes .Options import options15 from spambayes.Options import options 16 16 17 17 def pickle_read(filename): -
plugins/trunk/spam-filter/spambayes_/tokenizer.py
r17736 r17737 16 16 import urllib.request, urllib.parse, urllib.error 17 17 18 from spambayes import classifier19 from spambayes .Options import options20 21 from spambayes .mboxutils import get_message18 from spambayes import classifier 19 from spambayes.Options import options 20 21 from spambayes.mboxutils import get_message 22 22 23 23 try: 24 from spambayes import dnscache24 from spambayes import dnscache 25 25 cache = dnscache.cache(cachefile=options["Tokenizer", "lookup_ip_cache"]) 26 26 cache.printStatsAtEnd = False … … 1623 1623 if options["Tokenizer", "crack_images"]: 1624 1624 engine_name = options["Tokenizer", 'ocr_engine'] 1625 from spambayes .ImageStripper import crack_images1625 from spambayes.ImageStripper import crack_images 1626 1626 text, tokens = crack_images(engine_name, parts) 1627 1627 for t in tokens: -
plugins/trunk/spam-filter/tracspamfilter/admin.py
r17736 r17737 106 106 }) 107 107 add_script(req, 'spamfilter/adminmonitor.js') 108 add_script_data(req, {'toggleform': 'spammonitorform'})109 108 110 109 add_stylesheet(req, 'spamfilter/admin.css') -
plugins/trunk/spam-filter/tracspamfilter/adminreport.py
r17729 r17737 16 16 from trac.core import Component, implements 17 17 from trac.web.api import HTTPNotFound 18 from trac.web.chrome import ( 19 add_link, add_script, add_script_data, add_stylesheet) 18 from trac.web.chrome import add_link, add_stylesheet 20 19 21 20 from tracspamfilter.api import _ … … 113 112 _('Next Page')) 114 113 115 if entries:116 add_script_data(req, {'toggleform': "spamreportform"})117 114 return { 118 115 'entries': entries, -
plugins/trunk/spam-filter/tracspamfilter/filters/bayes.py
r17736 r17737 22 22 from tracspamfilter.api import IFilterStrategy, N_ 23 23 24 from spambayes.classifier import Classifier 25 from spambayes.tokenizer import tokenize 24 try: 25 from spambayes.classifier import Classifier 26 from spambayes.tokenizer import tokenize 27 except ImportError: # not installed, use internal copy 28 from spambayes_.classifier import Classifier 29 from spambayes_.tokenizer import tokenize 26 30 27 31 class BayesianFilterStrategy(Component): … … 104 108 105 109 def get_system_info(self): 106 import spambayes 107 yield 'SpamBayes', get_pkginfo(spambayes)['version'] 110 try: 111 import spambayes 112 yield 'SpamBayes', get_pkginfo(spambayes)['version'] 113 except ImportError: # not installed, use internal copy 114 import spambayes_ 115 yield 'SpamBayes', spambayes_.__version__ 108 116 109 117 # Internal methods -
plugins/trunk/spam-filter/tracspamfilter/filters/trapfield.py
r17733 r17737 53 53 anchors = { 54 54 'wiki_edit_form.html': '<input type="submit" id="save" name="save" ', 55 'ticket.html': '<input type="submit" name="submit"' 55 'ticket.html': '<input type="submit" name="submit"', 56 'prefs.html': '<input type="hidden" name="action" value="save"' 56 57 # missing /register (accountmanager) 57 58 } -
plugins/trunk/spam-filter/tracspamfilter/templates/admin_user.html
r16685 r17737 1 <!DOCTYPE html 2 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 4 <html xmlns="http://www.w3.org/1999/xhtml" 5 xmlns:xi="http://www.w3.org/2001/XInclude" 6 xmlns:py="http://genshi.edgewall.org/" 7 xmlns:i18n="http://genshi.edgewall.org/i18n" i18n:domain="tracspamfilter"> 8 <xi:include href="admin.html" /> 1 {# Copyright (C) 2023 Dirk Stöcker 2 3 This software is licensed as described in the file COPYING, which 4 you should have received as part of this distribution. The terms 5 are also available at https://trac.edgewall.org/wiki/TracLicense. 6 7 This software consists of voluntary contributions made by many 8 individuals. For the exact contribution history, see the revision 9 history and logs, available at https://trac.edgewall.org/. 10 #} 11 # extends 'admin.html' 12 <!DOCTYPE html> 13 <html> 9 14 <head> 10 <title>Spam User Handling</title> 15 <title> 16 # block admintitle 17 ${_("Spam User Handling")} 18 # endblock admintitle 19 </title> 11 20 </head> 12 21 13 22 <body> 14 <h2 i18n:msg="type, count">Spam Filtering: User handling (${usertype}) 15 <span class="entryinfo" py:if="stats">${entrytext}</span> 23 # block adminpanel 24 <h2>${_("Spam Filtering: User handling (%(type)s)") % {'type': usertype}} 25 # if stats: 26 <span class="entryinfo">${entrytext}</span> 27 # endif 16 28 </h2> 17 29 18 30 <div class="nav"> 19 31 <ul> 20 <li class="first"><a href="user?mode=overview">Overview</a></li> 21 <li><a href="user?mode=all">All</a></li> 22 <li><a href="user?mode=authorized">Registered</a></li> 23 <li py:if="accmgr"><a href="user?mode=unusedmulti">Unused [multi selection]</a></li> 24 <li class="last"><a href="user?mode=unused">Unused</a></li> 32 <li class="first"><a href="user?mode=overview">${_("Overview")}</a></li> 33 <li><a href="user?mode=all">${_("All")}</a></li> 34 <li><a href="user?mode=authorized">${_("Registered")}</a></li> 35 # if accmgr: 36 <li><a href="user?mode=unusedmulti">${_("Unused [multi selection]")}</a></li> 37 # endif 38 <li class="last"><a href="user?mode=unused">${_("Unused")}</a></li> 25 39 </ul> 26 40 </div> 27 41 28 <div py:if="stats" i18n:msg="total, registered, unused">There are ${stats['numtotal']} 29 different entries in the database, ${stats['numauthorized']} users are 30 registered and ${stats['numunused']} have not been used.</div> 42 # if stats: 43 <div> 44 ${_("There are %(total)s different entries in the database, %(registered)s users are registered and %(unused)s have not been used.") 45 % {'total': stats['numtotal'], 'registered': stats['numauthorized'], 'unused': stats['numunused']}}</div> 46 # endif 31 47 32 <table class="listing" id="userinfo" py:if="username"> 48 # if username: 49 <table class="listing" id="userinfo"> 33 50 <thead> 34 51 <tr> 35 <th> Date</th>36 <th i18n:msg="username">Action of user '${username}'</th>52 <th></th> 53 <th</th> 37 54 </tr> 38 55 </thead> 39 56 <tbody> 40 <py:for each="date, link, action in user"> 41 <tr> 42 <td>${format_datetime(date) if date else "-"}</td> 43 <td py:if="link"><a href="${href(link)}">${action}</a></td> 44 <td py:if="not link">${action}</td> 45 </tr> 46 </py:for> 57 # for date, link, action in user: 58 <tr> 59 <td>${format_datetime(date) if date else "-"}</td> 60 # if link: 61 <td><a href="${href(link)}">${action}</a></td> 62 # else: 63 <td>${action}</td> 64 #endif 65 </tr> 66 # endfor 47 67 </tbody> 48 68 </table> 49 <py:choose test="accmgr and mode == 'unusedmulti'"> 50 <py:when test="True"> 51 <form action="${href.admin('accounts/users')}" method="post"> 52 <xi:include href="usertable.html" /> 53 <div class="buttons"> 54 <input type="hidden" name="mode" value="$mode" /> 55 <input class="dangerbutton" type="submit" name="remove" 56 value="${dgettext('tracspamfilter', 'Remove selected')}" /> 57 </div> 58 </form> 59 </py:when> 60 <py:otherwise><xi:include href="usertable.html" /></py:otherwise> 61 </py:choose> 69 # endif 70 # if accmgr and mode == 'unusedmulti': 71 <script type="text/javascript"> 72 jQuery(function($) { 73 $("#userform").addSelectAllCheckboxes(); 74 }); 75 </script> 76 <form id="userform" method="post" action="${href.admin('accounts/users')}"> 77 ${jmacros.form_token_input()} 78 # include 'usertable.html' 79 <div class="buttons"> 80 <input type="hidden" name="mode" value="$mode" /> 81 # if users: 82 <input class="dangerbutton" type="submit" name="remove" 83 value="${_('Remove selected')}" /> 84 # endif 85 </div> 86 </form> 87 # else: 88 # include 'usertable.html' 89 # endif 62 90 63 91 <form method="post" action=""> 64 <h4 py:if="encoded">Values must be URL encoded!</h4> 92 ${jmacros.form_token_input()} 93 # if encoded: 94 <h4>${_("Values must be URL encoded!")}</h4> 95 #endif 65 96 <div class="buttons"> 66 <label> Old user:97 <label> 67 98 <input type="text" id="userold" name="userold" size="30" value="" /> 68 99 </label> 69 <label> New user:100 <label> 70 101 <input type="text" id="usernew" name="usernew" size="30" value="" /> 71 102 </label> 72 103 <input type="hidden" name="mode" value="$mode" /> 73 <input py:if="encoded" type="hidden" name="encoded" value="1" /> 74 <input py:if="auth" type="hidden" name="auth" value="$auth" /> 75 <input type="submit" name="changeuser" value="${dgettext('tracspamfilter', 'Change unauthorized user') 76 if not auth else dgettext('tracspamfilter', 'Change user')}" /> 104 # if encoded: 105 <input type="hidden" name="encoded" value="1" /> 106 # endif 107 # if auth: 108 <input type="hidden" name="auth" value="$auth" /> 109 # endif 110 <input type="submit" name="changeuser" value="${_('Change unauthorized user') 111 if not auth else _('Change user')}" /> 77 112 </div> 78 113 </form> … … 80 115 <div class="buttons"> 81 116 <form method="post" action=""><div> 117 82 118 <input type="hidden" name="mode" value="$mode" /> 83 <input type="submit" name="cleantemp" value="${ dngettext('tracspamfilter','Remove %(num)s temporary session',119 <input type="submit" name="cleantemp" value="${'Remove %(num)s temporary session', 84 120 'Remove %(num)s temporary sessions', tempcount)}" /> 85 121 </div></form> 86 122 <form method="post" action=""><div> 123 87 124 <input type="hidden" name="mode" value="$mode" /> 88 <input type="submit" name="fixemails" value="${ dgettext('tracspamfilter','Convert emails to registered usernames')}" />125 <input type="submit" name="fixemails" value="${'Convert emails to registered usernames')}" /> 89 126 </div></form> 90 127 </div> 91 128 # endblock adminpanel 92 129 </body> 93 94 130 </html> -
plugins/trunk/spam-filter/tracspamfilter/templates/usertable.html
r17728 r17737 1 <!DOCTYPE html 2 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 4 <html xmlns="http://www.w3.org/1999/xhtml" 5 xmlns:xi="http://www.w3.org/2001/XInclude" 6 xmlns:py="http://genshi.edgewall.org/" 7 xmlns:i18n="http://genshi.edgewall.org/i18n" i18n:domain="tracspamfilter" 8 py:strip=""> 9 <table class="listing" id="userstatistics" py:if="len(users)"> 1 {# Copyright (C) 2023 Dirk Stöcker 2 3 This software is licensed as described in the file COPYING, which 4 you should have received as part of this distribution. The terms 5 are also available at https://trac.edgewall.org/wiki/TracLicense. 6 7 This software consists of voluntary contributions made by many 8 individuals. For the exact contribution history, see the revision 9 history and logs, available at https://trac.edgewall.org/. 10 #} 11 # if len(users): 12 <table class="listing" id="userstatistics"> 10 13 <thead> 11 14 <tr> 12 <th py:if="accmgr and mode == 'unusedmulti'"> </th> 13 <th>User name</th> 14 <th>Last login</th> 15 <th>Registered</th> 16 <th>Setup</th> 17 <th>E-Mail</th> 18 <th>Wiki edits</th> 19 <th>Ticket edits</th> 20 <th>SVN edits</th> 21 <th>Other</th> 22 <th py:if="accmgr and mode == 'unused'"> </th> 15 # if accmgr and mode == 'unusedmulti': 16 <th class="sel"> </th> 17 # endif 18 <th>${_("User name")}</th> 19 <th>${_("Last login")}</th> 20 <th>${_("Registered")}</th> 21 <th>${_("Setup")}</th> 22 <th>${_("E-Mail")}</th> 23 <th>${_("Wiki edits")}</th> 24 <th>${_("Ticket edits")}</th> 25 <th>${_("SVN edits")}</th> 26 <th>${_("Other")}</th> 27 # if accmgr and mode == 'unused': 28 <th> </th> 29 # endif 23 30 </tr> 24 31 </thead> 25 32 <tbody> 26 <py:for each="name, data in sorted(users.iteritems())">33 27 34 <tr> 28 <td py:if="accmgr and mode == 'unusedmulti'"> 29 <py:if test="not curtime-data[0] > maxage"> </py:if> 30 <input py:if="curtime-data[0] > maxage" type="checkbox" name="sel" value="${name}" /> 35 # if accmgr and mode == 'unusedmulti': 36 <td class="sel"> 37 # if curtime-data[0] > maxage: 38 <input type="checkbox" name="sel" value="${name}" /> 39 # else: 40 41 # endif 31 42 </td> 43 32 44 <td> 33 45 <a href="user?mode=user&user=${quote(name.encode('utf-8'))}">${name}</a> 34 <span class="username" py:if="data[12]">(${data[12]})</span> 46 # if data[12]: 47 <span class="username">(${data[12]})</span> 48 # endif 35 49 </td> 36 <py:if test="data[0]"> 37 <py:choose test="data[1]"> 38 <py:when test="0"> 39 <td><a href="${data[0]}">Source</a></td> 40 </py:when> 41 <py:otherwise> 42 <td class="${'inactive' if curtime-data[0] > maxage else 'active'}">${format_datetime(data[0])}</td> 43 </py:otherwise> 44 </py:choose> 45 </py:if> 46 <py:if test="not data[0]"><td>-</td></py:if> 47 <py:if test="data[1]"><td class="active">yes</td></py:if> 48 <py:if test="not data[1]"><td>no</td></py:if> 49 <py:if test="data[2]"><td class="active">yes<span class="entrypassword" py:if="data[14]">(password)</span></td></py:if> 50 <py:if test="not data[2]"><td>no<span class="entrypassword" py:if="data[14]">(password)</span></td></py:if> 50 # if data[0]: 51 # if data[1]: 52 <td class="${'inactive' if curtime-data[0] > maxage else 'active'}">${format_datetime(data[0])}</td> 53 # else: 54 <td><a href="${data[0]}">${_("Source")}</a></td> 55 # endif 56 # else: 57 <td>-</td> 58 # endif 59 # if data[1]: 60 <td class="active">${_("yes")}</td> 61 # else: 62 <td>${_("no")}</td> 63 # endif 64 # if data[2]: 65 <td class="active">${_("yes")} 66 # else: 67 <td>${_("no")} 68 #endif 69 # if data[14]: 70 <span class="entrypassword" py:if="data[14]">${_("(password)")}</span> 71 # endif 72 </td> 51 73 <td>${data[3] if data[3] else '-'} 52 <py:if test="data[13]"><span class="doublemail" title="${data[13]}"> (double)</span></py:if> 74 # if data[13]: 75 <span class="doublemail" title="${data[13]}"> ${_("(double)")}</span> 76 # endif 53 77 </td> 54 <py:choose test="data[4]"> 55 <py:when test="1"><td class="asuser">user <py:if test="data[5]"> (${data[5]})</py:if></td></py:when> 56 <py:when test="2"><td class="${'asmailonly' if data[3] == name else 'asmail'}">e-mail <py:if test="data[5]"> (${data[5]})</py:if></td></py:when> 57 <py:when test="3"><td class="asboth">both <py:if test="data[5]"> (${data[5]})</py:if></td></py:when> 58 <py:otherwise><td>-</td></py:otherwise> 59 </py:choose> 60 <py:choose test="data[6]"> 61 <py:when test="1"><td class="asuser">user <py:if test="data[7]"> (${data[7]})</py:if></td></py:when> 62 <py:when test="2"><td class="${'asmailonly' if data[3] == name else 'asmail'}">e-mail <py:if test="data[7]"> (${data[7]})</py:if></td></py:when> 63 <py:when test="3"><td class="asboth">both <py:if test="data[7]"> (${data[7]})</py:if></td></py:when> 64 <py:otherwise><td>-</td></py:otherwise> 65 </py:choose> 66 <py:choose test="data[8]"> 67 <py:when test="1"><td class="asuser">user <py:if test="data[9]"> (${data[9]})</py:if></td></py:when> 68 <py:when test="2"><td class="${'asmailonly' if data[3] == name else 'asmail'}">e-mail <py:if test="data[9]"> (${data[9]})</py:if></td></py:when> 69 <py:when test="3"><td class="asboth">both <py:if test="data[9]"> (${data[9]})</py:if></td></py:when> 70 <py:otherwise><td>-</td></py:otherwise> 71 </py:choose> 72 <py:choose test="data[10]"> 73 <py:when test="1"><td class="asuser">user <py:if test="data[11]"> (${data[11]})</py:if></td></py:when> 74 <py:when test="2"><td class="asmail">e-mail <py:if test="data[11]"> (${data[11]})</py:if></td></py:when> 75 <py:when test="3"><td class="asboth">both <py:if test="data[11]"> (${data[11]})</py:if></td></py:when> 76 <py:otherwise><td>-</td></py:otherwise> 77 </py:choose> 78 <td py:if="accmgr and mode == 'unused'"> 79 <py:if test="not curtime-data[0] > maxage"> </py:if> 80 <form py:if="curtime-data[0] > maxage" action="${href.admin('accounts/users')}" method="post"> 78 # if data[4] == 1: 79 <td class="asuser">${_("user")} 80 # if data[5]: 81 (${data[5]}) 82 # endif 83 </td> 84 # elif data[4] == 2: 85 <td class="${'asmailonly' if data[3] == name else 'asmail'}">${_("e-mail")} 86 # if data[5]: 87 (${data[5]}) 88 # endif 89 </td> 90 # elif data[4] == 3: 91 <td class="asboth">${_("both")} 92 # if data[5]: 93 (${data[5]}) 94 # endif 95 </td> 96 # else: 97 <td>-</td> 98 # endif 99 # if data[6] == 1: 100 <td class="asuser">${_("user")} 101 # if data[7]: 102 (${data[7]}) 103 # endif 104 </td> 105 # elif data[6] == 2: 106 <td class="${'asmailonly' if data[3] == name else 'asmail'}">${_("e-mail")} 107 # if data[7]: 108 (${data[7]}) 109 # endif 110 </td> 111 # elif data[6] == 3: 112 <td class="asboth">${_("both")} 113 # if data[7]: 114 (${data[7]}) 115 # endif 116 </td> 117 # else: 118 <td>-</td> 119 # endif 120 # if data[8] == 1: 121 <td class="asuser">${_("user")} 122 # if data[9]: 123 (${data[9]}) 124 # endif 125 </td> 126 # elif data[8] == 2: 127 <td class="${'asmailonly' if data[3] == name else 'asmail'}">${_("e-mail")} 128 # if data[9]: 129 (${data[9]}) 130 # endif 131 </td> 132 # elif data[8] == 3: 133 <td class="asboth">${_("both")} 134 # if data[9]: 135 (${data[9]}) 136 # endif 137 </td> 138 # else: 139 <td>-</td> 140 # endif 141 # if data[10] == 1: 142 <td class="asuser">${_("user")} 143 # if data[11]: 144 (${data[11]}) 145 # endif 146 </td> 147 # elif data[10] == 2: 148 <td class="${'asmailonly' if data[3] == name else 'asmail'}">${_("e-mail")} 149 # if data[11]: 150 (${data[11]}) 151 # endif 152 </td> 153 # elif data[10] == 3: 154 <td class="asboth">${_("both")} 155 # if data[11]: 156 (${data[11]}) 157 # endif 158 </td> 159 # else: 160 <td>-</td> 161 # endif 162 # if accmgr and mode == 'unused': 163 <td> 164 # if curtime-data[0] > maxage: 165 <form action="${href.admin('accounts/users')}" method="post"> 81 166 <div> 82 167 <input type="hidden" name="sel" value="${name}" /> 83 <input class="dangerbutton" type="submit" name="remove" value="${ dgettext('tracspamfilter','Remove')}" />168 <input class="dangerbutton" type="submit" name="remove" value="${'Remove')}" /> 84 169 </div> 85 170 </form> 171 172 173 86 174 </td> 175 87 176 </tr> 88 </py:for>177 89 178 </tbody> 90 179 </table> 91 </html> 180 #endif
Note:
See TracChangeset
for help on using the changeset viewer.