<commit_before># -*- coding: utf-8 -*-

__all__ = ['HtmlUI']

from StringIO import StringIO
from .media import FormMedia


def collect_widgets(fields, update, default=None, from_fields=False):
    widgets = {}
    for field in fields:
        if hasattr(field, 'fields'):
            widgets.update(collect_widgets(field.fields, update))
            continue
        widget = None
        if from_fields and hasattr(field, 'widget'):
            widget = field.widget
        else:
            widget = update.get(field.resolve_name(), default)
        if widget:
            widgets[field.resolve_name()] = widget(element=field)
    return widgets


class HtmlUI(object):

    def __init__(self, **kw):
        '''
        form_widget - widget which will be rendered, if appears.
        fields_widgets - dict [field_name:widget] which will be used to render field.
        from_fields - bool make HtmlUI take widgets from fields.
        default - widget, default widget if other is absent.
        engine - template engine (jinja2, mint, ...).
        engine_ext - template files extensions.
        '''
        self.form_widget = kw.get('form_widget')
        self.fields_widgets = kw.get('fields_widgets', {})
        self.from_fields = kw.get('from_fields')
        self.default = kw.get('default')
        engine = kw.get('engine')
        if engine:
            engine = engine_wrapper(engine, ext=kw.get('engine_ext', 'html'))
        self.engine = engine
        self.media = FormMedia()
        self._init_kw = kw
        #XXX: not good due to one ui may process multiple forms
        self.widgets = {}

    def collect_widgets(self, form_instance):
        widgets = collect_widgets(form_instance.fields, self.fields_widgets, 
                                  default=self.default, from_fields=self.from_fields)
        for w in widgets.values():
            self.media += w.get_media()
        return widgets

    def ui_for(self, field):
        'Returns widget for field or default if former is absend or None'
        widget = self.widgets.get(field.resolve_name())
        if widget:
            return widget(engine=self.engine)
        if self.default:
            return self.default(engine=self.engine)

    def bind(self, engine, ext='html'):
        'Creates new HtmlUI instance binded to engine'
        vars = dict(self._init_kw, engine=engine, engine_ext=ext)
        return self.__class__(**vars)

    def render(self, form):
        #XXX: here we can
        #     - make a copy of self with binded form
        #     - make instance of class (implement it first) with HtmlUI as
        #     atribute
        #     It is all about "ui"
        self.widgets = self.collect_widgets(form)
        if self.form_widget:
            return self.form_widget(engine=self.engine).render(form=form, ui=self)
        result = StringIO()
        for field in form.fields:
            widget = self.ui_for(field)
            if widget:
                result.write(widget.render(field=field, ui=self))
        return result.getvalue()


class engine_wrapper(object):
    'This wrapper is temporary, for use only with jinja2 or mint'
    def __init__(self, env, ext='html'):
        self.env = env
        self.ext = ext
    def render(self, template_name, **data):
        return self.env.get_template('%s.%s' % (template_name, self.ext)).render(**data)<commit_msg>Fixed an order of widget selection from given widget set, form fields and forms<commit_after># -*- coding: utf-8 -*-

__all__ = ['HtmlUI']

from StringIO import StringIO
from .media import FormMedia


def collect_widgets(fields, update, default=None, from_fields=False):
    #XXX: why this is separated from HtmlUI?
    widgets = {}
    for field in fields:
        if hasattr(field, 'fields'):
            widgets.update(collect_widgets(field.fields, update))
            #XXX: what about if we want specify widget for fieldset?
            continue
        widget = update.get(field.resolve_name())
        if widget is None and from_fields:
            widget = getattr(field, 'widget', None)
        widget = widget or default
        if widget is not None:
            widgets[field.resolve_name()] = widget(element=field)
    return widgets


class HtmlUI(object):

    def __init__(self, **kw):
        '''
        form_widget - widget which will be rendered, if appears.
        fields_widgets - dict [field_name:widget] which will be used to render field.
        from_fields - bool make HtmlUI take widgets from fields.
        default - widget, default widget if other is absent.
        engine - template engine (jinja2, mint, ...).
        engine_ext - template files extensions.
        '''
        self.form_widget = kw.get('form_widget')
        self.fields_widgets = kw.get('fields_widgets', {})
        self.from_fields = kw.get('from_fields')
        self.default = kw.get('default')
        engine = kw.get('engine')
        if engine:
            engine = engine_wrapper(engine, ext=kw.get('engine_ext', 'html'))
        self.engine = engine
        self.media = FormMedia()
        self._init_kw = kw
        #XXX: not good due to one ui may process multiple forms
        self.widgets = {}

    def collect_widgets(self, form_instance):
        widgets = collect_widgets(form_instance.fields, self.fields_widgets, 
                                  default=self.default, from_fields=self.from_fields)
        for w in widgets.values():
            self.media += w.get_media()
        return widgets

    def ui_for(self, field):
        'Returns widget for field or default if former is absend or None'
        widget = self.widgets.get(field.resolve_name())
        if widget:
            return widget(engine=self.engine)
        if self.default:
            return self.default(engine=self.engine)

    def bind(self, engine, ext='html'):
        'Creates new HtmlUI instance binded to engine'
        vars = dict(self._init_kw, engine=engine, engine_ext=ext)
        return self.__class__(**vars)

    def render(self, form):
        #XXX: here we can
        #     - make a copy of self with binded form
        #     - make instance of class (implement it first) with HtmlUI as
        #     atribute
        #     It is all about "ui"
        self.widgets = self.collect_widgets(form)
        form_widget = self.form_widget or getattr(form, widget, None)
        if form_widget:
            return form_widget(engine=self.engine).render(form=form, ui=self)
        result = StringIO()
        for field in form.fields:
            widget = self.ui_for(field)
            if widget:
                result.write(widget.render(field=field, ui=self))
        return result.getvalue()


class engine_wrapper(object):
    'This wrapper is temporary, for use only with jinja2 or mint'
    def __init__(self, env, ext='html'):
        self.env = env
        self.ext = ext
    def render(self, template_name, **data):
        return self.env.get_template('%s.%s' % (template_name, self.ext)).render(**data)
{'fraction_non_alphanumeric': 0.1011123787792356, 'fraction_numerical': 0.0008556759840273817, 'mean_word_length': 2.3017890772128062, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2625064', 'n_tokens_mistral': 2000, 'n_tokens_neox': 1936, 'n_words': 579}