Package spammcan :: Package forms :: Module validators
[hide private]

Source Code for Module spammcan.forms.validators

  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   
26 -class ValidModelValue(validators.FancyValidator):
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
39 - def _to_python(self, value, state):
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
59 -class ValidPasteGuid(ValidModelValue):
60 class_ = 'Paste' 61 attr = 'guid' 62 name = 'GUID' 63 convert_value = True
64
65 -class ValidFormat(ValidModelValue):
66 class_ = 'Format' 67 attr = 'name' 68 name = 'name' 69 convert_value = True
70
71 -class ValidStyle(ValidModelValue):
72 class_ = 'Style' 73 attr = 'name' 74 name = 'name' 75 convert_value = True
76
77 -class Range(validators.FancyValidator):
78 messages = { 79 'invalid': u"Invalid range." 80 } 81
82 - def _to_python(self, value, state):
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
93 -class SpamBayesFilter(validators.FancyValidator):
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
106 - def validate_python(self, value, state):
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
126 - def convert_values(self, values, state=None):
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