home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 June / maximum-cd-2009-06.iso / DiscContents / digsby_setup.exe / lib / lxml / html / formfill.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-02-26  |  8.8 KB  |  335 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from lxml.etree import XPath, ElementBase
  5. from lxml.html import fromstring, tostring, XHTML_NAMESPACE
  6. from lxml.html import _forms_xpath, _options_xpath, _nons, _transform_result
  7. from lxml.html import defs
  8.  
  9. try:
  10.     basestring = __builtins__['basestring']
  11. except (KeyError, NameError):
  12.     basestring = str
  13.  
  14. __all__ = [
  15.     'FormNotFound',
  16.     'fill_form',
  17.     'fill_form_html',
  18.     'insert_errors',
  19.     'insert_errors_html',
  20.     'DefaultErrorCreator']
  21.  
  22. class FormNotFound(LookupError):
  23.     pass
  24.  
  25. _form_name_xpath = XPath('descendant-or-self::form[name=$name]|descendant-or-self::x:form[name=$name]', namespaces = {
  26.     'x': XHTML_NAMESPACE })
  27. _input_xpath = []([]([ 'descendant-or-self::' + _tag for _tag in ('input', 'select', 'textarea', 'x:input', 'x:select', 'x:textarea') ]), namespaces = {
  28.     'x': XHTML_NAMESPACE })
  29. _label_for_xpath = XPath('//label[@for=$for_id]|//x:label[@for=$for_id]', namespaces = {
  30.     'x': XHTML_NAMESPACE })
  31. _name_xpath = XPath('descendant-or-self::*[@name=$name]')
  32.  
  33. def fill_form(el, values, form_id = None, form_index = None):
  34.     el = _find_form(el, form_id = form_id, form_index = form_index)
  35.     _fill_form(el, values)
  36.  
  37.  
  38. def fill_form_html(html, values, form_id = None, form_index = None):
  39.     result_type = type(html)
  40.     if isinstance(html, basestring):
  41.         doc = fromstring(html)
  42.     else:
  43.         doc = copy.deepcopy(html)
  44.     fill_form(doc, values, form_id = form_id, form_index = form_index)
  45.     return _transform_result(result_type, doc)
  46.  
  47.  
  48. def _fill_form(el, values):
  49.     counts = { }
  50.     if hasattr(values, 'mixed'):
  51.         values = values.mixed()
  52.     
  53.     inputs = _input_xpath(el)
  54.     for input in inputs:
  55.         name = input.get('name')
  56.         if not name:
  57.             continue
  58.         
  59.         if _takes_multiple(input):
  60.             value = values.get(name, [])
  61.             if not isinstance(value, (list, tuple)):
  62.                 value = [
  63.                     value]
  64.             
  65.             _fill_multiple(input, value)
  66.             continue
  67.         if name not in values:
  68.             continue
  69.             continue
  70.         index = counts.get(name, 0)
  71.         counts[name] = index + 1
  72.         value = values[name]
  73.         if isinstance(value, (list, tuple)):
  74.             
  75.             try:
  76.                 value = value[index]
  77.             except IndexError:
  78.                 continue
  79.             except:
  80.                 None<EXCEPTION MATCH>IndexError
  81.             
  82.  
  83.         None<EXCEPTION MATCH>IndexError
  84.         if index > 0:
  85.             continue
  86.         
  87.         _fill_single(input, value)
  88.     
  89.  
  90.  
  91. def _takes_multiple(input):
  92.     if _nons(input.tag) == 'select' and input.get('multiple'):
  93.         return True
  94.     
  95.     type = input.get('type', '').lower()
  96.     if type in ('radio', 'checkbox'):
  97.         return True
  98.     
  99.     return False
  100.  
  101.  
  102. def _fill_multiple(input, value):
  103.     type = input.get('type', '').lower()
  104.     if type == 'checkbox':
  105.         v = input.get('value')
  106.         if v is None:
  107.             if not value:
  108.                 result = False
  109.             else:
  110.                 result = value[0]
  111.                 if isinstance(value, basestring):
  112.                     result = result == 'on'
  113.                 
  114.             _check(input, result)
  115.         else:
  116.             _check(input, v in value)
  117.     elif type == 'radio':
  118.         v = input.get('value')
  119.         _check(input, v in value)
  120.     else:
  121.         for option in _options_xpath(input):
  122.             v = option.get('value')
  123.             if v is None:
  124.                 v = option.text_content()
  125.             
  126.             _select(option, v in value)
  127.         
  128.  
  129.  
  130. def _check(el, check):
  131.     if check:
  132.         el.set('checked', '')
  133.     elif 'checked' in el.attrib:
  134.         del el.attrib['checked']
  135.     
  136.  
  137.  
  138. def _select(el, select):
  139.     if select:
  140.         el.set('selected', '')
  141.     elif 'selected' in el.attrib:
  142.         del el.attrib['selected']
  143.     
  144.  
  145.  
  146. def _fill_single(input, value):
  147.     if _nons(input.tag) == 'textarea':
  148.         input.clear()
  149.         input.text = value
  150.     else:
  151.         input.set('value', value)
  152.  
  153.  
  154. def _find_form(el, form_id = None, form_index = None):
  155.     if form_id is None and form_index is None:
  156.         forms = _forms_xpath(el)
  157.         for form in forms:
  158.             return form
  159.         
  160.         raise FormNotFound('No forms in page')
  161.     
  162.     if form_id is not None:
  163.         form = el.get_element_by_id(form_id)
  164.         if form is not None:
  165.             return form
  166.         
  167.         forms = _form_name_xpath(el, name = form_id)
  168.         if forms:
  169.             return forms[0]
  170.         else:
  171.             raise FormNotFound('No form with the name or id of %r (forms: %s)' % (id, ', '.join(_find_form_ids(el))))
  172.     
  173.     if form_index is not None:
  174.         forms = _forms_xpath(el)
  175.         
  176.         try:
  177.             return forms[form_index]
  178.         except IndexError:
  179.             raise FormNotFound('There is no form with the index %r (%i forms found)' % (form_index, len(forms)))
  180.         except:
  181.             None<EXCEPTION MATCH>IndexError
  182.         
  183.  
  184.     None<EXCEPTION MATCH>IndexError
  185.  
  186.  
  187. def _find_form_ids(el):
  188.     forms = _forms_xpath(el)
  189.     if not forms:
  190.         yield '(no forms)'
  191.         return None
  192.     
  193.     for index, form in enumerate(forms):
  194.         if form.get('id'):
  195.             if form.get('name'):
  196.                 yield '%s or %s' % (form.get('id'), form.get('name'))
  197.             else:
  198.                 yield form.get('id')
  199.         form.get('name')
  200.         if form.get('name'):
  201.             yield form.get('name')
  202.             continue
  203.         yield '(unnamed form %s)' % index
  204.     
  205.  
  206.  
  207. class DefaultErrorCreator(object):
  208.     insert_before = True
  209.     block_inside = True
  210.     error_container_tag = 'div'
  211.     error_message_class = 'error-message'
  212.     error_block_class = 'error-block'
  213.     default_message = 'Invalid'
  214.     
  215.     def __init__(self, **kw):
  216.         for name, value in kw.items():
  217.             if not hasattr(self, name):
  218.                 raise TypeError('Unexpected keyword argument: %s' % name)
  219.             
  220.             setattr(self, name, value)
  221.         
  222.  
  223.     
  224.     def __call__(self, el, is_block, message):
  225.         error_el = el.makeelement(self.error_container_tag)
  226.         if self.error_message_class:
  227.             error_el.set('class', self.error_message_class)
  228.         
  229.         if is_block and self.error_block_class:
  230.             error_el.set('class', error_el.get('class', '') + ' ' + self.error_block_class)
  231.         
  232.         if message is None or message == '':
  233.             message = self.default_message
  234.         
  235.         if isinstance(message, ElementBase):
  236.             error_el.append(message)
  237.         elif not message:
  238.             pass
  239.         error_el.text = self.default_message
  240.         if is_block and self.block_inside:
  241.             if self.insert_before:
  242.                 error_el.tail = el.text
  243.                 el.text = None
  244.                 el.insert(0, error_el)
  245.             else:
  246.                 el.append(error_el)
  247.         else:
  248.             parent = el.getparent()
  249.             pos = parent.index(el)
  250.             if self.insert_before:
  251.                 parent.insert(pos, error_el)
  252.             else:
  253.                 error_el.tail = el.tail
  254.                 el.tail = None
  255.                 parent.insert(pos + 1, error_el)
  256.  
  257.  
  258. default_error_creator = DefaultErrorCreator()
  259.  
  260. def insert_errors(el, errors, form_id = None, form_index = None, error_class = 'error', error_creator = default_error_creator):
  261.     el = _find_form(el, form_id = form_id, form_index = form_index)
  262.     for name, error in errors.items():
  263.         if error is None:
  264.             continue
  265.         
  266.         for error_el, message in _find_elements_for_name(el, name, error):
  267.             _insert_error(error_el, message, error_class, error_creator)
  268.         
  269.     
  270.  
  271.  
  272. def insert_errors_html(html, values, **kw):
  273.     result_type = type(html)
  274.     if isinstance(html, basestring):
  275.         doc = fromstring(html)
  276.     else:
  277.         doc = copy.deepcopy(html)
  278.     insert_errors(doc, values, **kw)
  279.     return _transform_result(result_type, doc)
  280.  
  281.  
  282. def _insert_error(el, error, error_class, error_creator):
  283.     if _nons(el.tag) in defs.empty_tags or _nons(el.tag) == 'textarea':
  284.         is_block = False
  285.     else:
  286.         is_block = True
  287.     if _nons(el.tag) != 'form' and error_class:
  288.         _add_class(el, error_class)
  289.     
  290.     if el.get('id'):
  291.         labels = _label_for_xpath(el, for_id = el.get('id'))
  292.         if labels:
  293.             for label in labels:
  294.                 _add_class(label, error_class)
  295.             
  296.         
  297.     
  298.     error_creator(el, is_block, error)
  299.  
  300.  
  301. def _add_class(el, class_name):
  302.     if el.get('class'):
  303.         el.set('class', el.get('class') + ' ' + class_name)
  304.     else:
  305.         el.set('class', class_name)
  306.  
  307.  
  308. def _find_elements_for_name(form, name, error):
  309.     if name is None:
  310.         yield (form, error)
  311.         return None
  312.     
  313.     if name.startswith('#'):
  314.         el = form.get_element_by_id(name[1:])
  315.         if el is not None:
  316.             yield (el, error)
  317.         
  318.         return None
  319.     
  320.     els = _name_xpath(form, name = name)
  321.     if not els:
  322.         return None
  323.     
  324.     if not isinstance(error, (list, tuple)):
  325.         yield (els[0], error)
  326.         return None
  327.     
  328.     for el, err in zip(els, error):
  329.         if err is None:
  330.             continue
  331.         
  332.         yield (el, err)
  333.     
  334.  
  335.