1 """Basic custom validators."""
2
3 __all__ = [
4 'Range',
5 'SpamBayesFilter',
6 'ValidFormat',
7 'ValidModelValue',
8 'ValidPasteGuid',
9 'ValidStyle',
10 ]
11
12 import logging
13 import socket
14 import xmlrpclib
15
16 from sqlalchemy.exceptions import InvalidRequestError
17 from turbogears import config, validators
18 from turbojson.jsonify import jsonify
19
20 from spammcan import model
21
22
23 log = logging.getLogger('spammcan.controllers')
24
25
27 """Check if given value is a valid key to an existing model object.
28 """
29
30 class_ = None
31 attr = 'id'
32 name = 'value'
33 convert_value = True
34
35 messages = {
36 'notExistant': u"There is no %(class_)s with the %(name)s '%(value)s'."
37 }
38
40 model_cls = getattr(model, self.class_ or '', None)
41 try:
42 if model_cls:
43 model_inst = model_cls.query.filter_by(
44 **{self.attr: value}).one()
45 else:
46 msg = u'Model class %s not found.' % self.class_
47 log.debug(msg)
48 raise ValueError(msg)
49 except (ValueError, InvalidRequestError), exc:
50 log.debug('Could not validate %s.%s == %r: %r',
51 self.class_, self.class_, value, exc)
52 raise validators.Invalid(self.message('notExistant', state,
53 class_=self.class_, name=self.name, value=value), value, state)
54 if self.convert_value:
55 return model_inst
56 else:
57 return value
58
64
70
76
77 -class Range(validators.FancyValidator):
78 messages = {
79 'invalid': u"Invalid range."
80 }
81
83 parts = value.split(':', 1)
84 try:
85 if len(parts) > 1:
86 return range(int(parts[0]), int(parts[1])+1)
87 else:
88 return [int(parts[0])]
89 except ValueError, exc:
90 raise validators.Invalid(self.message('invalid', state,
91 value=value), value, state)
92
94 """Check given value dict against SpamBayes xmlrpc server."""
95
96 __unpackargs__ = ['error_field']
97
98 sbrpc_url = 'http://localhost:8001/sbrpc'
99 spam_threshold = 0.8
100 default_score = 0.5
101
102 messages = {
103 'isSpam': u'Your form submission was rejected as spam.'
104 }
105
107 sbrpc_url = config.get('sbfilter.sbrpc_url', self.sbrpc_url)
108 sb_proxy = xmlrpclib.ServerProxy(sbrpc_url, allow_none=True)
109 try:
110 score = sb_proxy.score(self.convert_values(value), [], [])
111 except (socket.error, xmlrpclib.Error, TypeError), exc:
112 log.warning("SpamBayes XmlRPC call to 'score()' on '%s' failed: %r",
113 self.sbrpc_url, exc)
114 score = self.default_score
115 log.debug("SpamBayes score for value with keys %s: %.4f", value.keys(),
116 score)
117 if score >= self.spam_threshold:
118 msg = self.message('isSpam', state, value=value, score=score)
119 if self.error_field:
120 error_dict = {self.error_field: msg}
121 else:
122 error_dict = None
123 raise validators.Invalid(msg, value, state,
124 error_dict=error_dict)
125
127 if isinstance(values, dict):
128 result = dict()
129 for key, value in values.iteritems():
130 if isinstance(value, dict) or hasattr(value, '__iter__'):
131 result[key] = convert_values(value)
132 if type(value) not in xmlrpclib.Marshaller.dispatch.keys():
133 result[key] = jsonify(value)
134 else:
135 result[key] = value
136 elif hasattr(values, '__iter__'):
137 result = []
138 for value in values:
139 if isinstance(value, dict) or hasattr(values, '__iter__'):
140 result.append(convert_values(value))
141 elif type(value) not in xmlrpclib.Marshaller.dispatch.keys():
142 result.append(jsonify(value))
143 else:
144 result.append(value)
145 else:
146 result = value
147 return result
148