django.utils.safestring.mark_safe

Here are the examples of the python api django.utils.safestring.mark_safe taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

200 Examples 7

Example 1

Project: talk.org
Source File: admin_list.py
View license
def items_for_result(cl, result):
    first = True
    pk = cl.lookup_opts.pk.attname
    for field_name in cl.lookup_opts.admin.list_display:
        row_class = ''
        try:
            f = cl.lookup_opts.get_field(field_name)
        except models.FieldDoesNotExist:
            # For non-field list_display values, the value is either a method
            # or a property.
            try:
                attr = getattr(result, field_name)
                allow_tags = getattr(attr, 'allow_tags', False)
                boolean = getattr(attr, 'boolean', False)
                if callable(attr):
                    attr = attr()
                if boolean:
                    allow_tags = True
                    result_repr = _boolean_icon(attr)
                else:
                    result_repr = smart_unicode(attr)
            except (AttributeError, ObjectDoesNotExist):
                result_repr = EMPTY_CHANGELIST_VALUE
            else:
                # Strip HTML tags in the resulting text, except if the
                # function has an "allow_tags" attribute set to True.
                if not allow_tags:
                    result_repr = escape(result_repr)
                else:
                    result_repr = mark_safe(result_repr)
        else:
            field_val = getattr(result, f.attname)

            if isinstance(f.rel, models.ManyToOneRel):
                if field_val is not None:
                    result_repr = escape(getattr(result, f.name))
                else:
                    result_repr = EMPTY_CHANGELIST_VALUE
            # Dates and times are special: They're formatted in a certain way.
            elif isinstance(f, models.DateField) or isinstance(f, models.TimeField):
                if field_val:
                    (date_format, datetime_format, time_format) = get_date_formats()
                    if isinstance(f, models.DateTimeField):
                        result_repr = capfirst(dateformat.format(field_val, datetime_format))
                    elif isinstance(f, models.TimeField):
                        result_repr = capfirst(dateformat.time_format(field_val, time_format))
                    else:
                        result_repr = capfirst(dateformat.format(field_val, date_format))
                else:
                    result_repr = EMPTY_CHANGELIST_VALUE
                row_class = ' class="nowrap"'
            # Booleans are special: We use images.
            elif isinstance(f, models.BooleanField) or isinstance(f, models.NullBooleanField):
                result_repr = _boolean_icon(field_val)
            # DecimalFields are special: Zero-pad the decimals.
            elif isinstance(f, models.DecimalField):
                if field_val is not None:
                    result_repr = ('%%.%sf' % f.decimal_places) % field_val
                else:
                    result_repr = EMPTY_CHANGELIST_VALUE
            # Fields with choices are special: Use the representation
            # of the choice.
            elif f.choices:
                result_repr = dict(f.choices).get(field_val, EMPTY_CHANGELIST_VALUE)
            else:
                result_repr = escape(field_val)
        if force_unicode(result_repr) == '':
            result_repr = mark_safe(' ')
        # If list_display_links not defined, add the link tag to the first field
        if (first and not cl.lookup_opts.admin.list_display_links) or field_name in cl.lookup_opts.admin.list_display_links:
            table_tag = {True:'th', False:'td'}[first]
            first = False
            url = cl.url_for_result(result)
            # Convert the pk to something that can be used in Javascript.
            # Problem cases are long ints (23L) and non-ASCII strings.
            result_id = repr(force_unicode(getattr(result, pk)))[1:]
            yield mark_safe(u'<%s%s><a href="%s"%s>%s</a></%s>' % \
                (table_tag, row_class, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %s); return false;"' % result_id or ''), conditional_escape(result_repr), table_tag))
        else:
            yield mark_safe(u'<td%s>%s</td>' % (row_class, conditional_escape(result_repr)))

Example 2

Project: talk.org
Source File: main.py
View license
def _get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current_depth):
    "Helper function that recursively populates deleted_objects."
    nh = _nest_help # Bind to local variable for performance
    if current_depth > 16:
        return # Avoid recursing too deep.
    opts_seen = []
    for related in opts.get_all_related_objects():
        if related.opts in opts_seen:
            continue
        opts_seen.append(related.opts)
        rel_opts_name = related.get_accessor_name()
        if isinstance(related.field.rel, models.OneToOneRel):
            try:
                sub_obj = getattr(obj, rel_opts_name)
            except ObjectDoesNotExist:
                pass
            else:
                if related.opts.admin:
                    p = '%s.%s' % (related.opts.app_label, related.opts.get_delete_permission())
                    if not user.has_perm(p):
                        perms_needed.add(related.opts.verbose_name)
                        # We don't care about populating deleted_objects now.
                        continue
                if related.field.rel.edit_inline or not related.opts.admin:
                    # Don't display link to edit, because it either has no
                    # admin or is edited inline.
                    nh(deleted_objects, current_depth, [mark_safe(u'%s: %s' % (force_unicode(capfirst(related.opts.verbose_name)), sub_obj)), []])
                else:
                    # Display a link to the admin page.
                    nh(deleted_objects, current_depth, [mark_safe(u'%s: <a href="../../../../%s/%s/%s/">%s</a>' %
                        (escape(force_unicode(capfirst(related.opts.verbose_name))),
                            related.opts.app_label,
                            related.opts.object_name.lower(),
                            sub_obj._get_pk_val(), sub_obj)), []])
                _get_deleted_objects(deleted_objects, perms_needed, user, sub_obj, related.opts, current_depth+2)
        else:
            has_related_objs = False
            for sub_obj in getattr(obj, rel_opts_name).all():
                has_related_objs = True
                if related.field.rel.edit_inline or not related.opts.admin:
                    # Don't display link to edit, because it either has no
                    # admin or is edited inline.
                    nh(deleted_objects, current_depth, [u'%s: %s' % (force_unicode(capfirst(related.opts.verbose_name)), escape(sub_obj)), []])
                else:
                    # Display a link to the admin page.
                    nh(deleted_objects, current_depth, [mark_safe(u'%s: <a href="../../../../%s/%s/%s/">%s</a>' % \
                        (escape(force_unicode(capfirst(related.opts.verbose_name))), related.opts.app_label, related.opts.object_name.lower(), sub_obj._get_pk_val(), escape(sub_obj))), []])
                _get_deleted_objects(deleted_objects, perms_needed, user, sub_obj, related.opts, current_depth+2)
            # If there were related objects, and the user doesn't have
            # permission to delete them, add the missing perm to perms_needed.
            if related.opts.admin and has_related_objs:
                p = '%s.%s' % (related.opts.app_label, related.opts.get_delete_permission())
                if not user.has_perm(p):
                    perms_needed.add(related.opts.verbose_name)
    for related in opts.get_all_related_many_to_many_objects():
        if related.opts in opts_seen:
            continue
        opts_seen.append(related.opts)
        rel_opts_name = related.get_accessor_name()
        has_related_objs = False

        # related.get_accessor_name() could return None for symmetrical relationships
        if rel_opts_name:
            rel_objs = getattr(obj, rel_opts_name, None)
            if rel_objs:
                has_related_objs = True

        if has_related_objs:
            for sub_obj in rel_objs.all():
                if related.field.rel.edit_inline or not related.opts.admin:
                    # Don't display link to edit, because it either has no
                    # admin or is edited inline.
                    nh(deleted_objects, current_depth, [_('One or more %(fieldname)s in %(name)s: %(obj)s') % \
                        {'fieldname': force_unicode(related.field.verbose_name), 'name': force_unicode(related.opts.verbose_name), 'obj': escape(sub_obj)}, []])
                else:
                    # Display a link to the admin page.
                    nh(deleted_objects, current_depth, [
                        mark_safe((_('One or more %(fieldname)s in %(name)s:') % {'fieldname': escape(force_unicode(related.field.verbose_name)), 'name': escape(force_unicode(related.opts.verbose_name))}) + \
                        (u' <a href="../../../../%s/%s/%s/">%s</a>' % \
                            (related.opts.app_label, related.opts.module_name, sub_obj._get_pk_val(), escape(sub_obj)))), []])
        # If there were related objects, and the user doesn't have
        # permission to change them, add the missing perm to perms_needed.
        if related.opts.admin and has_related_objs:
            p = u'%s.%s' % (related.opts.app_label, related.opts.get_change_permission())
            if not user.has_perm(p):
                perms_needed.add(related.opts.verbose_name)

Example 3

Project: talk.org
Source File: defaultfilters.py
View license
def unordered_list(value, autoescape=None):
    """
    Recursively takes a self-nested list and returns an HTML unordered list --
    WITHOUT opening and closing <ul> tags.

    The list is assumed to be in the proper format. For example, if ``var``
    contains: ``['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]``,
    then ``{{ var|unordered_list }}`` would return::

        <li>States
        <ul>
                <li>Kansas
                <ul>
                        <li>Lawrence</li>
                        <li>Topeka</li>
                </ul>
                </li>
                <li>Illinois</li>
        </ul>
        </li>
    """
    if autoescape:
        from django.utils.html import conditional_escape
        escaper = conditional_escape
    else:
        escaper = lambda x: x
    def convert_old_style_list(list_):
        """
        Converts old style lists to the new easier to understand format.

        The old list format looked like:
            ['Item 1', [['Item 1.1', []], ['Item 1.2', []]]

        And it is converted to:
            ['Item 1', ['Item 1.1', 'Item 1.2]]
        """
        if not isinstance(list_, (tuple, list)) or len(list_) != 2:
            return list_, False
        first_item, second_item = list_
        if second_item == []:
            return [first_item], True
        old_style_list = True
        new_second_item = []
        for sublist in second_item:
            item, old_style_list = convert_old_style_list(sublist)
            if not old_style_list:
                break
            new_second_item.extend(item)
        if old_style_list:
            second_item = new_second_item
        return [first_item, second_item], old_style_list
    def _helper(list_, tabs=1):
        indent = u'\t' * tabs
        output = []

        list_length = len(list_)
        i = 0
        while i < list_length:
            title = list_[i]
            sublist = ''
            sublist_item = None
            if isinstance(title, (list, tuple)):
                sublist_item = title
                title = ''
            elif i < list_length - 1:
                next_item = list_[i+1]
                if next_item and isinstance(next_item, (list, tuple)):
                    # The next item is a sub-list.
                    sublist_item = next_item
                    # We've processed the next item now too.
                    i += 1
            if sublist_item:
                sublist = _helper(sublist_item, tabs+1)
                sublist = '\n%s<ul>\n%s\n%s</ul>\n%s' % (indent, sublist,
                                                         indent, indent)
            output.append('%s<li>%s%s</li>' % (indent,
                    escaper(force_unicode(title)), sublist))
            i += 1
        return '\n'.join(output)
    value, converted = convert_old_style_list(value)
    return mark_safe(_helper(value))

Example 4

Project: GAE-Bulk-Mailer
Source File: forms.py
View license
    def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row):
        "Helper function for outputting HTML. Used by as_table(), as_ul(), as_p()."
        top_errors = self.non_field_errors() # Errors that should be displayed above all fields.
        output, hidden_fields = [], []

        for name, field in self.fields.items():
            html_class_attr = ''
            bf = self[name]
            bf_errors = self.error_class([conditional_escape(error) for error in bf.errors]) # Escape and cache in local variable.
            if bf.is_hidden:
                if bf_errors:
                    top_errors.extend(['(Hidden field %s) %s' % (name, force_text(e)) for e in bf_errors])
                hidden_fields.append(six.text_type(bf))
            else:
                # Create a 'class="..."' atribute if the row should have any
                # CSS classes applied.
                css_classes = bf.css_classes()
                if css_classes:
                    html_class_attr = ' class="%s"' % css_classes

                if errors_on_separate_row and bf_errors:
                    output.append(error_row % force_text(bf_errors))

                if bf.label:
                    label = conditional_escape(force_text(bf.label))
                    # Only add the suffix if the label does not end in
                    # punctuation.
                    if self.label_suffix:
                        if label[-1] not in ':?.!':
                            label = format_html('{0}{1}', label, self.label_suffix)
                    label = bf.label_tag(label) or ''
                else:
                    label = ''

                if field.help_text:
                    help_text = help_text_html % force_text(field.help_text)
                else:
                    help_text = ''

                output.append(normal_row % {
                    'errors': force_text(bf_errors),
                    'label': force_text(label),
                    'field': six.text_type(bf),
                    'help_text': help_text,
                    'html_class_attr': html_class_attr
                })

        if top_errors:
            output.insert(0, error_row % force_text(top_errors))

        if hidden_fields: # Insert any hidden fields in the last row.
            str_hidden = ''.join(hidden_fields)
            if output:
                last_row = output[-1]
                # Chop off the trailing row_ender (e.g. '</td></tr>') and
                # insert the hidden fields.
                if not last_row.endswith(row_ender):
                    # This can happen in the as_p() case (and possibly others
                    # that users write): if there are only top errors, we may
                    # not be able to conscript the last row for our purposes,
                    # so insert a new, empty row.
                    last_row = (normal_row % {'errors': '', 'label': '',
                                              'field': '', 'help_text':'',
                                              'html_class_attr': html_class_attr})
                    output.append(last_row)
                output[-1] = last_row[:-len(row_ender)] + str_hidden + row_ender
            else:
                # If there aren't any rows in the output, just append the
                # hidden fields.
                output.append(str_hidden)
        return mark_safe('\n'.join(output))

Example 5

Project: GAE-Bulk-Mailer
Source File: defaultfilters.py
View license
@register.filter(is_safe=True)
def floatformat(text, arg=-1):
    """
    Displays a float to a specified number of decimal places.

    If called without an argument, it displays the floating point number with
    one decimal place -- but only if there's a decimal place to be displayed:

    * num1 = 34.23234
    * num2 = 34.00000
    * num3 = 34.26000
    * {{ num1|floatformat }} displays "34.2"
    * {{ num2|floatformat }} displays "34"
    * {{ num3|floatformat }} displays "34.3"

    If arg is positive, it will always display exactly arg number of decimal
    places:

    * {{ num1|floatformat:3 }} displays "34.232"
    * {{ num2|floatformat:3 }} displays "34.000"
    * {{ num3|floatformat:3 }} displays "34.260"

    If arg is negative, it will display arg number of decimal places -- but
    only if there are places to be displayed:

    * {{ num1|floatformat:"-3" }} displays "34.232"
    * {{ num2|floatformat:"-3" }} displays "34"
    * {{ num3|floatformat:"-3" }} displays "34.260"

    If the input float is infinity or NaN, the (platform-dependent) string
    representation of that value will be displayed.
    """

    try:
        input_val = force_text(text)
        d = Decimal(input_val)
    except UnicodeEncodeError:
        return ''
    except InvalidOperation:
        if input_val in special_floats:
            return input_val
        try:
            d = Decimal(force_text(float(text)))
        except (ValueError, InvalidOperation, TypeError, UnicodeEncodeError):
            return ''
    try:
        p = int(arg)
    except ValueError:
        return input_val

    try:
        m = int(d) - d
    except (ValueError, OverflowError, InvalidOperation):
        return input_val

    if not m and p < 0:
        return mark_safe(formats.number_format('%d' % (int(d)), 0))

    if p == 0:
        exp = Decimal(1)
    else:
        exp = Decimal('1.0') / (Decimal(10) ** abs(p))
    try:
        # Set the precision high enough to avoid an exception, see #15789.
        tupl = d.as_tuple()
        units = len(tupl[1]) - tupl[2]
        prec = abs(p) + units + 1

        # Avoid conversion to scientific notation by accessing `sign`, `digits`
        # and `exponent` from `Decimal.as_tuple()` directly.
        sign, digits, exponent = d.quantize(exp, ROUND_HALF_UP,
            Context(prec=prec)).as_tuple()
        digits = [six.text_type(digit) for digit in reversed(digits)]
        while len(digits) <= abs(exponent):
            digits.append('0')
        digits.insert(-exponent, '.')
        if sign:
            digits.append('-')
        number = ''.join(reversed(digits))
        return mark_safe(formats.number_format(number, abs(p)))
    except InvalidOperation:
        return input_val

Example 6

Project: GAE-Bulk-Mailer
Source File: defaultfilters.py
View license
@register.filter(is_safe=True, needs_autoescape=True)
def unordered_list(value, autoescape=None):
    """
    Recursively takes a self-nested list and returns an HTML unordered list --
    WITHOUT opening and closing <ul> tags.

    The list is assumed to be in the proper format. For example, if ``var``
    contains: ``['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]``,
    then ``{{ var|unordered_list }}`` would return::

        <li>States
        <ul>
                <li>Kansas
                <ul>
                        <li>Lawrence</li>
                        <li>Topeka</li>
                </ul>
                </li>
                <li>Illinois</li>
        </ul>
        </li>
    """
    if autoescape:
        escaper = conditional_escape
    else:
        escaper = lambda x: x
    def convert_old_style_list(list_):
        """
        Converts old style lists to the new easier to understand format.

        The old list format looked like:
            ['Item 1', [['Item 1.1', []], ['Item 1.2', []]]

        And it is converted to:
            ['Item 1', ['Item 1.1', 'Item 1.2]]
        """
        if not isinstance(list_, (tuple, list)) or len(list_) != 2:
            return list_, False
        first_item, second_item = list_
        if second_item == []:
            return [first_item], True
        try:
            # see if second item is iterable
            iter(second_item)
        except TypeError:
            return list_, False
        old_style_list = True
        new_second_item = []
        for sublist in second_item:
            item, old_style_list = convert_old_style_list(sublist)
            if not old_style_list:
                break
            new_second_item.extend(item)
        if old_style_list:
            second_item = new_second_item
        return [first_item, second_item], old_style_list
    def _helper(list_, tabs=1):
        indent = '\t' * tabs
        output = []

        list_length = len(list_)
        i = 0
        while i < list_length:
            title = list_[i]
            sublist = ''
            sublist_item = None
            if isinstance(title, (list, tuple)):
                sublist_item = title
                title = ''
            elif i < list_length - 1:
                next_item = list_[i+1]
                if next_item and isinstance(next_item, (list, tuple)):
                    # The next item is a sub-list.
                    sublist_item = next_item
                    # We've processed the next item now too.
                    i += 1
            if sublist_item:
                sublist = _helper(sublist_item, tabs+1)
                sublist = '\n%s<ul>\n%s\n%s</ul>\n%s' % (indent, sublist,
                                                         indent, indent)
            output.append('%s<li>%s%s</li>' % (indent,
                    escaper(force_text(title)), sublist))
            i += 1
        return '\n'.join(output)
    value, converted = convert_old_style_list(value)
    return mark_safe(_helper(value))

Example 7

Project: kikola
Source File: widgets.py
View license
    def render(self, name, value=None, attrs=None):
        if not self.choices and not self.choices_url:
            raise TypeError, \
                  'One of "choices" or "choices_url" keyword argument must ' \
                  'be supplied obligatory.'

        if self.choices and self.choices_url:
            raise TypeError, \
                  'Only one of "choices" or "choices_url" keyword argument ' \
                  'can be supplied.'

        choices = ''

        if self.choices:
            self.set_current_choice(value)
            choices = simplejson.dumps([unicode(v) for k, v in self.choices],
                                       ensure_ascii=False)
            html_code = HiddenInput().render(name, value=value)
            name += '_autocomplete'
        else:
            html_code = ''

        if self.choices_url:
            try:
                choices = simplejson.dumps(reverse(str(self.choices_url)))
            except NoReverseMatch:
                choices = simplejson.dumps(self.choices_url)

        if self.options or self.extra:
            if 'extraParams' in self.options:
                self.options['extraParams'].update(self.extra)
            else:
                self.options['extraParams'] = self.extra

            options = ', ' + simplejson.dumps(self.options,
                                              indent=4,
                                              sort_keys=True)
            extra = []

            for k, v in self.extra.items():
                options = options.replace(simplejson.dumps(v), v)
                extra.append(
                    u"function %s() { return $('#id_%s').val(); }\n" % (v, k)
                )

            extra = u''.join(extra)
        else:
            extra, options = '', ''

        final_attrs = self.build_attrs(attrs)

        if self.parent_widget is None:
            html_code += super(AutocompleteWidget, self).\
                         render(name, self.choice or value, attrs)
        else:
            html_code += self.parent_widget().\
                         render(name, self.choice or value, final_attrs)

        html_code += u"""
<script type="text/javascript"><!--
    %s$('#%s').autocomplete(%s%s);
--></script>
""" % (extra, final_attrs['id'], choices, options)

        return mark_safe(html_code)

Example 8

View license
    def render(self, name, value, attrs=None):
        if value is None:
            value = []

        display = ''
        if self.url:
            url = self.url
            # todo: Display is not so simple in this case. Needs a lot of work.
            # Will probably have to be a dictionary.
            display = self.initial_display
        else:
            dc, dc, query = pickle.loads(
                _simple_autocomplete_queryset_cache[self.token]
            )
            queryset = QuerySet(model=self.model, query=query)
            threshold = get_threshold_for_model(self.model)
            if threshold and (queryset.count() < threshold):
                # Render the normal select widget if size below threshold
                return super(AutoCompleteMultipleWidget, self).render(
                    name, value, attrs
                )
            else:
                url = reverse('simple_autocomplete:simple-autocomplete', args=[self.token])

            html = u"""
    <script type="text/javascript">
    (function($) {

    $(document).ready(function() {

    $("#id_%s_helper").autocomplete({
        source: function(request, response) {
            $.ajax({
                url: "%s",
                data: {q: request.term},
                success: function(data) {
                    if (data != 'CACHE_MISS')
                    {
                        response($.map(data, function(item) {
                            return {
                                label: item[1],
                                value: item[1],
                                real_value: item[0]
                            };
                        }));
                    }
                },
                dataType: "json"
            });
        },
        select: function(event, ui) {
            var name = '%s';
            var parent = $('#id_' + name).parent();
            var target = $('div.autocomplete-placeholder', parent);
            target.append('<p><input name="' + name + '" value="' + ui.item.real_value + '" '
                + 'type="hidden" />' + ui.item.value
                + ' <a href="#" title="Remove" onclick="django.jQuery(this).parent().remove(); django.jQuery('+"'"+'#id_%s_helper'+"'"+').val(' + "''" + '); django.jQuery('+"'"+'#id_%s_helper'+"'"+').focus(); return false;">x<small></small></a></p>');
        },
        close: function(event, ui) {
            $('#id_%s_helper').val('');
        },
        minLength: 3
    });

    });

    })(django.jQuery);
    </script>

<input id="id_%s_helper" type="text" value="" />
<input id="id_%s" type="hidden" value="" />
<div class="autocomplete-placeholder">""" % (name, url, name, name, name, name, name, name)

            # Create html for existing values
            for v in value:
                if v is None: continue
                display = unicode(queryset.get(pk=v))
                html += """<p><input name="%s" type="hidden" value="%s" />
%s <a href="#" title="Remove" onclick="$(this).parent().remove(); $('#id_%s_helper').val(''); $('#id_%s_helper').focus(); return false;">x<small></small></a></p>""" % (name, v, display, name, name)

            html += "</div>"

            # Help with green plus icon alignment
            # todo: use css class
            html += """<div style="display: inline-block; width: 104px;">&nbsp;</div>"""

            return mark_safe(html)

Example 9

Project: vumi-go
Source File: tasks.py
View license
@task(ignore_result=True)
@with_user_api
def import_new_contacts_file(api, account_key, group_key, file_name, file_path,
                             fields, has_header):
    contact_store = api.contact_store
    group = contact_store.get_group(group_key)

    # Get the profile for this user so we can email them when the import
    # has been completed.
    user_profile = UserProfile.objects.get(user_account=account_key)

    written_contacts = []

    try:
        extension, parser = ContactFileParser.get_parser(file_name)

        contact_dictionaries = parser.parse_file(file_path, fields, has_header)
        for counter, contact_dictionary in enumerate(contact_dictionaries):

            # Make sure we set this group they're being uploaded in to
            contact_dictionary['groups'] = [group.key]

            contact = contact_store.new_contact(**contact_dictionary)
            written_contacts.append(contact)

        send_mail(
            'Contact import completed successfully.',
            render_to_string('contacts/import_completed_mail.txt', {
                'count': counter,
                'group': group,
                'user': user_profile.user,
            }), settings.DEFAULT_FROM_EMAIL, [user_profile.user.email],
            fail_silently=False)

    except Exception:
        # Clean up if something went wrong, either everything is written
        # or nothing is written
        for contact in written_contacts:
            contact.delete()

        exc_type, exc_value, exc_traceback = sys.exc_info()

        send_mail(
            'Something went wrong while importing the contacts.',
            render_to_string('contacts/import_failed_mail.txt', {
                'user': user_profile.user,
                'group_key': group_key,
                'account_key': account_key,
                'file_name': file_name,
                'file_path': file_path,
                'fields': fields,
                'has_header': has_header,
                'exception_type': exc_type,
                'exception_value': mark_safe(exc_value),
                'exception_traceback': mark_safe(
                    traceback.format_tb(exc_traceback)),
            }), settings.DEFAULT_FROM_EMAIL, [
                user_profile.user.email,
                '[email protected]',
            ], fail_silently=False)
    finally:
        default_storage.delete(file_path)

Example 10

Project: PyClassLessons
Source File: admin_list.py
View license
def result_headers(cl):
    """
    Generates the list column headers.
    """
    ordering_field_columns = cl.get_ordering_field_columns()
    for i, field_name in enumerate(cl.list_display):
        text, attr = label_for_field(
            field_name, cl.model,
            model_admin=cl.model_admin,
            return_attr=True
        )
        if attr:
            # Potentially not sortable

            # if the field is the action checkbox: no sorting and special class
            if field_name == 'action_checkbox':
                yield {
                    "text": text,
                    "class_attrib": mark_safe(' class="action-checkbox-column"'),
                    "sortable": False,
                }
                continue

            admin_order_field = getattr(attr, "admin_order_field", None)
            if not admin_order_field:
                # Not sortable
                yield {
                    "text": text,
                    "class_attrib": format_html(' class="column-{0}"', field_name),
                    "sortable": False,
                }
                continue

        # OK, it is sortable if we got this far
        th_classes = ['sortable', 'column-{0}'.format(field_name)]
        order_type = ''
        new_order_type = 'asc'
        sort_priority = 0
        sorted = False
        # Is it currently being sorted on?
        if i in ordering_field_columns:
            sorted = True
            order_type = ordering_field_columns.get(i).lower()
            sort_priority = list(ordering_field_columns).index(i) + 1
            th_classes.append('sorted %sending' % order_type)
            new_order_type = {'asc': 'desc', 'desc': 'asc'}[order_type]

        # build new ordering param
        o_list_primary = []  # URL for making this field the primary sort
        o_list_remove = []  # URL for removing this field from sort
        o_list_toggle = []  # URL for toggling order type for this field
        make_qs_param = lambda t, n: ('-' if t == 'desc' else '') + str(n)

        for j, ot in ordering_field_columns.items():
            if j == i:  # Same column
                param = make_qs_param(new_order_type, j)
                # We want clicking on this header to bring the ordering to the
                # front
                o_list_primary.insert(0, param)
                o_list_toggle.append(param)
                # o_list_remove - omit
            else:
                param = make_qs_param(ot, j)
                o_list_primary.append(param)
                o_list_toggle.append(param)
                o_list_remove.append(param)

        if i not in ordering_field_columns:
            o_list_primary.insert(0, make_qs_param(new_order_type, i))

        yield {
            "text": text,
            "sortable": True,
            "sorted": sorted,
            "ascending": order_type == "asc",
            "sort_priority": sort_priority,
            "url_primary": cl.get_query_string({ORDER_VAR: '.'.join(o_list_primary)}),
            "url_remove": cl.get_query_string({ORDER_VAR: '.'.join(o_list_remove)}),
            "url_toggle": cl.get_query_string({ORDER_VAR: '.'.join(o_list_toggle)}),
            "class_attrib": format_html(' class="{0}"', ' '.join(th_classes)) if th_classes else '',
        }

Example 11

Project: PyClassLessons
Source File: admin_list.py
View license
def items_for_result(cl, result, form):
    """
    Generates the actual list of data.
    """

    def link_in_col(is_first, field_name, cl):
        if cl.list_display_links is None:
            return False
        if is_first and not cl.list_display_links:
            return True
        return field_name in cl.list_display_links

    first = True
    pk = cl.lookup_opts.pk.attname
    for field_name in cl.list_display:
        row_classes = ['field-%s' % field_name]
        try:
            f, attr, value = lookup_field(field_name, result, cl.model_admin)
        except ObjectDoesNotExist:
            result_repr = EMPTY_CHANGELIST_VALUE
        else:
            if f is None:
                if field_name == 'action_checkbox':
                    row_classes = ['action-checkbox']
                allow_tags = getattr(attr, 'allow_tags', False)
                boolean = getattr(attr, 'boolean', False)
                if boolean:
                    allow_tags = True
                result_repr = display_for_value(value, boolean)
                # Strip HTML tags in the resulting text, except if the
                # function has an "allow_tags" attribute set to True.
                if allow_tags:
                    result_repr = mark_safe(result_repr)
                if isinstance(value, (datetime.date, datetime.time)):
                    row_classes.append('nowrap')
            else:
                if isinstance(f.rel, models.ManyToOneRel):
                    field_val = getattr(result, f.name)
                    if field_val is None:
                        result_repr = EMPTY_CHANGELIST_VALUE
                    else:
                        result_repr = field_val
                else:
                    result_repr = display_for_field(value, f)
                if isinstance(f, (models.DateField, models.TimeField, models.ForeignKey)):
                    row_classes.append('nowrap')
        if force_text(result_repr) == '':
            result_repr = mark_safe('&nbsp;')
        row_class = mark_safe(' class="%s"' % ' '.join(row_classes))
        # If list_display_links not defined, add the link tag to the first field
        if link_in_col(first, field_name, cl):
            table_tag = 'th' if first else 'td'
            first = False

            # Display link to the result's change_view if the url exists, else
            # display just the result's representation.
            try:
                url = cl.url_for_result(result)
            except NoReverseMatch:
                link_or_text = result_repr
            else:
                url = add_preserved_filters({'preserved_filters': cl.preserved_filters, 'opts': cl.opts}, url)
                # Convert the pk to something that can be used in Javascript.
                # Problem cases are long ints (23L) and non-ASCII strings.
                if cl.to_field:
                    attr = str(cl.to_field)
                else:
                    attr = pk
                value = result.serializable_value(attr)
                result_id = escapejs(value)
                link_or_text = format_html(
                    '<a href="{0}"{1}>{2}</a>',
                    url,
                    format_html(' onclick="opener.dismissRelatedLookupPopup(window, &#39;{0}&#39;); return false;"', result_id) if cl.is_popup else '',
                    result_repr)

            yield format_html('<{0}{1}>{2}</{3}>',
                              table_tag,
                              row_class,
                              link_or_text,
                              table_tag)
        else:
            # By default the fields come from ModelAdmin.list_editable, but if we pull
            # the fields out of the form instead of list_editable custom admins
            # can provide fields on a per request basis
            if (form and field_name in form.fields and not (
                    field_name == cl.model._meta.pk.name and
                    form[cl.model._meta.pk.name].is_hidden)):
                bf = form[field_name]
                result_repr = mark_safe(force_text(bf.errors) + force_text(bf))
            yield format_html('<td{0}>{1}</td>', row_class, result_repr)
    if form and not form[cl.model._meta.pk.name].is_hidden:
        yield format_html('<td>{0}</td>', force_text(form[cl.model._meta.pk.name]))

Example 12

Project: PyClassLessons
Source File: defaultfilters.py
View license
@register.filter(is_safe=True, needs_autoescape=True)
def unordered_list(value, autoescape=None):
    """
    Recursively takes a self-nested list and returns an HTML unordered list --
    WITHOUT opening and closing <ul> tags.

    The list is assumed to be in the proper format. For example, if ``var``
    contains: ``['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]``,
    then ``{{ var|unordered_list }}`` would return::

        <li>States
        <ul>
                <li>Kansas
                <ul>
                        <li>Lawrence</li>
                        <li>Topeka</li>
                </ul>
                </li>
                <li>Illinois</li>
        </ul>
        </li>
    """
    if autoescape:
        escaper = conditional_escape
    else:
        escaper = lambda x: x

    def convert_old_style_list(list_):
        """
        Converts old style lists to the new easier to understand format.

        The old list format looked like:
            ['Item 1', [['Item 1.1', []], ['Item 1.2', []]]

        And it is converted to:
            ['Item 1', ['Item 1.1', 'Item 1.2]]
        """
        if not isinstance(list_, (tuple, list)) or len(list_) != 2:
            return list_, False
        first_item, second_item = list_
        if second_item == []:
            return [first_item], True
        try:
            # see if second item is iterable
            iter(second_item)
        except TypeError:
            return list_, False
        old_style_list = True
        new_second_item = []
        for sublist in second_item:
            item, old_style_list = convert_old_style_list(sublist)
            if not old_style_list:
                break
            new_second_item.extend(item)
        if old_style_list:
            second_item = new_second_item
        return [first_item, second_item], old_style_list

    def _helper(list_, tabs=1):
        indent = '\t' * tabs
        output = []

        list_length = len(list_)
        i = 0
        while i < list_length:
            title = list_[i]
            sublist = ''
            sublist_item = None
            if isinstance(title, (list, tuple)):
                sublist_item = title
                title = ''
            elif i < list_length - 1:
                next_item = list_[i + 1]
                if next_item and isinstance(next_item, (list, tuple)):
                    # The next item is a sub-list.
                    sublist_item = next_item
                    # We've processed the next item now too.
                    i += 1
            if sublist_item:
                sublist = _helper(sublist_item, tabs + 1)
                sublist = '\n%s<ul>\n%s\n%s</ul>\n%s' % (indent, sublist,
                                                         indent, indent)
            output.append('%s<li>%s%s</li>' % (indent,
                    escaper(force_text(title)), sublist))
            i += 1
        return '\n'.join(output)
    value, converted = convert_old_style_list(value)
    return mark_safe(_helper(value))

Example 13

Project: django-shop
Source File: checkout.py
View license
    @classmethod
    def form_factory(cls, request, data, cart):
        """
        From the given request, update the database model.
        If the form data is invalid, return an error dictionary to update the response.
        """
        # search for the associated address DB instance or create a new one
        current_address, active_address = cls.get_address(cart), None
        try:
            active_priority = int(data.get('active_priority'))
            filter_args = dict(customer=request.customer, priority=active_priority)
            active_address = cls.get_model().objects.filter(**filter_args).first()
        except ValueError:
            active_priority = data.get('active_priority')
        except TypeError:
            active_priority = cls.default_priority
        if not active_address:
            active_address = cls.get_model().objects.get_fallback(customer=request.customer)

        if data.pop('remove_entity', False):
            if isinstance(active_priority, int):
                active_address.delete()
            old_address = cls.get_model().objects.get_fallback(customer=request.customer)
            faked_data = dict((key, getattr(old_address, key, val)) for key, val in data.items())
            if old_address:
                faked_data.update(active_priority=old_address.priority)
            address_form = cls(data=faked_data, instance=old_address)
            if isinstance(active_priority, int):
                remove_entity_filter = cls.js_filter.format(active_priority)
                address_form.data.update(remove_entity_filter=mark_safe(remove_entity_filter))
            address_form.set_address(cart, old_address)
        elif active_priority == 'add':
            # Add a newly filled address for the given customer
            address_form = cls(data=data, cart=cart)
            if address_form.is_valid():
                # prevent adding the same address twice
                all_field_names = cls.get_model()._meta.get_all_field_names()
                filter_args = dict((attr, val) for attr, val in address_form.data.items()
                                   if attr in all_field_names and val)
                filter_args.update(customer=request.customer)
                if not cls.get_model().objects.filter(**filter_args).exists():
                    next_address = address_form.save(commit=False)
                    if next_address:
                        next_address.customer = request.customer
                        next_address.priority = cls.get_model().objects.get_max_priority(request.customer) + 1
                        next_address.save()
                        address_form.data.update(active_priority=next_address.priority)
                    else:
                        address_form.data.update(active_priority='nop')
                    address_form.set_address(cart, next_address)
        elif active_address is None or active_priority == 'new':
            # customer selected 'Add another address', hence create a new empty form
            initial = dict((key, val) for key, val in data.items() if key in cls.plugin_fields)
            address_form = cls(initial=initial)
            address_form.data.update(address_form.get_initial_data())
            address_form.data.update(active_priority='add')
            address_form.set_address(cart, None)
        elif current_address == active_address:
            # an existing entity of AddressModel was edited
            address_form = cls(data=data, instance=active_address)
            if address_form.is_valid():
                next_address = address_form.save()
                address_form.set_address(cart, next_address)
        else:
            # an address with another priority was selected
            initial = dict(data)
            for attr in cls().get_initial_data().keys():
                if hasattr(active_address, attr):
                    initial.update({attr: getattr(active_address, attr)})
            initial.update(active_priority=active_address.priority)
            address_form = cls(data=initial, instance=current_address)
            address_form.set_address(cart, active_address)
        return address_form

Example 14

View license
    def render(self, name, value, attrs=None, choices=()):

        apps_available = []  # main container to send to template
        user_permissions = Permission.objects.filter(id__in=value or []).values_list('id', flat=True)
        all_perms = Permission.objects.all().values('id', 'codename', 'content_type_id').order_by('codename')
        excluded_perms = set([])
        codename_id_map = {}
        for p in all_perms:
            codename_id_map['%s_%s' % (p['codename'], p['content_type_id'])] = p['id']

        reminder_perms = codename_id_map.copy()
        # used to detect if the tabular permissions covers all permissions, if so, we don't need to make it visible.

        for app in apps.get_app_configs():
            app_dict = {'verbose_name': force_text(app.verbose_name),
                        'models': []}

            for model_name in app.models:
                model = app.models[model_name]
                ct_id = ContentType.objects.get_for_model(model, for_concrete_model=TABULAR_PERMISSIONS_USE_FOR_CONCRETE).pk
                add_perm_name = get_perm_name(model_name, 'add')
                change_perm_name = get_perm_name(model_name, 'change')
                delete_perm_name = get_perm_name(model_name, 'delete')
                # pdb.set_trace()
                add_perm_id = codename_id_map.get('%s_%s' % (add_perm_name, ct_id), False)
                change_perm_id = codename_id_map.get('%s_%s' % (change_perm_name, ct_id), False)
                delete_perm_id = codename_id_map.get('%s_%s' % (delete_perm_name, ct_id), False)

                if add_perm_id and change_perm_id and delete_perm_id and not {add_perm_id, change_perm_id,
                                                                              delete_perm_id} & excluded_perms:
                    excluded_perms.update([add_perm_id, change_perm_id, delete_perm_id])
                    reminder_perms.pop('%s_%s' % (add_perm_name, ct_id))
                    reminder_perms.pop('%s_%s' % (change_perm_name, ct_id))
                    reminder_perms.pop('%s_%s' % (delete_perm_name, ct_id))

                    if app.label in TABULAR_PERMISSIONS_EXCLUDE_APPS \
                            or model_name in TABULAR_PERMISSIONS_EXCLUDE_MODELS \
                            or TABULAR_PERMISSIONS_EXCLUDE_FUNCTION(model):
                        continue

                    app_dict['models'].append({
                        'model_name': model_name,
                        'model': model,
                        'verbose_name_plural': force_text(model._meta.verbose_name_plural),
                        'verbose_name': force_text(model._meta.verbose_name),
                        'add_perm_id': add_perm_id,
                        'add_perm_name': add_perm_name,
                        'change_perm_id': change_perm_id,
                        'change_perm_name': change_perm_name,
                        'delete_perm_id': delete_perm_id,
                        'delete_perm_name': delete_perm_name,
                    })

            if app.models:
                apps_available.append(app_dict)

        request_context = {'apps_available': apps_available, 'user_permissions': user_permissions,
                           'codename_id_map': codename_id_map, 'input_name': self.input_name}
        body = get_template(TABULAR_PERMISSIONS_TEMPLATE).render(request_context).encode("utf-8")
        self.managed_perms = excluded_perms
        if reminder_perms:
            self.hide_original = False

        # Get "original" FilteredSelectMultiple, and hide it if necessary.
        # Next block is a "copy" of FilteredSelectMultiple render(), except the if reminder_perms: check.
        # Due to change in how SelectFilter take its arguments and the dropping of static('admin/') in django1.9
        # there a check on django version

        if attrs is None:
            attrs = {}
        attrs['class'] = 'selectfilter'
        if self.is_stacked:
            attrs['class'] += 'stacked'

        output = [super(FilteredSelectMultiple, self).render(name, value, attrs, choices)]
        if reminder_perms:
            output.append('<script type="text/javascript">addEvent(window, "load", function(e) {')

            if '1.8' in django_version:
                output.append('SelectFilter.init("id_%s", "%s", %s, "%s"); });</script>\n'
                              % (name, self.verbose_name.replace('"', '\\"'), int(self.is_stacked), static('admin/')))
            else:  # 1.9
                output.append('SelectFilter.init("id_%s", "%s", %s); });</script>\n'
                              % (name, escapejs(self.verbose_name), int(self.is_stacked)))

        initial = mark_safe(''.join(output))
        response = ' <hr/>'.join([force_text(body), force_text(initial)])
        return mark_safe(response)

Example 15

Project: redsolution-cms
Source File: admin.py
View license
    def change_view(self, request, **kwargs):
        "The 'change' admin view for this model"
        model = self.model
        opts = model._meta

        try:
            obj = self.model.objects.get_settings()
        except model.DoesNotExist:
            # Don't raise Http404 just yet, because we haven't checked
            # permissions yet. We don't want an unauthenticated user to be able
            # to determine whether a given object exists.
            obj = None

        if obj is None:
            raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_unicode(opts.verbose_name), 'key': escape(kwargs.get('object_id', ''))})

        if request.method == 'POST' and request.POST.has_key("_saveasnew"):
            return self.add_view(request, form_url='../add/')

        ModelForm = self.get_form(request, obj)
        formsets = []
        if request.method == 'POST':
            form = ModelForm(request.POST, request.FILES, instance=obj)
            if form.is_valid():
                form_validated = True
                new_object = self.save_form(request, form, change=True)
            else:
                form_validated = False
                new_object = obj
            prefixes = {}
            for FormSet in self.get_formsets(request, new_object):
                prefix = FormSet.get_default_prefix()
                prefixes[prefix] = prefixes.get(prefix, 0) + 1
                if prefixes[prefix] != 1:
                    prefix = "%s-%s" % (prefix, prefixes[prefix])
                formset = FormSet(request.POST, request.FILES,
                                  instance=new_object, prefix=prefix)
                formsets.append(formset)

            if all_valid(formsets) and form_validated:
                self.save_model(request, new_object, form, change=True)
                form.save_m2m()
                for formset in formsets:
                    self.save_formset(request, form, formset, change=True)

                self.construct_change_message(request, form, formsets)
                return self.response_change(request, new_object)

        else:
            form = ModelForm(instance=obj)
            prefixes = {}
            for FormSet in self.get_formsets(request, obj):
                prefix = FormSet.get_default_prefix()
                prefixes[prefix] = prefixes.get(prefix, 0) + 1
                if prefixes[prefix] != 1:
                    prefix = "%s-%s" % (prefix, prefixes[prefix])
                formset = FormSet(instance=obj, prefix=prefix)
                formsets.append(formset)

        adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), self.prepopulated_fields)
        media = self.media + adminForm.media

        inline_admin_formsets = []
        for inline, formset in zip(self.inline_instances, formsets):
            fieldsets = list(inline.get_fieldsets(request, obj))
            inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets)
            inline_admin_formsets.append(inline_admin_formset)
            media = media + inline_admin_formset.media

        context = {
            'title': _('Change %s') % force_unicode(opts.verbose_name),
            'adminform': adminForm,
            'original': obj,
            'is_popup': request.REQUEST.has_key('_popup'),
            'media': mark_safe(media),
            'inline_admin_formsets': inline_admin_formsets,
            'errors': helpers.AdminErrorList(form, formsets),
            'app_label': opts.app_label,
        }
        return self.render_change_form(request, context, change=True, obj=obj)

Example 16

Project: reviewboard
Source File: difftags.py
View license
@register.simple_tag
def diff_lines(index, chunk, standalone, line_fmt, anchor_fmt='',
               begin_collapse_fmt='', end_collapse_fmt='', moved_fmt=''):
    """Renders the lines of a diff.

    This will render each line in the diff viewer. The function expects
    some basic data on what will be rendered, as well as printf-formatted
    templates for the contents.

    printf-formatted templates are used instead of standard Django templates
    because they're much faster to render, which makes a huge difference
    when rendering thousands of lines or more.
    """
    lines = chunk['lines']
    num_lines = len(lines)
    chunk_index = chunk['index']
    change = chunk['change']
    is_equal = False
    is_replace = False
    is_insert = False
    is_delete = False

    if change == 'equal':
        is_equal = True
    elif change == 'replace':
        is_replace = True
    elif change == 'insert':
        is_insert = True
    elif change == 'delete':
        is_delete = True

    result = []

    for i, line in enumerate(lines):
        row_classes = []
        cell_1_classes = ['l']
        cell_2_classes = ['r']
        row_class_attr = ''
        cell_1_class_attr = ''
        cell_2_class_attr = ''
        line1 = line[2]
        line2 = line[5]
        linenum1 = line[1]
        linenum2 = line[4]
        show_collapse = False
        anchor = None

        if not is_equal:
            if i == 0:
                row_classes.append('first')
                anchor = '%s.%s' % (index, chunk_index)

            if i == num_lines - 1:
                row_classes.append('last')

            if line[7]:
                row_classes.append('whitespace-line')

            if is_replace:
                if len(line1) < DiffChunkGenerator.STYLED_MAX_LINE_LEN:
                    line1 = highlightregion(line1, line[3])

                if len(line2) < DiffChunkGenerator.STYLED_MAX_LINE_LEN:
                    line2 = highlightregion(line2, line[6])
        else:
            show_collapse = (i == 0 and standalone)

        if (not is_insert and
                len(line1) < DiffChunkGenerator.STYLED_MAX_LINE_LEN):
            line1 = showextrawhitespace(line1)

        if (not is_delete and
                len(line2) < DiffChunkGenerator.STYLED_MAX_LINE_LEN):
            line2 = showextrawhitespace(line2)

        moved_from = {}
        moved_to = {}
        is_moved_row = False
        is_first_moved_row = False

        if len(line) > 8 and isinstance(line[8], dict):
            moved_info = line[8]

            if 'from' in moved_info:
                moved_from_linenum, moved_from_first = moved_info['from']
                is_moved_row = True

                cell_2_classes.append('moved-from')

                if moved_from_first:
                    # This is the start of a new move range.
                    is_first_moved_row = True
                    cell_2_classes.append('moved-from-start')
                    moved_from = {
                        'class': 'moved-flag',
                        'line': mark_safe(moved_from_linenum),
                        'target': mark_safe(linenum2),
                        'text': _('Moved from line %s') % moved_from_linenum,
                    }

            if 'to' in moved_info:
                moved_to_linenum, moved_to_first = moved_info['to']
                is_moved_row = True

                cell_1_classes.append('moved-to')

                if moved_to_first:
                    # This is the start of a new move range.
                    is_first_moved_row = True
                    cell_1_classes.append('moved-to-start')
                    moved_to = {
                        'class': 'moved-flag',
                        'line': mark_safe(moved_to_linenum),
                        'target': mark_safe(linenum1),
                        'text': _('Moved to line %s') % moved_to_linenum,
                    }

        if is_moved_row:
            row_classes.append('moved-row')

        if is_first_moved_row:
            row_classes.append('moved-row-start')

        if row_classes:
            row_class_attr = ' class="%s"' % ' '.join(row_classes)

        if cell_1_classes:
            cell_1_class_attr = ' class="%s"' % ' '.join(cell_1_classes)

        if cell_2_classes:
            cell_2_class_attr = ' class="%s"' % ' '.join(cell_2_classes)

        anchor_html = ''
        begin_collapse_html = ''
        end_collapse_html = ''
        moved_from_html = ''
        moved_to_html = ''

        context = {
            'chunk_index': chunk_index,
            'row_class_attr': row_class_attr,
            'cell_1_class_attr': cell_1_class_attr,
            'cell_2_class_attr': cell_2_class_attr,
            'linenum_row': line[0],
            'linenum1': linenum1,
            'linenum2': linenum2,
            'line1': line1,
            'line2': line2,
            'moved_from': moved_from,
            'moved_to': moved_to,
        }

        if anchor:
            anchor_html = anchor_fmt % {
                'anchor': anchor,
            }

        if show_collapse:
            begin_collapse_html = begin_collapse_fmt % context
            end_collapse_html = end_collapse_fmt % context

        if moved_from:
            moved_from_html = moved_fmt % moved_from

        if moved_to:
            moved_to_html = moved_fmt % moved_to

        context.update({
            'anchor_html': anchor_html,
            'begin_collapse_html': begin_collapse_html,
            'end_collapse_html': end_collapse_html,
            'moved_from_html': moved_from_html,
            'moved_to_html': moved_to_html,
        })

        result.append(line_fmt % context)

    return ''.join(result)

Example 17

Project: reviewboard
Source File: builtin_fields.py
View license
    def render_change_entry_html(self, info):
        added_diff_info = info['added'][0]
        review_request = self.review_request_details.get_review_request()

        try:
            diffset = self.data.diffsets_by_id[added_diff_info[2]]
        except KeyError:
            # If a published revision of a diff has been deleted from the
            # database, this will explode. Just return a blank string for this,
            # so that it doesn't show a traceback.
            return ''

        diff_revision = diffset.revision
        past_revision = diff_revision - 1
        diff_url = added_diff_info[1]

        s = []

        # Fetch the total number of inserts/deletes. These will be shown
        # alongside the diff revision.
        counts = diffset.get_total_line_counts()
        raw_insert_count = counts.get('raw_insert_count', 0)
        raw_delete_count = counts.get('raw_delete_count', 0)

        line_counts = []

        if raw_insert_count > 0:
            line_counts.append('<span class="insert-count">+%d</span>'
                               % raw_insert_count)

        if raw_delete_count > 0:
            line_counts.append('<span class="delete-count">-%d</span>'
                               % raw_delete_count)

        # Display the label, URL, and line counts for the diff.
        s.append(format_html(
            '<p class="diff-changes">'
            ' <a href="{url}">{label}</a>'
            ' <span class="line-counts">({line_counts})</span>'
            '</p>',
            url=diff_url,
            label=_('Revision %s') % diff_revision,
            count=_('%d files') % diffset.file_count,
            line_counts=mark_safe(' '.join(line_counts))))

        if past_revision > 0:
            # This is not the first diff revision. Include an interdiff link.
            interdiff_url = local_site_reverse(
                'view-interdiff',
                local_site=review_request.local_site,
                args=[
                    review_request.display_id,
                    past_revision,
                    diff_revision,
                ])

            s.append(format_html(
                '<p><a href="{url}">{text}</a>',
                url=interdiff_url,
                text=_('Show changes')))

        if diffset.file_count > 0:
            # Begin displaying the list of files modified in this diff.
            # It will be capped at a fixed number (MAX_FILES_PREVIEW).
            s += [
                '<div class="diff-index">',
                ' <table>',
            ]

            # We want a sorted list of filediffs, but tagged with the order in
            # which they come from the database, so that we can properly link
            # to the respective files in the diff viewer.
            files = get_sorted_filediffs(enumerate(diffset.files.all()),
                                         key=lambda i: i[1])

            for i, filediff in files[:self.MAX_FILES_PREVIEW]:
                counts = filediff.get_line_counts()

                data_attrs = [
                    'data-%s="%s"' % (attr.replace('_', '-'), counts[attr])
                    for attr in ('insert_count', 'delete_count',
                                 'replace_count', 'total_line_count')
                    if counts.get(attr) is not None
                ]

                s.append(format_html(
                    '<tr {data_attrs}>'
                    ' <td class="diff-file-icon"></td>'
                    ' <td class="diff-file-info">'
                    '  <a href="{url}">{filename}</a>'
                    ' </td>'
                    '</tr>',
                    data_attrs=mark_safe(' '.join(data_attrs)),
                    url=diff_url + '#%d' % i,
                    filename=filediff.source_file))

            num_remaining = diffset.file_count - self.MAX_FILES_PREVIEW

            if num_remaining > 0:
                # There are more files remaining than we've shown, so show
                # the count.
                s.append(format_html(
                    '<tr>'
                    ' <td></td>'
                    ' <td class="diff-file-info">{text}</td>'
                    '</tr>',
                    text=_('%s more') % num_remaining))

            s += [
                ' </table>',
                '</div>',
            ]

        return ''.join(s)

Example 18

Project: classic.rhizome.org
Source File: core.py
View license
def replace(text, max_width=MAX_WIDTH, max_height=MAX_HEIGHT):
    """
    Scans a block of text, replacing anything matched by a ``ProviderRule``
    pattern with an OEmbed html snippet, if possible.
    
    Templates should be stored at oembed/{format}.html, so for example:
        
        oembed/video.html
        
    These templates are passed a context variable, ``response``, which is a 
    dictionary representation of the response.
    """
    rules = list(ProviderRule.objects.all())
    patterns = [re.compile(r.regex, re.I) for r in rules] # Compiled patterns from the rules
    parts = [] # The parts that we will assemble into the final return value.
    indices = [] # List of indices of parts that need to be replaced with OEmbed stuff.
    indices_rules = [] # List of indices into the rules in order for which index was gotten by.
    urls = set() # A set of URLs to try to lookup from the database.
    stored = {} # A mapping of URLs to StoredOEmbed objects.
    index = 0
    # First we pass through the text, populating our data structures.
    for i, part in re_parts(patterns, text):
        if i == -1:
            parts.append(part)
            index += 1
        else:
            to_append = ""
            # If the link ends with one of our overrides, build a list
            while part[-1] in END_OVERRIDES:
                to_append += part[-1]
                part = part[:-1]
            indices.append(index)
            urls.add(part)
            indices_rules.append(i)
            parts.append(part)
            index += 1
            if to_append:
                parts.append(to_append)
                index += 1
    # Now we fetch a list of all stored patterns, and put it in a dictionary 
    # mapping the URL to to the stored model instance.
    for stored_embed in StoredOEmbed.objects.filter(match__in=urls, max_width=max_width, max_height = max_height):
        stored[stored_embed.match] = stored_embed
    # Now we're going to do the actual replacement of URL to embed.
    for i, id_to_replace in enumerate(indices):
        rule = rules[indices_rules[i]]
        part = parts[id_to_replace]
        try:
            # Try to grab the stored model instance from our dictionary, and
            # use the stored HTML fragment as a replacement.
            parts[id_to_replace] = stored[part].html
        except KeyError:
            try:
                # Build the URL based on the properties defined in the OEmbed spec.
                q = urllib.urlencode({"url" : part, 
                                      "maxwidth":max_width,
                                      "maxheight":max_height, 
                                      "format":FORMAT})
                url = u"%s?%s" % (rule.endpoint, q)
                # Fetch the link and parse the JSON.
                resp = simplejson.loads(fetch(url))
                
                # link types that don't have html elements aren't dealt with right now.
                if resp['type'] == 'link' and 'html' not in resp:
                    raise ValueError
                
                # Depending on the embed type, grab the associated template and
                # pass it the parsed JSON response as context.
                replacement = render_to_string('oembed/%s.html' % resp['type'], {'response': resp})
                if replacement:
                    stored_embed = StoredOEmbed.objects.create(
                        match = part,
                        max_width = max_width,
                        max_height = max_height,
                        html = replacement,
                    )
                    stored[stored_embed.match] = stored_embed
                    parts[id_to_replace] = replacement
                else:
                    raise ValueError
            except ValueError:
                parts[id_to_replace] = part
            except KeyError:
                parts[id_to_replace] = part
            except urllib2.HTTPError:
                parts[id_to_replace] = part
    # Combine the list into one string and return it.
    return mark_safe(u''.join(parts))

Example 19

View license
def items_for_result(view, result):
    """
    Generates the actual list of data.
    """
    model_admin = view.model_admin
    for field_name in view.list_display:
        empty_value_display = model_admin.get_empty_value_display()
        row_classes = ['field-%s' % field_name]
        try:
            f, attr, value = lookup_field(field_name, result, model_admin)
        except ObjectDoesNotExist:
            result_repr = empty_value_display
        else:
            empty_value_display = getattr(attr, 'empty_value_display', empty_value_display)
            if f is None or f.auto_created:
                allow_tags = getattr(attr, 'allow_tags', False)
                boolean = getattr(attr, 'boolean', False)
                if boolean or not value:
                    allow_tags = True

                if django.VERSION >= (1, 9):
                    result_repr = display_for_value(value, empty_value_display, boolean)
                else:
                    result_repr = display_for_value(value, boolean)
                # Strip HTML tags in the resulting text, except if the
                # function has an "allow_tags" attribute set to True.
                if allow_tags:
                    result_repr = mark_safe(result_repr)
                if isinstance(value, (datetime.date, datetime.time)):
                    row_classes.append('nowrap')
            else:
                if isinstance(f, models.ManyToOneRel):
                    field_val = getattr(result, f.name)
                    if field_val is None:
                        result_repr = empty_value_display
                    else:
                        result_repr = field_val
                else:
                    if django.VERSION >= (1, 9):
                        result_repr = display_for_field(value, f, empty_value_display)
                    else:
                        result_repr = display_for_field(value, f)

                if isinstance(f, (models.DateField, models.TimeField, models.ForeignKey)):
                    row_classes.append('nowrap')
        if force_text(result_repr) == '':
            result_repr = mark_safe('&nbsp;')
        row_classes.extend(model_admin.get_extra_class_names_for_field_col(field_name, result))
        row_attributes_dict = model_admin.get_extra_attrs_for_field_col(field_name, result)
        row_attributes_dict['class'] = ' ' . join(row_classes)
        row_attributes = ''.join(' %s="%s"' % (key, val) for key, val in row_attributes_dict.items())
        row_attributes_safe = mark_safe(row_attributes)
        yield format_html('<td{}>{}</td>', row_attributes_safe, result_repr)

Example 20

Project: rocket-league-replays
Source File: replays.py
View license
@register.assignment_tag
def steam_stats(uid):
    data = {}
    season_id = get_default_season()

    # Winning goals scored.
    data['winning_goals'] = Goal.objects.filter(
        player__platform__in=['OnlinePlatform_Steam', '1'],
        player__online_id=uid,
        replay__show_leaderboard=True,
        replay__season_id=season_id,
        number=F('replay__team_0_score') + F('replay__team_1_score')
    ).count()

    # Last minute goals (literally, goals scored within the last minute of the game)
    data['last_minute_goals'] = Goal.objects.filter(
        player__platform__in=['OnlinePlatform_Steam', '1'],
        player__online_id=uid,
        replay__show_leaderboard=True,
        replay__season_id=season_id,
        frame__gte=F('replay__num_frames') - (60 * F('replay__record_fps'))
    ).count()

    # Number of times the player has scored a goal which equalised the game and
    # forced it into overtime.
    data['overtime_triggering_goals'] = 0
    data['overtime_triggering_and_winning_goals'] = 0
    data['overtime_trigger_and_team_win'] = 0

    # Find replays which went into overtime.
    replays = Replay.objects.filter(
        show_leaderboard=True,
        season_id=season_id,
        goal__frame__gte=(60 * 5 * F('record_fps')),
    )

    # Get all games with overtime goals.
    replays = Replay.objects.annotate(
        num_goals=F('team_0_score') + F('team_1_score'),
    ).filter(
        season_id=season_id,
        num_frames__gt=60 * 5 * F('record_fps'),
        show_leaderboard=True,
        player__platform__in=['OnlinePlatform_Steam', '1'],
        player__online_id=uid,
        num_goals__gte=2,
    ).prefetch_related('goal_set')

    for replay in replays:
        # Who scored the 2nd to last goal?
        try:
            goal = replay.goal_set.get(
                number=replay.num_goals - 1,
                player__platform__in=['OnlinePlatform_Steam', '1'],
                player__online_id=uid,
            )

            data['overtime_triggering_goals'] += 1

            # Did the team win?
            team = goal.player.team

            if (
                team == 0 and replay.team_0_score > replay.team_1_score or
                team == 1 and replay.team_1_score > replay.team_0_score
            ):
                data['overtime_trigger_and_team_win'] += 1

            # Did they also score the winning goal?
            replay.goal_set.get(
                number=replay.num_goals,
                player__platform__in=['OnlinePlatform_Steam', '1'],
                player__online_id=uid,
            )

            data['overtime_triggering_and_winning_goals'] += 1
        except Goal.DoesNotExist:
            pass
        except Goal.MultipleObjectsReturned:
            pass

    # Which match size does this player appear most in?
    data['preferred_match_size'] = None

    sizes = Replay.objects.filter(
        season_id=season_id,
        show_leaderboard=True,
        player__platform__in=['OnlinePlatform_Steam', '1'],
        player__online_id=uid,
    ).values('team_sizes').annotate(
        Count('team_sizes'),
    ).order_by('-team_sizes__count')

    if len(sizes) > 0:
        data['preferred_match_size'] = sizes[0]['team_sizes']

    # What's this player's prefered role within a team?
    data['preferred_role'] = None

    role_query = Player.objects.filter(
        replay__show_leaderboard=True,
        replay__season_id=season_id,
        platform__in=['OnlinePlatform_Steam', '1'],
        online_id=uid,
    ).aggregate(
        goals=Sum('goals'),
        assists=Sum('assists'),
        saves=Sum('saves'),
    )

    if not any([v[1] for v in role_query.items()]):
        data['preferred_role'] = None
    else:
        max_stat = max(role_query, key=lambda k: role_query[k])

        if max_stat == 'goals':
            data['preferred_role'] = 'Goalscorer'
        elif max_stat == 'assists':
            data['preferred_role'] = 'Assister'
        elif max_stat == 'saves':
            data['preferred_role'] = 'Goalkeeper'

    """
    # Number of times the player's score was higher than everyone else on their
    # team put together.
    data['carries'] = 0

    # Number of times the player's score was higher than everyone else put together.
    data['dominations'] = 0

    replays = Replay.objects.filter(
        team_sizes__gte=2,
        show_leaderboard=True,
        player__platform__in=['OnlinePlatform_Steam', '1'],
        player__online_id=uid,
    )

    for replay in replays:
        # Which team was the player on? Split screen players will break a .get()
        # here, so we have to filter().
        player = replay.player_set.filter(
            platform='OnlinePlatform_Steam',
            online_id=uid,
        )[0]

        # What was the total score for this team?
        team_score = Player.objects.filter(
            replay=replay,
            team=player.team,
        ).exclude(
            pk=player.pk,
        ).aggregate(
            score=Sum('score'),
        )['score']

        if player.score > team_score:
            data['carries'] += 1

        # What was the total score for the other team?
        other_team_score = Player.objects.filter(
            replay=replay,
        ).exclude(
            team=player.team,
        ).aggregate(
            score=Sum('score'),
        )['score']

        if not team_score:
            team_score = 0

        if not other_team_score:
            other_team_score = 0

        if player.score > team_score + other_team_score:
            data['dominations'] += 1

    # The biggest gap in a win involving the player.
    data['biggest_win'] = None

    replays = Replay.objects.filter(
        team_sizes__gte=2,
        show_leaderboard=True,
        player__platform__in=['OnlinePlatform_Steam', '1'],
        player__online_id=uid,
    ).extra(select={
        'goal_diff': 'abs("team_0_score" - "team_1_score")'
    }).order_by('-goal_diff')
    """

    for replay in replays:
        # Which team was the player on? Split screen players will break a .get()
        # here, so we have to filter().
        player = replay.player_set.filter(
            platform__in=['OnlinePlatform_Steam', '1'],
            online_id=uid,
        )[0]

        # Check if the player was on the winning team.
        if (
            player.team == 0 and replay.team_0_score > replay.team_1_score or
            player.team == 1 and replay.team_1_score > replay.team_0_score
        ):
            data['biggest_win'] = mark_safe('<a href="{}">{} - {}</a>'.format(
                replay.get_absolute_url(),
                replay.team_0_score,
                replay.team_1_score,
            ))
            break

    data.update(Player.objects.filter(
        replay__season_id=season_id,
        platform__in=['OnlinePlatform_Steam', '1'],
        online_id=uid,
    ).aggregate(
        highest_score=Max('score'),
        most_goals=Max('goals'),
        most_shots=Max('shots'),
        most_assists=Max('assists'),
        most_saves=Max('saves'),
    ))

    return data

Example 21

View license
def items_for_result(cl, result, form):
    """
    Generates the actual list of data.
    """

    def link_in_col(is_first, field_name, cl):
        if cl.list_display_links is None:
            return False
        if is_first and not cl.list_display_links:
            return True
        return field_name in cl.list_display_links

    first = True
    pk = cl.lookup_opts.pk.attname
    for field_name in cl.list_display:
        row_classes = ['field-%s' % field_name]
        try:
            f, attr, value = lookup_field(field_name, result, cl.model_admin)
        except ObjectDoesNotExist:
            result_repr = EMPTY_CHANGELIST_VALUE
        else:
            if f is None:
                if field_name == 'action_checkbox':
                    row_classes = ['action-checkbox']
                allow_tags = getattr(attr, 'allow_tags', False)
                boolean = getattr(attr, 'boolean', False)
                if boolean:
                    allow_tags = True
                result_repr = display_for_value(value, boolean)
                # Strip HTML tags in the resulting text, except if the
                # function has an "allow_tags" attribute set to True.
                if allow_tags:
                    result_repr = mark_safe(result_repr)
                if isinstance(value, (datetime.date, datetime.time)):
                    row_classes.append('nowrap')
            else:
                if isinstance(f.rel, models.ManyToOneRel):
                    field_val = getattr(result, f.name)
                    if field_val is None:
                        result_repr = EMPTY_CHANGELIST_VALUE
                    else:
                        result_repr = field_val
                else:
                    result_repr = display_for_field(value, f)
                if isinstance(f, (models.DateField, models.TimeField, models.ForeignKey)):
                    row_classes.append('nowrap')
        if force_text(result_repr) == '':
            result_repr = mark_safe('&nbsp;')
        row_class = mark_safe(' class="%s"' % ' '.join(row_classes))
        # If list_display_links not defined, add the link tag to the first field
        if link_in_col(first, field_name, cl):
            table_tag = 'th' if first else 'td'
            first = False

            # Display link to the result's change_view if the url exists, else
            # display just the result's representation.
            try:
                url = cl.url_for_result(result)
            except NoReverseMatch:
                link_or_text = result_repr
            else:
                url = add_preserved_filters({'preserved_filters': cl.preserved_filters, 'opts': cl.opts}, url)
                # Convert the pk to something that can be used in Javascript.
                # Problem cases are long ints (23L) and non-ASCII strings.
                if cl.to_field:
                    attr = str(cl.to_field)
                else:
                    attr = pk
                value = result.serializable_value(attr)
                result_id = escapejs(value)
                link_or_text = format_html(
                    '<a href="{}"{}>{}</a>',
                    url,
                    format_html(
                        ' onclick="opener.dismissRelatedLookupPopup(window, '
                        '&#39;{}&#39;); return false;"', result_id
                    ) if cl.is_popup else '',
                    result_repr)

            yield format_html('<{}{}>{}</{}>',
                              table_tag,
                              row_class,
                              link_or_text,
                              table_tag)
        else:
            # By default the fields come from ModelAdmin.list_editable, but if we pull
            # the fields out of the form instead of list_editable custom admins
            # can provide fields on a per request basis
            if (form and field_name in form.fields and not (
                    field_name == cl.model._meta.pk.name and
                    form[cl.model._meta.pk.name].is_hidden)):
                bf = form[field_name]
                result_repr = mark_safe(force_text(bf.errors) + force_text(bf))
            yield format_html('<td{}>{}</td>', row_class, result_repr)
    if form and not form[cl.model._meta.pk.name].is_hidden:
        yield format_html('<td>{}</td>', force_text(form[cl.model._meta.pk.name]))

Example 22

View license
@register.filter(is_safe=True)
def floatformat(text, arg=-1):
    """
    Displays a float to a specified number of decimal places.

    If called without an argument, it displays the floating point number with
    one decimal place -- but only if there's a decimal place to be displayed:

    * num1 = 34.23234
    * num2 = 34.00000
    * num3 = 34.26000
    * {{ num1|floatformat }} displays "34.2"
    * {{ num2|floatformat }} displays "34"
    * {{ num3|floatformat }} displays "34.3"

    If arg is positive, it will always display exactly arg number of decimal
    places:

    * {{ num1|floatformat:3 }} displays "34.232"
    * {{ num2|floatformat:3 }} displays "34.000"
    * {{ num3|floatformat:3 }} displays "34.260"

    If arg is negative, it will display arg number of decimal places -- but
    only if there are places to be displayed:

    * {{ num1|floatformat:"-3" }} displays "34.232"
    * {{ num2|floatformat:"-3" }} displays "34"
    * {{ num3|floatformat:"-3" }} displays "34.260"

    If the input float is infinity or NaN, the (platform-dependent) string
    representation of that value will be displayed.
    """

    try:
        input_val = force_text(text)
        d = Decimal(input_val)
    except UnicodeEncodeError:
        return ''
    except InvalidOperation:
        if input_val in special_floats:
            return input_val
        try:
            d = Decimal(force_text(float(text)))
        except (ValueError, InvalidOperation, TypeError, UnicodeEncodeError):
            return ''
    try:
        p = int(arg)
    except ValueError:
        return input_val

    try:
        m = int(d) - d
    except (ValueError, OverflowError, InvalidOperation):
        return input_val

    if not m and p < 0:
        return mark_safe(formats.number_format('%d' % (int(d)), 0))

    if p == 0:
        exp = Decimal(1)
    else:
        exp = Decimal('1.0') / (Decimal(10) ** abs(p))
    try:
        # Set the precision high enough to avoid an exception, see #15789.
        tupl = d.as_tuple()
        units = len(tupl[1]) - tupl[2]
        prec = abs(p) + units + 1

        # Avoid conversion to scientific notation by accessing `sign`, `digits`
        # and `exponent` from `Decimal.as_tuple()` directly.
        sign, digits, exponent = d.quantize(exp, ROUND_HALF_UP,
            Context(prec=prec)).as_tuple()
        digits = [six.text_type(digit) for digit in reversed(digits)]
        while len(digits) <= abs(exponent):
            digits.append('0')
        digits.insert(-exponent, '.')
        if sign:
            digits.append('-')
        number = ''.join(reversed(digits))
        return mark_safe(formats.number_format(number, abs(p)))
    except InvalidOperation:
        return input_val

Example 23

View license
@register.filter(is_safe=True, needs_autoescape=True)
def unordered_list(value, autoescape=True):
    """
    Recursively takes a self-nested list and returns an HTML unordered list --
    WITHOUT opening and closing <ul> tags.

    The list is assumed to be in the proper format. For example, if ``var``
    contains: ``['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]``,
    then ``{{ var|unordered_list }}`` would return::

        <li>States
        <ul>
                <li>Kansas
                <ul>
                        <li>Lawrence</li>
                        <li>Topeka</li>
                </ul>
                </li>
                <li>Illinois</li>
        </ul>
        </li>
    """
    if autoescape:
        escaper = conditional_escape
    else:
        escaper = lambda x: x

    def convert_old_style_list(list_):
        """
        Converts old style lists to the new easier to understand format.

        The old list format looked like:
            ['Item 1', [['Item 1.1', []], ['Item 1.2', []]]

        And it is converted to:
            ['Item 1', ['Item 1.1', 'Item 1.2]]
        """
        if not isinstance(list_, (tuple, list)) or len(list_) != 2:
            return list_, False
        first_item, second_item = list_
        if second_item == []:
            return [first_item], True
        try:
            # see if second item is iterable
            iter(second_item)
        except TypeError:
            return list_, False
        old_style_list = True
        new_second_item = []
        for sublist in second_item:
            item, old_style_list = convert_old_style_list(sublist)
            if not old_style_list:
                break
            new_second_item.extend(item)
        if old_style_list:
            second_item = new_second_item
        return [first_item, second_item], old_style_list

    def walk_items(item_list):
        item_iterator = iter(item_list)
        for item in item_iterator:
            try:
                next_item = next(item_iterator)
            except StopIteration:
                next_item = None
            if not isinstance(next_item, six.string_types):
                try:
                    iter(next_item)
                except TypeError:
                    pass
                else:
                    yield item, next_item
                    continue
            yield item, None
            if next_item:
                yield next_item, None

    def list_formatter(item_list, tabs=1):
        indent = '\t' * tabs
        output = []
        for item, children in walk_items(item_list):
            sublist = ''
            if children:
                sublist = '\n%s<ul>\n%s\n%s</ul>\n%s' % (
                    indent, list_formatter(children, tabs + 1), indent, indent)
            output.append('%s<li>%s%s</li>' % (
                indent, escaper(force_text(item)), sublist))
        return '\n'.join(output)

    value, converted = convert_old_style_list(value)
    if converted:
        warnings.warn(
            "The old style syntax in `unordered_list` is deprecated and will "
            "be removed in Django 2.0. Use the the new format instead.",
            RemovedInDjango20Warning)
    return mark_safe(list_formatter(value))

Example 24

Project: Django--an-app-at-a-time
Source File: html.py
View license
def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
    """
    Converts any URLs in text into clickable links.

    Works on http://, https://, www. links, and also on links ending in one of
    the original seven gTLDs (.com, .edu, .gov, .int, .mil, .net, and .org).
    Links can have trailing punctuation (periods, commas, close-parens) and
    leading punctuation (opening parens) and it'll still do the right thing.

    If trim_url_limit is not None, the URLs in the link text longer than this
    limit will be truncated to trim_url_limit-3 characters and appended with
    an ellipsis.

    If nofollow is True, the links will get a rel="nofollow" attribute.

    If autoescape is True, the link text and URLs will be autoescaped.
    """
    safe_input = isinstance(text, SafeData)

    def trim_url(x, limit=trim_url_limit):
        if limit is None or len(x) <= limit:
            return x
        return '%s...' % x[:max(0, limit - 3)]

    def unescape(text, trail):
        """
        If input URL is HTML-escaped, unescape it so as we can safely feed it to
        smart_urlquote. For example:
        http://example.com?x=1&amp;y=<2> => http://example.com?x=1&y=<2>
        """
        unescaped = (text + trail).replace(
            '&amp;', '&').replace('<', '<').replace(
            '>', '>').replace('&quot;', '"').replace('&#39;', "'")
        if trail and unescaped.endswith(trail):
            # Remove trail for unescaped if it was not consumed by unescape
            unescaped = unescaped[:-len(trail)]
        elif trail == ';':
            # Trail was consumed by unescape (as end-of-entity marker), move it to text
            text += trail
            trail = ''
        return text, unescaped, trail

    words = word_split_re.split(force_text(text))
    for i, word in enumerate(words):
        if '.' in word or '@' in word or ':' in word:
            # Deal with punctuation.
            lead, middle, trail = '', word, ''
            for punctuation in TRAILING_PUNCTUATION:
                if middle.endswith(punctuation):
                    middle = middle[:-len(punctuation)]
                    trail = punctuation + trail
            for opening, closing in WRAPPING_PUNCTUATION:
                if middle.startswith(opening):
                    middle = middle[len(opening):]
                    lead = lead + opening
                # Keep parentheses at the end only if they're balanced.
                if (middle.endswith(closing)
                        and middle.count(closing) == middle.count(opening) + 1):
                    middle = middle[:-len(closing)]
                    trail = closing + trail

            # Make URL we want to point to.
            url = None
            nofollow_attr = ' rel="nofollow"' if nofollow else ''
            if simple_url_re.match(middle):
                middle, middle_unescaped, trail = unescape(middle, trail)
                url = smart_urlquote(middle_unescaped)
            elif simple_url_2_re.match(middle):
                middle, middle_unescaped, trail = unescape(middle, trail)
                url = smart_urlquote('http://%s' % middle_unescaped)
            elif ':' not in middle and simple_email_re.match(middle):
                local, domain = middle.rsplit('@', 1)
                try:
                    domain = domain.encode('idna').decode('ascii')
                except UnicodeError:
                    continue
                url = 'mailto:%[email protected]%s' % (local, domain)
                nofollow_attr = ''

            # Make link.
            if url:
                trimmed = trim_url(middle)
                if autoescape and not safe_input:
                    lead, trail = escape(lead), escape(trail)
                    trimmed = escape(trimmed)
                middle = '<a href="%s"%s>%s</a>' % (escape(url), nofollow_attr, trimmed)
                words[i] = mark_safe('%s%s%s' % (lead, middle, trail))
            else:
                if safe_input:
                    words[i] = mark_safe(word)
                elif autoescape:
                    words[i] = escape(word)
        elif safe_input:
            words[i] = mark_safe(word)
        elif autoescape:
            words[i] = escape(word)
    return ''.join(words)

Example 25

Project: django-adminactions
Source File: export.py
View license
def base_export(modeladmin, request, queryset, title, impl,  # noqa
                name, action_short_description, template, form_class, ):
    """
        export a queryset to csv file
    """
    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(opts.app_label, get_permission_codename('adminactions_export', opts))
    if not request.user.has_perm(perm):
        messages.error(request, _('Sorry you do not have rights to execute this action'))
        return

    try:
        adminaction_requested.send(sender=modeladmin.model,
                                   action=name,
                                   request=request,
                                   queryset=queryset,
                                   modeladmin=modeladmin)
    except ActionInterrupted as e:
        messages.error(request, str(e))
        return

    cols = [(f.name, f.verbose_name) for f in queryset.model._meta.fields]
    initial = {'_selected_action': request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
               'select_across': request.POST.get('select_across') == '1',
               'action': get_action(request),
               'columns': [x for x, v in cols]}
    if initial["action"] == "export_as_csv":
        initial.update(getattr(
            settings, "ADMINACTIONS_CSV_OPTIONS_DEFAULT", {}))

    if 'apply' in request.POST:
        form = form_class(request.POST)
        form.fields['columns'].choices = cols
        if form.is_valid():
            try:
                adminaction_start.send(sender=modeladmin.model,
                                       action=name,
                                       request=request,
                                       queryset=queryset,
                                       modeladmin=modeladmin,
                                       form=form)
            except ActionInterrupted as e:
                messages.error(request, str(e))
                return

            if hasattr(modeladmin, 'get_%s_filename' % name):
                filename = modeladmin.get_export_as_csv_filename(request, queryset)
            else:
                filename = None
            try:
                response = impl(queryset,
                                fields=form.cleaned_data['columns'],
                                header=form.cleaned_data.get('header', False),
                                filename=filename,
                                options=form.cleaned_data)
            except Exception as e:
                messages.error(request, "Error: (%s)" % str(e))
            else:
                adminaction_end.send(sender=modeladmin.model,
                                     action=name,
                                     request=request,
                                     queryset=queryset,
                                     modeladmin=modeladmin,
                                     form=form)
                return response
    else:
        form = form_class(initial=initial)
        form.fields['columns'].choices = cols

    adminForm = helpers.AdminForm(form, modeladmin.get_fieldsets(request), {}, [], model_admin=modeladmin)
    media = modeladmin.media + adminForm.media
    # tpl = 'adminactions/export_csv.html'
    ctx = {'adminform': adminForm,
           'change': True,
           'action_short_description': action_short_description,
           'title': title,
           'is_popup': False,
           'save_as': False,
           'has_delete_permission': False,
           'has_add_permission': False,
           'has_change_permission': True,
           'queryset': queryset,
           'opts': queryset.model._meta,
           'app_label': queryset.model._meta.app_label,
           'media': mark_safe(media)}
    if django.VERSION[:2] > (1, 7):
        ctx.update(modeladmin.admin_site.each_context(request))
    else:
        ctx.update(modeladmin.admin_site.each_context())
    return render_to_response(template, RequestContext(request, ctx))

Example 26

Project: django-adminactions
Source File: export.py
View license
def export_delete_tree(modeladmin, request, queryset):  # noqa
    """
    Export as fixture selected queryset and all the records that belong to.
    That mean that dump what will be deleted if the queryset was deleted
    """
    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(opts.app_label, get_permission_codename('adminactions_export', opts))
    if not request.user.has_perm(perm):
        messages.error(request, _('Sorry you do not have rights to execute this action'))
        return
    try:
        adminaction_requested.send(sender=modeladmin.model,
                                   action='export_delete_tree',
                                   request=request,
                                   queryset=queryset,
                                   modeladmin=modeladmin)
    except ActionInterrupted as e:
        messages.error(request, str(e))
        return

    initial = {'_selected_action': request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
               'select_across': request.POST.get('select_across') == '1',
               'action': get_action(request),

               'serializer': 'json',
               'indent': 4}

    if 'apply' in request.POST:
        form = FixtureOptions(request.POST)
        if form.is_valid():
            try:
                adminaction_start.send(sender=modeladmin.model,
                                       action='export_delete_tree',
                                       request=request,
                                       queryset=queryset,
                                       modeladmin=modeladmin,
                                       form=form)
            except ActionInterrupted as e:
                messages.error(request, str(e))
                return
            try:
                collect_related = form.cleaned_data.get('add_foreign_keys')
                using = router.db_for_write(modeladmin.model)

                c = Collector(using)
                c.collect(queryset, collect_related=collect_related)
                data = []
                for model, instances in list(c.data.items()):
                    data.extend(instances)
                adminaction_end.send(sender=modeladmin.model,
                                     action='export_delete_tree',
                                     request=request,
                                     queryset=queryset,
                                     modeladmin=modeladmin,
                                     form=form)
                if hasattr(modeladmin, 'get_export_delete_tree_filename'):
                    filename = modeladmin.get_export_delete_tree_filename(request, queryset)
                else:
                    filename = None
                return _dump_qs(form, queryset, data, filename)
            except AttributeError as e:
                messages.error(request, str(e))
                return HttpResponseRedirect(request.path)
    else:
        form = FixtureOptions(initial=initial)

    adminForm = helpers.AdminForm(form, modeladmin.get_fieldsets(request), {}, model_admin=modeladmin)
    media = modeladmin.media + adminForm.media
    tpl = 'adminactions/export_fixture.html'
    ctx = {'adminform': adminForm,
           'change': True,
           'action_short_description': export_delete_tree.short_description,
           'title': u"%s (%s)" % (
               export_delete_tree.short_description.capitalize(),
               modeladmin.opts.verbose_name_plural,
           ),
           'is_popup': False,
           'save_as': False,
           'has_delete_permission': False,
           'has_add_permission': False,
           'has_change_permission': True,
           'queryset': queryset,
           'opts': queryset.model._meta,
           'app_label': queryset.model._meta.app_label,
           'media': mark_safe(media)}
    if django.VERSION[:2] > (1, 7):
        ctx.update(modeladmin.admin_site.each_context(request))
    else:
        ctx.update(modeladmin.admin_site.each_context())
    return render_to_response(tpl, RequestContext(request, ctx))

Example 27

Project: django-adminactions
Source File: mass_update.py
View license
def mass_update(modeladmin, request, queryset):  # noqa
    """
        mass update queryset
    """

    def not_required(field, **kwargs):
        """ force all fields as not required"""
        kwargs['required'] = False
        return field.formfield(**kwargs)

    def _doit():
        errors = {}
        updated = 0
        for record in queryset:
            for field_name, value_or_func in list(form.cleaned_data.items()):
                if callable(value_or_func):
                    old_value = getattr(record, field_name)
                    setattr(record, field_name, value_or_func(old_value))
                else:
                    setattr(record, field_name, value_or_func)
            if clean:
                record.clean()
            record.save()
            updated += 1
        if updated:
            messages.info(request, _("Updated %s records") % updated)

        if len(errors):
            messages.error(request, "%s records not updated due errors" % len(errors))
        adminaction_end.send(sender=modeladmin.model,
                             action='mass_update',
                             request=request,
                             queryset=queryset,
                             modeladmin=modeladmin,
                             form=form,
                             errors=errors,
                             updated=updated)

    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(opts.app_label, get_permission_codename('adminactions_massupdate', opts))
    if not request.user.has_perm(perm):
        messages.error(request, _('Sorry you do not have rights to execute this action'))
        return

    try:
        adminaction_requested.send(sender=modeladmin.model,
                                   action='mass_update',
                                   request=request,
                                   queryset=queryset,
                                   modeladmin=modeladmin)
    except ActionInterrupted as e:
        messages.error(request, str(e))
        return

    # Allows to specified a custom mass update Form in the ModelAdmin
    mass_update_form = getattr(modeladmin, 'mass_update_form', MassUpdateForm)

    MForm = modelform_factory(modeladmin.model, form=mass_update_form,
                              exclude=('pk',),
                              formfield_callback=not_required)
    grouped = defaultdict(lambda: [])
    selected_fields = []
    initial = {'_selected_action': request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
               'select_across': request.POST.get('select_across') == '1',
               'action': 'mass_update'}

    if 'apply' in request.POST:
        form = MForm(request.POST)
        if form.is_valid():
            try:
                adminaction_start.send(sender=modeladmin.model,
                                       action='mass_update',
                                       request=request,
                                       queryset=queryset,
                                       modeladmin=modeladmin,
                                       form=form)
            except ActionInterrupted as e:
                messages.error(request, str(e))
                return HttpResponseRedirect(request.get_full_path())

            # need_transaction = form.cleaned_data.get('_unique_transaction', False)
            validate = form.cleaned_data.get('_validate', False)
            clean = form.cleaned_data.get('_clean', False)

            if validate:
                with compat.atomic():
                    _doit()

            else:
                values = {}
                for field_name, value in list(form.cleaned_data.items()):
                    if isinstance(form.fields[field_name], ModelMultipleChoiceField):
                        messages.error(request, "Unable no mass update ManyToManyField without 'validate'")
                        return HttpResponseRedirect(request.get_full_path())
                    elif callable(value):
                        messages.error(request, "Unable no mass update using operators without 'validate'")
                        return HttpResponseRedirect(request.get_full_path())
                    elif field_name not in ['_selected_action', '_validate', 'select_across', 'action',
                                            '_unique_transaction', '_clean']:
                        values[field_name] = value
                queryset.update(**values)

            return HttpResponseRedirect(request.get_full_path())
    else:
        initial.update({'action': 'mass_update', '_validate': 1})
        # form = MForm(initial=initial)
        prefill_with = request.POST.get('prefill-with', None)
        prefill_instance = None
        try:
            # Gets the instance directly from the queryset for data security
            prefill_instance = queryset.get(pk=prefill_with)
        except ObjectDoesNotExist:
            pass

        form = MForm(initial=initial, instance=prefill_instance)

    for el in queryset.all()[:10]:
        for f in modeladmin.model._meta.fields:
            if f.name not in form._no_sample_for:
                if hasattr(f, 'flatchoices') and f.flatchoices:
                    grouped[f.name] = list(dict(getattr(f, 'flatchoices')).values())
                elif hasattr(f, 'choices') and f.choices:
                    grouped[f.name] = list(dict(getattr(f, 'choices')).values())
                elif isinstance(f, df.BooleanField):
                    grouped[f.name] = [True, False]
                else:
                    value = getattr(el, f.name)
                    if value is not None and value not in grouped[f.name]:
                        grouped[f.name].append(value)
                    initial[f.name] = initial.get(f.name, value)

    adminForm = helpers.AdminForm(form, modeladmin.get_fieldsets(request), {}, [], model_admin=modeladmin)
    media = modeladmin.media + adminForm.media
    dthandler = lambda obj: obj.isoformat() if isinstance(obj, datetime.date) else str(obj)
    tpl = 'adminactions/mass_update.html'
    ctx = {'adminform': adminForm,
           'form': form,
           'action_short_description': mass_update.short_description,
           'title': u"%s (%s)" % (
               mass_update.short_description.capitalize(),
               smart_text(modeladmin.opts.verbose_name_plural),
           ),
           'grouped': grouped,
           'fieldvalues': json.dumps(grouped, default=dthandler),
           'change': True,
           'selected_fields': selected_fields,
           'is_popup': False,
           'save_as': False,
           'has_delete_permission': False,
           'has_add_permission': False,
           'has_change_permission': True,
           'opts': modeladmin.model._meta,
           'app_label': modeladmin.model._meta.app_label,
           # 'action': 'mass_update',
           # 'select_across': request.POST.get('select_across')=='1',
           'media': mark_safe(media),
           'selection': queryset}
    if django.VERSION[:2] > (1, 7):
        ctx.update(modeladmin.admin_site.each_context(request))
    else:
        ctx.update(modeladmin.admin_site.each_context())

    if django.VERSION[:2] > (1, 8):
        return render(request, tpl, context=ctx)
    else:
        return render_to_response(tpl, RequestContext(request, ctx))

Example 28

Project: django-adminactions
Source File: merge.py
View license
def merge(modeladmin, request, queryset):  # noqa
    """
    Merge two model instances. Move all foreign keys.

    """

    opts = modeladmin.model._meta
    perm = "{0}.{1}".format(opts.app_label, get_permission_codename('adminactions_merge', opts))
    if not request.user.has_perm(perm):
        messages.error(request, _('Sorry you do not have rights to execute this action'))
        return

    def raw_widget(field, **kwargs):
        """ force all fields as not required"""
        kwargs['widget'] = TextInput({'class': 'raw-value'})
        return field.formfield(**kwargs)

    merge_form = getattr(modeladmin, 'merge_form', MergeForm)
    MForm = modelform_factory(modeladmin.model,
                              form=merge_form,
                              exclude=('pk', ),
                              formfield_callback=raw_widget)
    OForm = modelform_factory(modeladmin.model,
                              exclude=('pk', ),
                              formfield_callback=raw_widget)

    tpl = 'adminactions/merge.html'
    # transaction_supported = model_supports_transactions(modeladmin.model)
    ctx = {
        '_selected_action': request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
        'transaction_supported': 'Un',
        'select_across': request.POST.get('select_across') == '1',
        'action': request.POST.get('action'),
        'fields': [f for f in queryset.model._meta.fields if not f.primary_key and f.editable],
        'app_label': queryset.model._meta.app_label,
        'result': '',
        'opts': queryset.model._meta}

    if 'preview' in request.POST:
        master = queryset.get(pk=request.POST.get('master_pk'))
        original = clone_instance(master)
        other = queryset.get(pk=request.POST.get('other_pk'))
        formset = formset_factory(OForm)(initial=[model_to_dict(master), model_to_dict(other)])
        with transaction.nocommit():
            form = MForm(request.POST, instance=master)
            other.delete()
            form_is_valid = form.is_valid()
        if form_is_valid:
            ctx.update({'original': original})
            tpl = 'adminactions/merge_preview.html'
        else:
            master = queryset.get(pk=request.POST.get('master_pk'))
            other = queryset.get(pk=request.POST.get('other_pk'))

    elif 'apply' in request.POST:
        master = queryset.get(pk=request.POST.get('master_pk'))
        other = queryset.get(pk=request.POST.get('other_pk'))
        formset = formset_factory(OForm)(initial=[model_to_dict(master), model_to_dict(other)])
        with transaction.nocommit():
            form = MForm(request.POST, instance=master)
            stored_pk = other.pk
            other.delete()
            ok = form.is_valid()
            other.pk = stored_pk
        if ok:
            if form.cleaned_data['dependencies'] == MergeForm.DEP_MOVE:
                related = api.ALL_FIELDS
            else:
                related = None
            fields = form.cleaned_data['field_names']
            api.merge(master, other, fields=fields, commit=True, related=related)
            return HttpResponseRedirect(request.path)
        else:
            messages.error(request, form.errors)
    else:
        try:
            master, other = queryset.all()
            # django 1.4 need to remove the trailing milliseconds
            for field in master._meta.fields:
                if isinstance(field, models.DateTimeField):
                    for target in (master, other):
                        raw_value = getattr(target, field.name)
                        if raw_value:
                            fixed_value = datetime(
                                raw_value.year,
                                raw_value.month,
                                raw_value.day,
                                raw_value.hour,
                                raw_value.minute,
                                raw_value.second)
                            setattr(target, field.name, fixed_value)
        except ValueError:
            messages.error(request, _('Please select exactly 2 records'))
            return

        initial = {'_selected_action': request.POST.getlist(helpers.ACTION_CHECKBOX_NAME),
                   'select_across': 0,
                   'generic': MergeForm.GEN_IGNORE,
                   'dependencies': MergeForm.DEP_MOVE,
                   'action': 'merge',
                   'master_pk': master.pk,
                   'other_pk': other.pk}
        formset = formset_factory(OForm)(initial=[model_to_dict(master), model_to_dict(other)])
        form = MForm(initial=initial, instance=master)

    adminForm = helpers.AdminForm(form, modeladmin.get_fieldsets(request), {}, [], model_admin=modeladmin)
    media = modeladmin.media + adminForm.media
    ctx.update({'adminform': adminForm,
                'formset': formset,
                'media': mark_safe(media),
                'action_short_description': merge.short_description,
                'title': u"%s (%s)" % (
                    merge.short_description.capitalize(),
                    smart_text(modeladmin.opts.verbose_name_plural),
                ),
                'master': master,
                'other': other})
    if django.VERSION[:2] > (1, 7):
        ctx.update(modeladmin.admin_site.each_context(request))
    else:
        ctx.update(modeladmin.admin_site.each_context())
    if django.VERSION[:2] > (1, 8):
        return render(request, tpl, context=ctx)
    else:
        return render_to_response(tpl, RequestContext(request, ctx))

Example 29

Project: coursys
Source File: views.py
View license
@requires_discipline_user
def edit_case_info(request, course_slug, case_slug, field):
    """
    View function for all of the "edit this aspect of the case" steps.  Uses the STEP_* dictionaries to get relevant strings/classes.
    """
    course = get_object_or_404(CourseOffering, slug=course_slug)
    case = get_object_or_404(DisciplineCaseBase, slug=case_slug, offering__slug=course_slug)
    case = case.subclass()

    # permisson checks
    roles = request.session['discipline-'+course_slug]
    if not case.can_edit(field):
        # once instructor finished, don't allow editing those fields
        return ForbiddenResponse(request, "letter has been sent: cannot edit this field")
    elif isinstance(case, DisciplineCaseInstr) and "INSTR" not in roles:
        # only instructor can edit those fields
        return ForbiddenResponse(request, "only the instructor can edit this field")
    elif isinstance(case, DisciplineCaseChair) and "DEPT" not in roles:
        # only discipline admins can edit chair fields
        return ForbiddenResponse(request, "only the Chair (or delegate) can edit this field")

    FormClass = STEP_FORM[field]
    if request.method == 'POST':
        form = FormClass(request.POST, instance=case)
        if form.is_valid():
            c = form.save()
            if field in PRE_LETTER_STEPS:
                # letter hasn't been reviewed if anything changes
                c.letter_review = False
                c.letter_sent = 'WAIT'
                c.penalty_implemented = False
                c.save()

            #LOG EVENT#
            l = LogEntry(userid=request.user.username,
                  description=("edit discipline case %s in %s: changed %s") % (c.slug, c.offering, STEP_DESC[field]),
                  related_object=c)
            l.save()
            messages.add_message(request, messages.SUCCESS, "Updated " + STEP_DESC[field] + '.')
            
            # set identical value for group members as requested
            also_contact = []
            for postfield in request.POST:
                match = also_set_re.match(postfield)
                if not match or request.POST[postfield] != "on":
                    continue
                
                field = match.group('field')
                caseid = match.group('caseid')
                cases = DisciplineCaseBase.objects.filter(id=caseid)
                if len(cases) != 1 or cases[0].group != case.group:
                    continue
                c0 = cases[0].subclass()
                if not c0.can_edit(field):
                    messages.add_message(request, messages.ERROR,
                        "Case for %s is finished: cannot update %s." % (c0.student.name(), STEP_DESC[field]))
                    continue

                if field=="contacted" and form.cleaned_data[field]=='MAIL':
                    # special case handled below
                    also_contact.append(c0)
                else:
                    setattr(c0, field, form.cleaned_data[field])
                    if field in PRE_LETTER_STEPS:
                        c0.letter_review = False
                    c0.save()
                    messages.add_message(request, messages.SUCCESS,
                        "Also updated %s for %s." % (STEP_DESC[field], c0.student.name()))
                    
            if hasattr(c, 'send_letter_now'):
                # send instructor's letter
                assert case.public_attachments_size() <= MAX_ATTACHMENTS # should be ensured by "review letter" step
                c.send_letter(_currentuser(request))
                messages.add_message(request, messages.INFO, "Letter sent to student summarizing case.")

            if hasattr(c, 'send_contact_mail'):
                # send initial contact email
                c.send_contact_email()
                messages.add_message(request, messages.INFO, "Email sent to student notifying of case.")
                for c0 in also_contact:
                    textkey = 'also-contact_email_text-' + str(c0.id)
                    if textkey in request.POST and request.POST[textkey]=="on":
                        # only send the email if text was updated too
                        c0.contacted = form.cleaned_data['contacted']
                        c0.contact_email_text = form.cleaned_data['contact_email_text']
                        c0.save()
                        messages.add_message(request, messages.SUCCESS,
                            "Also updated %s for %s." % (STEP_DESC['contacted'], c0.student.name()))
                        c0.send_contact_email()
                        messages.add_message(request, messages.INFO, "Also emailed %s." % (c0.student.name()))
                    else:
                        # if not, give an error message.
                        messages.add_message(request, messages.ERROR,
                            mark_safe('Email not sent to %s since their "Contact Email Text" was not updated. You can <a href="%s">edit their contact info</a> if you wish.'
                            % (c0.student.name(),
                                reverse('discipline.views.edit_case_info',
                                    kwargs={'field': 'contacted', 'course_slug': course_slug, 'case_slug': c0.slug}))))
            
            if isinstance(case, DisciplineCaseChair):
                return HttpResponseRedirect(reverse('discipline.views.show_chair', kwargs={'course_slug': course_slug, 'case_slug': case.slug}))
            else:
                return HttpResponseRedirect(reverse('discipline.views.show', kwargs={'course_slug': course_slug, 'case_slug': case.slug}))
    else:
        form = FormClass(instance=case)
    
    templates = DisciplineTemplate.objects.filter(field__in=form.fields.keys())
    tempaltesJSON = json.dumps([t.JSON_data() for t in templates])
    groupmembersJSON = case.groupmembersJSON()
    hasRelAct = len(case.related_activities())>0
    
    context = {'course': course, 'case': case, 'form': form,
        'templatesJSON': mark_safe(tempaltesJSON), 'groupmembersJSON': mark_safe(groupmembersJSON), 'hasRelAct': hasRelAct}
    if field == 'letter_review':
        context['currentuser'] = _currentuser(request)
    return render_to_response("discipline/edit_"+field+".html", context, context_instance=RequestContext(request))

Example 30

Project: coursys
Source File: forms.py
View license
def getattribute(value, arg, html=True):
    """Gets an attribute of an object dynamically from a string name"""
    # special cases
    if arg == 'application_status':
        return value.get_application_status_display()
    elif arg == 'senior_supervisors':
        sups = value.supervisor_set.filter(supervisor_type='SEN', removed=False)
        names = [s.sortname() for s in sups]
        if not sups:
            pot_sups = value.supervisor_set.filter(supervisor_type='POT', removed=False)
            names = [s.sortname()+"*" for s in pot_sups]
        return '; '.join(names)
    elif arg == 'supervisors':
        sups = value.supervisor_set.filter(supervisor_type__in=['SEN','COM'], removed=False)
        names = [s.sortname() for s in sups]
        return '; '.join(names)
    elif arg == 'completed_req':
        reqs = value.completedrequirement_set.all().select_related('requirement')
        return ', '.join(r.requirement.description for r in reqs)
    elif arg == 'current_status':
        return value.get_current_status_display()
    elif arg == 'active_semesters':
        return value.active_semesters_display()
    elif arg == 'campus':
        return value.get_campus_display()
    elif arg == 'gpa':
        res = value.person.gpa()
        if res:
            return res
        else:
            return ''
    elif arg == 'gender':
        return value.person.gender()
    elif arg == 'visa':
        return value.person.visa()
    elif arg == 'citizen':
        return value.person.citizen() or 'unknown'
    elif arg == 'person.emplid':
        return unicode(value.person.emplid)
    elif arg == 'email':
        if html:
            return value.person.email_mailto()
        else:
            return value.person.email()
    elif arg == 'appemail':
        if 'applic_email' in value.config:
            email = value.config['applic_email']
            if html:
                return mark_safe('<a href="mailto:%s">%s</a>' % (escape(email), escape(email)))
            else:
                return email
        else:
            return ''
    elif arg == 'scholarships':
        scholarships = [str(scholarship) for scholarship in value.scholarship_set.all()]
        return '; '.join(scholarships)
    elif arg == 'unit':
        return str(value.program.unit)
    elif '.' not in arg:
        if hasattr(value, str(arg)):
            res = getattr(value, arg)
        elif hasattr(value, 'has_key') and value.has_key(arg):
            res = value[arg]
        elif numeric_test.match(str(arg)) and len(value) > int(arg):
            res = value[int(arg)]
        else:
            res = settings.TEMPLATE_STRING_IF_INVALID
    else:
        L = arg.split('.')
        res = getattribute(getattr(value, L[0]), '.'.join(L[1:]))

    # force types to something displayable everywhere
    if isinstance(res, Semester):
        res = res.name
    elif res is None:
        res = ''
    elif type(res) not in [int, float, str, unicode]:
        res = unicode(res)

    return res

Example 31

Project: coursys
Source File: view.py
View license
@login_required
def view(request, grad_slug, section=None):
    grad, authtype, units = _can_view_student(request, grad_slug)
    if grad is None or authtype == 'student':
        return ForbiddenResponse(request)

    # uses of the cortez link routed through here to see if they're actually being used
    if 'cortez-bounce' in request.GET and 'cortezid' in grad.config:
        from log.models import LogEntry
        from django.shortcuts import redirect
        l = LogEntry(userid=request.user.username,
              description="used cortez link for %s" % (grad.slug,),
              related_object=grad )
        l.save()
        return redirect("https://cortez.cs.sfu.ca/grad/scripts/grabcurrent.asp?Identifier=" + grad.config['cortezid'])
    
    context = {
        'grad': grad, 
        'index': True, 
        'can_edit': True, 
        'authtype': authtype }

    if authtype in ['supervisor', 'graddir']:
        context['can_edit'] = False
    
    for s in all_sections:
        context[s+'_content'] = ''
    
    if 'section' in request.GET:
        # page sections fetched by AJAX calls
        section = request.GET['section']

    if section:
        if section not in all_sections:
            return NotFoundResponse(request)
        
        elif section == 'general':
            programhistory = GradProgramHistory.objects.filter(student=grad, program__unit__in=units).order_by('starting')
            context['programhistory'] = programhistory
            flag_values = grad.flags_and_values()
            context['extras'] = [ (title, grad.config[field]) for field, title in grad.tacked_on_fields if field in grad.config] 
            context['flag_values'] = flag_values
            return render(request, 'grad/view__general.html', context)

        elif section == 'supervisors':
            supervisors = Supervisor.objects.filter(student=grad, removed=False).select_related('supervisor')
            context['supervisors'] = supervisors
            return render(request, 'grad/view__supervisors.html', context)

        elif section == 'status':
            statuses = GradStatus.objects.filter(student=grad, hidden=False).order_by('start__name')
            context['statuses'] = statuses
            return render(request, 'grad/view__status.html', context)

        elif section == 'requirements':
            completed_req = CompletedRequirement.objects.filter(student=grad, removed=False)
            completed_gradreq_id = [cr.requirement_id for cr in completed_req if cr.removed==False]
            req = GradRequirement.objects.filter(program=grad.program, hidden=False)
            missing_req = req.exclude(id__in=completed_gradreq_id)
            context['completed_req'] = completed_req
            context['missing_req'] = missing_req
            return render(request, 'grad/view__requirements.html', context)

        elif section == 'scholarships':
            scholarships = Scholarship.objects.filter(student=grad, removed=False).select_related('scholarship_type').order_by('start_semester__name')
            comments = FinancialComment.objects.filter(student=grad, comment_type='SCO', removed=False).order_by('created_at')
            context['scholarships'] = scholarships
            context['scholarship_comments'] = comments
            return render(request, 'grad/view__scholarships.html', context)

        elif section == 'otherfunding':
            otherfunding = OtherFunding.objects.filter(student=grad, removed=False).order_by('semester__name')
            context['otherfunding'] = otherfunding
            return render(request, 'grad/view__otherfunding.html', context)

        elif section == 'promises':
            promises = Promise.objects.filter(student=grad, removed=False).order_by('start_semester__name')
            context['promises'] = promises
            return render(request, 'grad/view__promises.html', context)

        elif section == 'tacontracts':
            tacontracts = TAContract.objects.filter(person=grad.person, status__in=['NEW', 'SGN'])
            oldcontracts = OldTAContract.objects.filter(application__person=grad.person)
            context['tacontracts'] = tacontracts
            context['oldcontracts'] = oldcontracts
            return render(request, 'grad/view__tacontracts.html', context)
        
        elif section == 'financialcomments':
            comments = FinancialComment.objects.filter(student=grad, removed=False).order_by('created_at')
            context['financial_comments'] = comments
            return render(request, 'grad/view__financialcomments.html', context)
        
        elif section == 'letters':
            letters = Letter.objects.filter(student=grad).select_related('template').order_by('date')
            context['letters'] = letters
            return render(request, 'grad/view__letters.html', context)
        
        elif section == 'progressreports':
            progressreports = ProgressReport.objects.filter(student=grad, 
                                                            removed=False)\
                                                            .order_by('date')
            context['progress_reports'] = progressreports
            return render(request, 'grad/view__progress.html', context)
        
        elif section == 'documents':
            documents = ExternalDocument.objects.filter(student=grad, 
                                                        removed=False)\
                                                        .order_by('date')
            context['documents'] = documents
            return render(request, 'grad/view__documents.html', context)

        elif section == 'visas':
            visas = Visa.get_visas([grad.person])
            context['visas'] = visas
            return render(request, 'grad/view__visas.html', context)

        else:
            raise ValueError, "Not all sections handled by view code: " + repr(section)

    elif '_escaped_fragment_' in request.GET:
        # Implement google-suggested hash-bang workaround. Not terribly efficient, but probably uncommon.
        # https://developers.google.com/webmasters/ajax-crawling/docs/getting-started
        sections = request.GET['_escaped_fragment_'].split(',')
        for s in sections:
            resp = view(request, grad_slug, section=s)
            context[s+'_content'] = mark_safe(resp.content)

    other_grad = GradStudent.objects \
                 .filter(program__unit__in=units, person=grad.person) \
                 .exclude(id=grad.id)
    other_applicant = [x for x in other_grad if x.is_applicant()]
    other_grad = [x for x in other_grad if not x.is_applicant()]
    context['other_grad'] = other_grad
    context['other_applicant'] = other_applicant

    return render(request, 'grad/view.html', context)

Example 32

Project: django-datatable
Source File: tables.py
View license
    def __init__(self, options=None):
        self.model = getattr(options, 'model', None)

        # ajax option
        self.ajax = getattr(options, 'ajax', False)
        self.ajax_source = getattr(options, 'ajax_source', None)

        # id attribute of <table> tag
        self.id = getattr(options, 'id', None)

        # build attributes for <table> tag, use bootstrap
        # css class "table table-boarded" as default style
        attrs = getattr(options, 'attrs', {})
        attrs['class'] = 'table ' + attrs.get('class', '')
        self.attrs = mark_safe(' '.join(['%s="%s"' % (attr_name, attr)
                                         for attr_name, attr in attrs.items()]))
        # build attributes for <thead> and <tbody>
        thead_attrs = getattr(options, 'thead_attrs', {})
        self.thead_attrs = mark_safe(' '.join(['%s="%s"' % (attr_name, attr)
                                         for attr_name, attr in thead_attrs.items()]))
        tbody_attrs = getattr(options, 'tbody_attrs', {})
        self.tbody_attrs = mark_safe(' '.join(['%s="%s"' % (attr_name, attr)
                                         for attr_name, attr in tbody_attrs.items()]))

        # scrolling option
        self.scrollable = getattr(options, 'scrollable', False)
        self.scrollinner = getattr(options, 'scrollinner', "150%")
        self.fixed_columns = getattr(options, 'fixed_columns', None)
        self.fixed_columns_width = getattr(options, 'fixed_columns_width', None)

        # inspect sorting option
        self.sort = []
        for column, order in getattr(options, 'sort', []):
            if not isinstance(column, int):
                raise ValueError('Sorting option must be organized by following'
                                 ' forms: [(0, "asc"), (1, "desc")]')
            if order not in ('asc', 'desc'):
                raise ValueError('Order value must be "asc" or "desc", '
                                 '"%s" is unsupported.' % order)
            self.sort.append((column, order))

        # options for table add-on
        self.search = getattr(options, 'search', True)
        self.search_placeholder = getattr(options, 'search_placeholder', None)

        self.info = getattr(options, 'info', True)
        self.info_format = getattr(options, 'info_format', None)

        self.pagination = getattr(options, 'pagination', True)
        self.page_length = getattr(options, 'page_length', 10)
        self.pagination_first = getattr(options, 'pagination_first', None)
        self.pagination_last = getattr(options, 'pagination_last', None)
        self.pagination_prev = getattr(options, 'pagination_prev', None)
        self.pagination_next = getattr(options, 'pagination_next', None)

        self.length_menu = getattr(options, 'length_menu', True)

        self.ext_button = getattr(options, 'ext_button', False)
        self.ext_button_template = getattr(options, 'ext_button_template', None)
        self.ext_button_template_name = getattr(options, 'ext_button_template_name', None)
        self.ext_button_context = getattr(options, 'ext_button_context', None)

        self.zero_records = getattr(options, 'zero_records', u'No records')
        self.theme_css_file = getattr(options, 'theme_css_file', 'table/css/datatable.bootstrap.css')
        self.theme_js_file = getattr(options, 'theme_js_file', 'table/js/bootstrap.dataTables.js')

Example 33

Project: bugle_project
Source File: typogrify.py
View license
def caps(text):
    """Wraps multiple capital letters in ``<span class="caps">`` 
    so they can be styled with CSS. 
    
    >>> caps("A message from KU")
    u'A message from <span class="caps">KU</span>'
    
    Uses the smartypants tokenizer to not screw with HTML or with tags it shouldn't.
    
    >>> caps("<PRE>CAPS</pre> more CAPS")
    u'<PRE>CAPS</pre> more <span class="caps">CAPS</span>'

    >>> caps("A message from 2KU2 with digits")
    u'A message from <span class="caps">2KU2</span> with digits'
        
    >>> caps("Dotted caps followed by spaces should never include them in the wrap D.O.T.   like so.")
    u'Dotted caps followed by spaces should never include them in the wrap <span class="caps">D.O.T.</span>  like so.'

    All caps with with apostrophes in them shouldn't break. Only handles dump apostrophes though.
    >>> caps("JIMMY'S")
    u'<span class="caps">JIMMY\\'S</span>'

    >>> caps("<i>D.O.T.</i>HE34T<b>RFID</b>")
    u'<i><span class="caps">D.O.T.</span></i><span class="caps">HE34T</span><b><span class="caps">RFID</span></b>'
    """
    text = force_unicode(text)
    try:
        import smartypants
    except ImportError:
        if settings.DEBUG:
            raise template.TemplateSyntaxError, "Error in {% caps %} filter: The Python SmartyPants library isn't installed."
        return text
        
    tokens = smartypants._tokenize(text)
    result = []
    in_skipped_tag = False    
    
    cap_finder = re.compile(r"""(
                            (\b[A-Z\d]*        # Group 2: Any amount of caps and digits
                            [A-Z]\d*[A-Z]      # A cap string much at least include two caps (but they can have digits between them)
                            [A-Z\d']*\b)       # Any amount of caps and digits or dumb apostsrophes
                            | (\b[A-Z]+\.\s?   # OR: Group 3: Some caps, followed by a '.' and an optional space
                            (?:[A-Z]+\.\s?)+)  # Followed by the same thing at least once more
                            (?:\s|\b|$))
                            """, re.VERBOSE)

    def _cap_wrapper(matchobj):
        """This is necessary to keep dotted cap strings to pick up extra spaces"""
        if matchobj.group(2):
            return """<span class="caps">%s</span>""" % matchobj.group(2)
        else:
            if matchobj.group(3)[-1] == " ":
                caps = matchobj.group(3)[:-1]
                tail = ' '
            else:
                caps = matchobj.group(3)
                tail = ''
            return """<span class="caps">%s</span>%s""" % (caps, tail)

    tags_to_skip_regex = re.compile("<(/)?(?:pre|code|kbd|script|math)[^>]*>", re.IGNORECASE)
    
    
    for token in tokens:
        if token[0] == "tag":
            # Don't mess with tags.
            result.append(token[1])
            close_match = tags_to_skip_regex.match(token[1])
            if close_match and close_match.group(1) == None:
                in_skipped_tag = True
            else:
                in_skipped_tag = False
        else:
            if in_skipped_tag:
                result.append(token[1])
            else:
                result.append(cap_finder.sub(_cap_wrapper, token[1]))
    output = "".join(result)
    return mark_safe(output)

Example 34

Project: oioioi
Source File: controllers.py
View license
    def adjust_submission_form(self, request, form, problem_instance):
        controller = problem_instance.controller
        size_limit = controller.get_submission_size_limit(problem_instance)

        def validate_file_size(file):
            if file.size > size_limit:
                raise ValidationError(_("File size limit exceeded."))

        def validate_language(file):
            ext = controller._get_language(file, problem_instance)
            if ext not in controller.get_allowed_extensions(problem_instance):
                raise ValidationError(_(
                    "Unknown or not supported file extension."))

        def parse_problem(problem):
            available_problems = form.fields['problem_instance_id'].choices
            problem_id = None
            for (id, name) in available_problems:
                if name.find(problem) != -1:
                    if problem_id is None:
                        problem_id = id
                    else:
                        # matched more than one available problem
                        return None
            return problem_id

        form.fields['file'] = forms.FileField(required=False,
                allow_empty_file=False,
                validators=[validate_file_size, validate_language],
                label=_("File"),
                help_text=mark_safe(_(
                    "Language is determined by the file extension."
                    " It has to be one of: %s."
                    " You can paste the code below instead of"
                    " choosing file."
                    " <strong>Try drag-and-drop too!</strong>"
                ) % (', '.join(controller.get_allowed_extensions(
                        problem_instance))))
        )
        form.fields['code'] = forms.CharField(required=False,
                label=_("Code"),
                widget=forms.widgets.Textarea(attrs={'rows': 10,
                    'class': 'monospace input-xxxlarge'})
        )

        choices = [('', '')]
        choices += [(lang, lang) for lang in controller.get_allowed_languages(
                problem_instance)]
        form.fields['prog_lang'] = forms.ChoiceField(required=False,
                label=_("Programming language"),
                choices=choices,
                widget=forms.Select(attrs={'disabled': 'disabled'})
        )

        if 'dropped_solution' in request.POST:
            form.fields['code'].initial = request.POST['dropped_solution']

        # guessing problem name and extension when file dragged and dropped
        if 'dropped_solution_name' in request.POST:
            # do not validate blank fields this time
            form.is_bound = False

            fname = request.POST['dropped_solution_name']
            if fname.count('.') == 1:
                [problem, ext] = fname.split('.', 1)
                if 'problem_instance_id' not in request.POST:
                    form.fields['problem_instance_id'].initial = \
                            parse_problem(problem)
                if 'prog_lang' not in request.POST:
                    form.fields['prog_lang'].initial = \
                            controller.parse_language_by_extension(ext,
                                    problem_instance)

        if request.contest and is_contest_admin(request):
            form.fields['user'] = UserSelectionField(
                    label=_("User"),
                    hints_url=reverse('contest_user_hints',
                            kwargs={'contest_id': request.contest.id}),
                    initial=request.user)

            def clean_user():
                try:
                    user = form.cleaned_data['user']
                    if user == request.user:
                        return user
                    if not request.user.is_superuser:
                        controller.registration_controller() \
                            .filter_participants(
                                User.objects.filter(pk=user.pk)).get()
                    return user
                except User.DoesNotExist:
                    raise forms.ValidationError(_(
                            "User does not exist or "
                            "you do not have enough privileges"))
            form.clean_user = clean_user
            form.fields['kind'] = forms.ChoiceField(choices=[
                ('NORMAL', _("Normal")), ('IGNORED', _("Ignored"))],
                initial=form.kind, label=_("Kind"))

Example 35

Project: SmartElect
Source File: utils.py
View license
def update_center_table(_file):
    """
    Import voting centers from a CSV file. It creates or updates.
    Safe to run repeatedly; if a voting center already exists with the
    center ID being imported it will update it if needed.

    Returns a 2-tuple of (message, successful), where message is status information (including
    errors, if any) and successful is a Boolean.

    If any errors are reported, no imports occur.
    """
    errors = []
    reader = UnicodeReader(_file)

    stats = {
        'num_blank': 0,
        'num_created': 0,
        'num_dupes': 0,
        'num_updated': 0,
    }

    line_number = 1
    columns = ", ".join(CSV_FIELDS)
    headers = reader.next()  # gets rid of the header row

    if not len(headers) == len(CSV_FIELDS):
        return PARSING_ERROR.format(line_number=1, columns=columns), False

    for index, header in enumerate(headers):
        if not header == CSV_FIELDS[index]:
            return PARSING_ERROR.format(line_number=1, columns=columns), False

    # If errors happen during the import and we want Django to roll
    # back the transaction, we need to exit the transaction context
    # with an exception (eventually).
    try:
        with transaction.atomic():
            for row in reader:
                line_number += 1
                import_center_csv_row(columns, row, line_number, stats, errors)

            if errors:
                errors.insert(0, force_text(ERRORS_OCCURRED_MESSAGE))
                message = mark_safe('<br><br>'.join(errors))
                logger.debug(errors)
                # trigger rollback:
                raise CenterImportFailedError
            else:
                message = STATUS_MESSAGE.format(blank=stats['num_blank'],
                                                created=stats['num_created'],
                                                dupes=stats['num_dupes'],
                                                updated=stats['num_updated'])
    except CenterImportFailedError:
        # Just to trigger a rollback
        logger.debug("Rolled back all imported centers due to errors.")
    else:
        logger.debug("No errors during import, will commit changes if nothing else goes wrong "
                     "during the request.")

    return message, not bool(errors)

Example 36

Project: splunk-webframework
Source File: admin_list.py
View license
def result_headers(cl):
    """
    Generates the list column headers.
    """
    ordering_field_columns = cl.get_ordering_field_columns()
    for i, field_name in enumerate(cl.list_display):
        text, attr = label_for_field(field_name, cl.model,
            model_admin = cl.model_admin,
            return_attr = True
        )
        if attr:
            # Potentially not sortable

            # if the field is the action checkbox: no sorting and special class
            if field_name == 'action_checkbox':
                yield {
                    "text": text,
                    "class_attrib": mark_safe(' class="action-checkbox-column"'),
                    "sortable": False,
                }
                continue

            admin_order_field = getattr(attr, "admin_order_field", None)
            if not admin_order_field:
                # Not sortable
                yield {
                    "text": text,
                    "sortable": False,
                }
                continue

        # OK, it is sortable if we got this far
        th_classes = ['sortable']
        order_type = ''
        new_order_type = 'asc'
        sort_priority = 0
        sorted = False
        # Is it currently being sorted on?
        if i in ordering_field_columns:
            sorted = True
            order_type = ordering_field_columns.get(i).lower()
            sort_priority = list(ordering_field_columns).index(i) + 1
            th_classes.append('sorted %sending' % order_type)
            new_order_type = {'asc': 'desc', 'desc': 'asc'}[order_type]

        # build new ordering param
        o_list_primary = [] # URL for making this field the primary sort
        o_list_remove  = [] # URL for removing this field from sort
        o_list_toggle  = [] # URL for toggling order type for this field
        make_qs_param = lambda t, n: ('-' if t == 'desc' else '') + str(n)

        for j, ot in ordering_field_columns.items():
            if j == i: # Same column
                param = make_qs_param(new_order_type, j)
                # We want clicking on this header to bring the ordering to the
                # front
                o_list_primary.insert(0, param)
                o_list_toggle.append(param)
                # o_list_remove - omit
            else:
                param = make_qs_param(ot, j)
                o_list_primary.append(param)
                o_list_toggle.append(param)
                o_list_remove.append(param)

        if i not in ordering_field_columns:
            o_list_primary.insert(0, make_qs_param(new_order_type, i))


        yield {
            "text": text,
            "sortable": True,
            "sorted": sorted,
            "ascending": order_type == "asc",
            "sort_priority": sort_priority,
            "url_primary": cl.get_query_string({ORDER_VAR: '.'.join(o_list_primary)}),
            "url_remove": cl.get_query_string({ORDER_VAR: '.'.join(o_list_remove)}),
            "url_toggle": cl.get_query_string({ORDER_VAR: '.'.join(o_list_toggle)}),
            "class_attrib": format_html(' class="{0}"', ' '.join(th_classes))
                            if th_classes else '',
        }

Example 37

View license
@register.filter(is_safe=True)
def floatformat(text, arg=-1):
    """
    Displays a float to a specified number of decimal places.

    If called without an argument, it displays the floating point number with
    one decimal place -- but only if there's a decimal place to be displayed:

    * num1 = 34.23234
    * num2 = 34.00000
    * num3 = 34.26000
    * {{ num1|floatformat }} displays "34.2"
    * {{ num2|floatformat }} displays "34"
    * {{ num3|floatformat }} displays "34.3"

    If arg is positive, it will always display exactly arg number of decimal
    places:

    * {{ num1|floatformat:3 }} displays "34.232"
    * {{ num2|floatformat:3 }} displays "34.000"
    * {{ num3|floatformat:3 }} displays "34.260"

    If arg is negative, it will display arg number of decimal places -- but
    only if there are places to be displayed:

    * {{ num1|floatformat:"-3" }} displays "34.232"
    * {{ num2|floatformat:"-3" }} displays "34"
    * {{ num3|floatformat:"-3" }} displays "34.260"

    If the input float is infinity or NaN, the (platform-dependent) string
    representation of that value will be displayed.
    """

    try:
        input_val = force_text(text)
        d = Decimal(input_val)
    except UnicodeEncodeError:
        return ''
    except InvalidOperation:
        if input_val in special_floats:
            return input_val
        try:
            d = Decimal(force_text(float(text)))
        except (ValueError, InvalidOperation, TypeError, UnicodeEncodeError):
            return ''
    try:
        p = int(arg)
    except ValueError:
        return input_val

    try:
        m = int(d) - d
    except (ValueError, OverflowError, InvalidOperation):
        return input_val

    if not m and p < 0:
        return mark_safe(formats.number_format('%d' % (int(d)), 0))

    if p == 0:
        exp = Decimal(1)
    else:
        exp = Decimal('1.0') / (Decimal(10) ** abs(p))
    try:
        # Set the precision high enough to avoid an exception, see #15789.
        tupl = d.as_tuple()
        units = len(tupl[1]) - tupl[2]
        prec = abs(p) + units + 1

        # Avoid conversion to scientific notation by accessing `sign`, `digits`
        # and `exponent` from `Decimal.as_tuple()` directly.
        sign, digits, exponent = d.quantize(exp, ROUND_HALF_UP,
            Context(prec=prec)).as_tuple()
        digits = [six.text_type(digit) for digit in reversed(digits)]
        while len(digits) <= abs(exponent):
            digits.append('0')
        digits.insert(-exponent, '.')
        if sign:
            digits.append('-')
        number = ''.join(reversed(digits))
        return mark_safe(formats.number_format(number, abs(p)))
    except InvalidOperation:
        return input_val

Example 38

View license
@register.filter(is_safe=True, needs_autoescape=True)
def unordered_list(value, autoescape=None):
    """
    Recursively takes a self-nested list and returns an HTML unordered list --
    WITHOUT opening and closing <ul> tags.

    The list is assumed to be in the proper format. For example, if ``var``
    contains: ``['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]``,
    then ``{{ var|unordered_list }}`` would return::

        <li>States
        <ul>
                <li>Kansas
                <ul>
                        <li>Lawrence</li>
                        <li>Topeka</li>
                </ul>
                </li>
                <li>Illinois</li>
        </ul>
        </li>
    """
    if autoescape:
        escaper = conditional_escape
    else:
        escaper = lambda x: x
    def convert_old_style_list(list_):
        """
        Converts old style lists to the new easier to understand format.

        The old list format looked like:
            ['Item 1', [['Item 1.1', []], ['Item 1.2', []]]

        And it is converted to:
            ['Item 1', ['Item 1.1', 'Item 1.2]]
        """
        if not isinstance(list_, (tuple, list)) or len(list_) != 2:
            return list_, False
        first_item, second_item = list_
        if second_item == []:
            return [first_item], True
        try:
            # see if second item is iterable
            iter(second_item)
        except TypeError:
            return list_, False
        old_style_list = True
        new_second_item = []
        for sublist in second_item:
            item, old_style_list = convert_old_style_list(sublist)
            if not old_style_list:
                break
            new_second_item.extend(item)
        if old_style_list:
            second_item = new_second_item
        return [first_item, second_item], old_style_list
    def _helper(list_, tabs=1):
        indent = '\t' * tabs
        output = []

        list_length = len(list_)
        i = 0
        while i < list_length:
            title = list_[i]
            sublist = ''
            sublist_item = None
            if isinstance(title, (list, tuple)):
                sublist_item = title
                title = ''
            elif i < list_length - 1:
                next_item = list_[i+1]
                if next_item and isinstance(next_item, (list, tuple)):
                    # The next item is a sub-list.
                    sublist_item = next_item
                    # We've processed the next item now too.
                    i += 1
            if sublist_item:
                sublist = _helper(sublist_item, tabs+1)
                sublist = '\n%s<ul>\n%s\n%s</ul>\n%s' % (indent, sublist,
                                                         indent, indent)
            output.append('%s<li>%s%s</li>' % (indent,
                    escaper(force_text(title)), sublist))
            i += 1
        return '\n'.join(output)
    value, converted = convert_old_style_list(value)
    return mark_safe(_helper(value))

Example 39

View license
def result_headers(context, cl): 
    """
    Generates the list column headers.
    """
    for i, field_name in enumerate(cl.list_display):
        text, attr = label_for_field(field_name, cl.model, return_attr=True)
        if attr:
            # Potentially not sortable

            # if the field is the action checkbox: no sorting and special class
            if field_name == 'action_checkbox':
                yield {
                    "text": text,
                    "class_attrib": mark_safe(' class="action-checkbox-column"'),
                    "sortable": False,
                }
                continue

#            if other_fields like Edit, Visualize, etc:
                # Not sortable
#                yield {
#                    "text": text,
#                    "class_attrib": format_html(' class="column-{0}"', field_name),
#                    "sortable": False,
#                }
#                continue

        # OK, it is sortable if we got this far
        th_classes = ['sortable', 'column-{0}'.format(field_name)]
        ascending = None
        is_sorted = False
        # Is it currently being sorted on?
        if context.get('current_sort_field') == str(i + 1):
            is_sorted = True
            ascending = False
            th_classes.append('sorted descending')
        elif context.get('current_sort_field') == '-'+str(i + 1):
            is_sorted = True
            ascending = True
            th_classes.append('sorted ascending')

        if 'request' in context:
            url = context['request'].path
        else:
            url = "./"

### TODO: when start using action_checkbox use i instead of i + 1. This +1 is to correct enumerate index
        # builds url
        url += "?sort_by="

        if ascending is False:
            url += "-"
        url += str(i + 1)

        if 'getsortvars' in context:
            extra_vars = context['getsortvars']
        else:
            if 'request' in context:
                request = context['request']
                getvars = request.GET.copy()
                if 'sort_by' in getvars:
                    del getvars['sort_by']
                if len(getvars.keys()) > 0:
                    context['getsortvars'] = "&%s" % getvars.urlencode()
                else:
                    context['getsortvars'] = ''
                extra_vars = context['getsortvars']

        # append other vars to url
        url += extra_vars

        yield {
            "text": text,
            "url": url,
            "sortable": True,
            "sorted": is_sorted,
            "ascending": ascending,
            "class_attrib": format_html(' class="{0}"', ' '.join(th_classes)) if th_classes else '',
        }

Example 40

Project: django-forms-builder
Source File: forms.py
View license
    def rows(self, csv=False):
        """
        Returns each row based on the selected criteria.
        """

        # Store the index of each field against its ID for building each
        # entry row with columns in the correct order. Also store the IDs of
        # fields with a type of FileField or Date-like for special handling of
        # their values.
        field_indexes = {}
        file_field_ids = []
        date_field_ids = []
        for field in self.form_fields:
            if self.posted_data("field_%s_export" % field.id):
                field_indexes[field.id] = len(field_indexes)
                if field.is_a(fields.FILE):
                    file_field_ids.append(field.id)
                elif field.is_a(*fields.DATES):
                    date_field_ids.append(field.id)
        num_columns = len(field_indexes)
        include_entry_time = self.posted_data("field_0_export")
        if include_entry_time:
            num_columns += 1

        # Get the field entries for the given form and filter by entry_time
        # if specified.
        model = self.fieldentry_model
        field_entries = model.objects.filter(entry__form=self.form
            ).order_by("-entry__id").select_related("entry")
        if self.posted_data("field_0_filter") == FILTER_CHOICE_BETWEEN:
            time_from = self.posted_data("field_0_from")
            time_to = self.posted_data("field_0_to")
            if time_from and time_to:
                field_entries = field_entries.filter(
                    entry__entry_time__range=(time_from, time_to))

        # Loop through each field value ordered by entry, building up each
        # entry as a row. Use the ``valid_row`` flag for marking a row as
        # invalid if it fails one of the filtering criteria specified.
        current_entry = None
        current_row = None
        valid_row = True
        for field_entry in field_entries:
            if field_entry.entry_id != current_entry:
                # New entry, write out the current row and start a new one.
                if valid_row and current_row is not None:
                    if not csv:
                        current_row.insert(0, current_entry)
                    yield current_row
                current_entry = field_entry.entry_id
                current_row = [""] * num_columns
                valid_row = True
                if include_entry_time:
                    current_row[-1] = field_entry.entry.entry_time
            field_value = field_entry.value or ""
            # Check for filter.
            field_id = field_entry.field_id
            filter_type = self.posted_data("field_%s_filter" % field_id)
            filter_args = None
            if filter_type:
                if filter_type == FILTER_CHOICE_BETWEEN:
                    f, t = "field_%s_from" % field_id, "field_%s_to" % field_id
                    filter_args = [self.posted_data(f), self.posted_data(t)]
                else:
                    field_name = "field_%s_contains" % field_id
                    filter_args = self.posted_data(field_name)
                    if filter_args:
                        filter_args = [filter_args]
            if filter_args:
                # Convert dates before checking filter.
                if field_id in date_field_ids:
                    try:
                        y, m, d = field_value.split(" ")[0].split("-")
                    except ValueError:
                        filter_args.append(field_value)
                    else:
                        dte = date(int(y), int(m), int(d))
                        filter_args.append(dte)
                else:
                    filter_args.append(field_value)
                filter_func = FILTER_FUNCS[filter_type]
                if not filter_func(*filter_args):
                    valid_row = False
            # Create download URL for file fields.
            if field_entry.value and field_id in file_field_ids:
                url = reverse("admin:form_file", args=(field_entry.id,))
                field_value = self.request.build_absolute_uri(url)
                if not csv:
                    parts = (field_value, split(field_entry.value)[1])
                    field_value = mark_safe("<a href=\"%s\">%s</a>" % parts)
            # Only use values for fields that were selected.
            try:
                current_row[field_indexes[field_id]] = field_value
            except KeyError:
                pass
        # Output the final row.
        if valid_row and current_row is not None:
            if not csv:
                current_row.insert(0, current_entry)
            yield current_row

Example 41

Project: mezzanine
Source File: forms.py
View license
    def rows(self, csv=False):
        """
        Returns each row based on the selected criteria.
        """

        # Store the index of each field against its ID for building each
        # entry row with columns in the correct order. Also store the IDs of
        # fields with a type of FileField or Date-like for special handling of
        # their values.
        field_indexes = {}
        file_field_ids = []
        date_field_ids = []
        for field in self.form_fields:
            if self.cleaned_data["field_%s_export" % field.id]:
                field_indexes[field.id] = len(field_indexes)
                if field.is_a(fields.FILE):
                    file_field_ids.append(field.id)
                elif field.is_a(*fields.DATES):
                    date_field_ids.append(field.id)
        num_columns = len(field_indexes)
        include_entry_time = self.cleaned_data["field_0_export"]
        if include_entry_time:
            num_columns += 1

        # Get the field entries for the given form and filter by entry_time
        # if specified.
        field_entries = FieldEntry.objects.filter(
            entry__form=self.form).order_by(
            "-entry__id").select_related("entry")
        if self.cleaned_data["field_0_filter"] == FILTER_CHOICE_BETWEEN:
            time_from = self.cleaned_data["field_0_from"]
            time_to = self.cleaned_data["field_0_to"]
            if time_from and time_to:
                field_entries = field_entries.filter(
                    entry__entry_time__range=(time_from, time_to))

        # Loop through each field value ordered by entry, building up each
        # entry as a row. Use the ``valid_row`` flag for marking a row as
        # invalid if it fails one of the filtering criteria specified.
        current_entry = None
        current_row = None
        valid_row = True
        for field_entry in field_entries:
            if field_entry.entry_id != current_entry:
                # New entry, write out the current row and start a new one.
                if valid_row and current_row is not None:
                    if not csv:
                        current_row.insert(0, current_entry)
                    yield current_row
                current_entry = field_entry.entry_id
                current_row = [""] * num_columns
                valid_row = True
                if include_entry_time:
                    current_row[-1] = field_entry.entry.entry_time
            field_value = field_entry.value or ""
            # Check for filter.
            field_id = field_entry.field_id
            filter_type = self.cleaned_data.get("field_%s_filter" % field_id)
            filter_args = None
            if filter_type:
                if filter_type == FILTER_CHOICE_BETWEEN:
                    f, t = "field_%s_from" % field_id, "field_%s_to" % field_id
                    filter_args = [self.cleaned_data[f], self.cleaned_data[t]]
                else:
                    field_name = "field_%s_contains" % field_id
                    filter_args = self.cleaned_data[field_name]
                    if filter_args:
                        filter_args = [filter_args]
            if filter_args:
                # Convert dates before checking filter.
                if field_id in date_field_ids:
                    y, m, d = field_value.split(" ")[0].split("-")
                    dte = date(int(y), int(m), int(d))
                    filter_args.append(dte)
                else:
                    filter_args.append(field_value)
                filter_func = FILTER_FUNCS[filter_type]
                if not filter_func(*filter_args):
                    valid_row = False
            # Create download URL for file fields.
            if field_entry.value and field_id in file_field_ids:
                url = reverse("admin:form_file", args=(field_entry.id,))
                field_value = self.request.build_absolute_uri(url)
                if not csv:
                    parts = (field_value, split(field_entry.value)[1])
                    field_value = mark_safe("<a href=\"%s\">%s</a>" % parts)
            # Only use values for fields that were selected.
            try:
                current_row[field_indexes[field_id]] = field_value
            except KeyError:
                pass
        # Output the final row.
        if valid_row and current_row is not None:
            if not csv:
                current_row.insert(0, current_entry)
            yield current_row

Example 42

Project: django-treebeard
Source File: admin_tree.py
View license
def items_for_result(cl, result, form):
    """
    Generates the actual list of data.

    @jjdelc:
    This has been shamelessly copied from original
    django.contrib.admin.templatetags.admin_list.items_for_result
    in order to alter the dispay for the first element
    """
    first = True
    pk = cl.lookup_opts.pk.attname
    for field_name in cl.list_display:
        result_repr, row_class = get_result_and_row_class(cl, field_name,
                                                          result)
        # If list_display_links not defined, add the link tag to the
        # first field
        if (first and not cl.list_display_links) or \
           field_name in cl.list_display_links:
            table_tag = {True: 'th', False: 'td'}[first]
            # This spacer indents the nodes based on their depth
            spacer = get_spacer(first, result)
            # This shows a collapse or expand link for nodes with childs
            collapse = get_collapse(result)
            # Add a <td/> before the first col to show the drag handler
            drag_handler = get_drag_handler(first)
            first = False
            url = cl.url_for_result(result)
            # Convert the pk to something that can be used in Javascript.
            # Problem cases are long ints (23L) and non-ASCII strings.
            if cl.to_field:
                attr = str(cl.to_field)
            else:
                attr = pk
            value = result.serializable_value(attr)
            result_id = repr(force_str(value))[1:]
            onclickstr = (
                ' onclick="opener.dismissRelatedLookupPopup(window, %s);'
                ' return false;"')
            yield mark_safe(
                u('%s<%s%s>%s %s <a href="%s"%s>%s</a></%s>') % (
                    drag_handler, table_tag, row_class, spacer, collapse, url,
                    (cl.is_popup and onclickstr % result_id or ''),
                    conditional_escape(result_repr), table_tag))
        else:
            # By default the fields come from ModelAdmin.list_editable, but if
            # we pull the fields out of the form instead of list_editable
            # custom admins can provide fields on a per request basis
            if (
                    form and
                    field_name in form.fields and
                    not (
                        field_name == cl.model._meta.pk.name and
                        form[cl.model._meta.pk.name].is_hidden
                    )
            ):
                bf = form[field_name]
                result_repr = mark_safe(force_str(bf.errors) + force_str(bf))
            yield format_html(u('<td{0}>{1}</td>'), row_class, result_repr)
    if form and not form[cl.model._meta.pk.name].is_hidden:
        yield format_html(u('<td>{0}</td>'),
                          force_str(form[cl.model._meta.pk.name]))

Example 43

Project: django-fretboard
Source File: helpers.py
View license
def convert_links(text, trim_url_limit=None, nofollow=False, autoescape=False):
    """
    Finds URLs in text and attempts to handle correctly.
    Heavily based on django.utils.html.urlize
    With the additions of attempting to embed media links, particularly images.

    Works on http://, https://, www. links, and also on links ending in one of
    the original seven gTLDs (.com, .edu, .gov, .int, .mil, .net, and .org).

    Links can have trailing punctuation (periods, commas, close-parens) and
    leading punctuation (opening parens) and it'll still do the right thing.

    """

    safe_input = isinstance(text, SafeData)
    words = word_split_re.split(force_text(text))
    for i, word in enumerate(words):
        if '.' in word or ':' in word:
            # Deal with punctuation.
            lead, middle, trail = '', word, ''
            for punctuation in TRAILING_PUNCTUATION:
                if middle.endswith(punctuation):
                    middle = middle[:-len(punctuation)]
                    trail = punctuation + trail
            for opening, closing in WRAPPING_PUNCTUATION:
                if middle.startswith(opening):
                    middle = middle[len(opening):]
                    lead = lead + opening
                # Keep parentheses at the end only if they're balanced.
                if (middle.endswith(closing)
                    and middle.count(closing) == middle.count(opening) + 1):
                    middle = middle[:-len(closing)]
                    trail = closing + trail

            # Make URL we want to point to.
            url = None
            if simple_url_re.match(middle):
                url = smart_urlquote(middle)
            elif simple_url_2_re.match(middle):
                url = smart_urlquote('http://%s' % middle)
            elif not ':' in middle and simple_email_re.match(middle):
                local, domain = middle.rsplit('@', 1)
                try:
                    domain = domain.encode('idna').decode('ascii')
                except UnicodeError:
                    continue
            if url:
                u = url.lower()
                if autoescape and not safe_input:
                    lead, trail = escape(lead), escape(trail)
                    url = escape(url)

                # Photos
                if u.endswith('.jpg') or u.endswith('.gif') or u.endswith('.png'):
                    middle = '<img src="%s">' % url

                # Youtube
                #'https://www.youtube.com/watch?v=gkqXgaUuxZg'
                elif 'youtube.com/watch' in url:
                    parsed = urlparse.urlsplit(url)
                    query  = urlparse.parse_qs(parsed.query)
                    token  = query.get('v')
                    if token and len(token) > 0:
                        middle = '<iframe src="http://www.youtube.com/embed/%s" height="320" width="100%%"></iframe>' % token[0]
                    else:
                        middle = url
                elif 'youtu.be/' in url:
                    try:
                        token = url.rsplit('/', 1)[1]
                        middle = '<iframe src="http://www.youtube.com/embed/' + token + '" height="320" width="100%%"></iframe>'
                    except IndexError:
                        middle = url

                words[i] = mark_safe('%s%s%s' % (lead, middle, trail))
            else:
                if safe_input:
                    words[i] = mark_safe(word)
                elif autoescape:
                    words[i] = escape(word)
        elif safe_input:
            words[i] = mark_safe(word)
        elif autoescape:
            words[i] = escape(word)
    return ''.join(words)

Example 44

Project: Tango
Source File: autotag_content.py
View license
def autotag(content_object, text):
    """
    Takes a given block of text and tags it according to models and fields defined in settings:
    
    AUTOTAG_CONTENT = (
      {
        'model'      : 'schools.school',
        'field'      : 'school',                
        'check'      : 'is_active',               
        'm2m_field'  : 'articles',
        'reverse_m2m': 'politicians',
       },
       ... etc ...
    )
    
    THE FIELDS...
    model: 
        the app and model to check
    field:
        the particular field/value you are matching in the text
    check:
        an optional field to filter by. Maybe. If we can figure out how to do it...
    m2m_field:
        Optional. Will add the current object to a m2m field on the remote object.
        For example, if you are auto_tagging schools in articles
        you can add the article to the schools "articles" field.
    reverse_m2m:
        Optional. Will add the remote object to a m2m field on the current object.
        For example, politicians can be a m2m on articles in some cases.
        If you were tagging politicians in articles, this would add the politician
        to the article's  "politicians" field.
        
    Do NOT attempt to use both m2m and reverse_m2m on the same thing.
    """
    try:
        tag_settings = settings.AUTOTAG_CONTENT
    except:
        # print "unable to get settings"
        return text
        #return "Tag settings have not been defined. "

    #print "have tag settings, attempting to tag"
    for item in tag_settings:
        #print item
        # make sure this thing is actually an installed app
        app_label     = item['model'].split('.')[0]
        model_name    = item['model'].split('.')[1]
        field_name    = item['field']
        # this try/except may be a bad idea. Maybe we WANT it to blow up.
        try:
            # model is what we're autotagging against (politicians, schools, etc)
            # field is the field we're checking (name, etc)
            content_type = ContentType.objects.get(app_label=app_label, model=model_name)
            model        = content_type.model_class()
            field        = model._meta.get_field(field_name)
            if 'm2m_field' in item:
                m2m_field  =  model._meta.get_field(item['m2m_field'])
            else:
                m2m_field = None
            objects = model.objects.all()

            for obj in objects:
                value = getattr(obj, field.name)     # get the value from the field name
                if m2m_field:
                    m2m_values = getattr(obj, m2m_field.name)
                else:
                    m2m_values = None
                if not value:
                    continue
                # add spaces to avoid partial word matches.
                # note: this totally hoses value match before comma and at end of sentence,
                # but I'm not sure what to do about it.
                checkvalues = [' {} '.format(value), ' {}, '.format(value), ' {}.'.format(value)]
                # print checkvalues
                matched = False
                for checkvalue in checkvalues:
                    if checkvalue in text and matched == False:   # Make sure it's in there, and not done already
                        replacement = '<a href="{}" title="More on {}">{}</a>'.format(obj.get_absolute_url(), value, value)
                        text = text.replace(value, replacement, 1)
                        matched = True
                        #print text
                        if m2m_values:
                            #print "attempting to establish m2m relationship"
                            m2m_values.add(content_object)
                            #print 'established m2m'
                        if 'reverse_m2m' in item:
                            #print 'attempting reverse m2m'
                            reverse_m2m = content_object.get_field(item['reverse_m2m'])
                            reverse_m2m_values = getattr(content_object, reverse_m2m.name)
                            reverse_m2m_values.add(obj)
                            #print 'established reverse m2m'
        except Exception as error:
            return "Error: {}".format(error)

    # now do the phrases defined in autotagger models
    for tag in AutoTag.objects.all():
        # print tag.phrase
        if tag.phrase in text and content_object._meta.app_label == 'articles':
            tag.articles.add(content_object.id)
            if tag.content_object:  # since we have a content object, go ahead and link over to it.
                try:  # wrapped in case get_absolute_url doesn't exist.
                    replacement = '<a href="{}" title="More on {}">{}</a>'.format(tag.content_object.get_absolute_url(), tag.phrase, tag.phrase)
                    text = text.replace(tag.phrase, replacement, 1)
                except:
                    pass
    return mark_safe(text)

Example 45

Project: tendenci
Source File: forms.py
View license
    def __init__(self, form, user, *args, **kwargs):
        """
        Dynamically add each of the form fields for the given form model
        instance and its related field model instances.
        """
        self.user = user
        self.form = form
        self.form_fields = form.fields.visible().order_by('position')
        self.auto_fields = form.fields.auto_fields().order_by('position')
        super(FormForForm, self).__init__(*args, **kwargs)

        def add_fields(form, form_fields):
            for field in form_fields:
                field_key = "field_%s" % field.id
                if "/" in field.field_type:
                    field_class, field_widget = field.field_type.split("/")
                else:
                    field_class, field_widget = field.field_type, None

                if field.field_type == 'EmailVerificationField':
                    one_email = get_setting('module', 'forms', 'one_email')
                    if one_email:
                        field_class = forms.EmailField
                    else:
                        field_class = EmailVerificationField

                elif field.field_type == 'BooleanField' and len(field.choices) > 0:
                    field_class = forms.MultipleChoiceField
                    field_widget = 'django.forms.CheckboxSelectMultiple'

                elif field.field_type == 'CountryField' or field.field_type == 'StateProvinceField':
                    field_class = getattr(forms, 'ChoiceField')
                else:
                    field_class = getattr(forms, field_class)
                field_args = {"label": mark_safe(field.label), "required": field.required}
                arg_names = field_class.__init__.im_func.func_code.co_varnames
                if "max_length" in arg_names:
                    field_args["max_length"] = FIELD_MAX_LENGTH
                if "choices" in arg_names:
                    field_args["choices"] = field.get_choices()
                    #field_args["choices"] = zip(choices, choices)
                if "initial" in arg_names:
                    default = field.default.lower()
                    if field_class == "BooleanField":
                        if default == "checked" or default == "true" or \
                            default == "on" or default == "1":
                                default = True
                        else:
                            default = False
                    field_args["initial"] = field.default

                if field_widget is not None:
                    module, widget = field_widget.rsplit(".", 1)
                    field_args["widget"] = getattr(import_module(module), widget)

                if field.field_function == 'EmailFirstName':
                    field_args["max_length"] = FIELD_FNAME_LENGTH
                elif field.field_function == 'EmailLastName':
                    field_args["max_length"] = FIELD_LNAME_LENGTH
                elif field.field_function == 'EmailFullName':
                    field_args["max_length"] = FIELD_NAME_LENGTH
                elif field.field_function == 'EmailPhoneNumber':
                    field_args["max_length"] = FIELD_PHONE_LENGTH
                elif field.field_type == 'FileField':
                    field_args["validators"] = [FileValidator()]

                form.fields[field_key] = field_class(**field_args)

                if not field_class == EmailVerificationField:
                    form.fields[field_key].widget.attrs['title'] = field.label
                    form.fields[field_key].widget.attrs['class'] = 'formforform-field'
                else:
                    form.fields[field_key].widget.widgets[0].attrs['class'] += ' formforform-field'
                    form.fields[field_key].widget.widgets[1].attrs['class'] += ' formforform-field'

                if form.fields[field_key].widget.__class__.__name__.lower() == 'selectdatewidget':
                    form.fields[field_key].widget.years = range(1920, THIS_YEAR + 10)

        def add_pricing_fields(form, formforform):
            # include pricing options if any
            if (formforform.custom_payment or formforform.recurring_payment) and formforform.pricing_set.all():

                currency_symbol = get_setting('site', 'global', 'currencysymbol')

                pricing_options = []
                for pricing in formforform.pricing_set.all():

                    if pricing.price == None:
                        pricing_options.append(
                            (pricing.pk, mark_safe(
                                '<input type="text" class="custom-price" name="custom_price_%s" value="%s"/> <strong>%s</strong><br>%s' %
                                (pricing.pk, form.data.get('custom_price_%s' %pricing.pk, unicode()), pricing.label, pricing.description)))
                        )
                    else:
                        if formforform.recurring_payment:
                            pricing_options.append(
                                (pricing.pk, mark_safe('<strong>%s per %s %s - %s</strong><br>%s' %
                                                        (tcurrency(pricing.price),
                                                         pricing.billing_frequency, pricing.billing_period,
                                                         pricing.label, pricing.description)))
                            )
                        else:
                            pricing_options.append(
                                (pricing.pk, mark_safe('<strong>%s %s</strong><br>%s' %
                                                       (tcurrency(pricing.price),
                                                        pricing.label, pricing.description)))
                            )

                form.fields['pricing_option'] = forms.ChoiceField(
                    label=_('Pricing'),
                    choices = pricing_options,
                    widget=forms.RadioSelect(attrs={'class': 'pricing-field'})
                )

                form.fields['payment_option'] = forms.ModelChoiceField(
                        label=_('Payment Method'),
                        empty_label=None,
                        queryset=formforform.payment_methods.all(),
                        widget=forms.RadioSelect(attrs={'class': 'payment-field'}),
                        initial=1,
                    )

        if self.form.pricing_position < self.form.fields_position:
            add_pricing_fields(self, self.form)
            add_fields(self, self.form_fields)
        else:
            add_fields(self, self.form_fields)
            add_pricing_fields(self, self.form)

        if not self.user.is_authenticated() and get_setting('site', 'global', 'captcha'): # add captcha if not logged in
            self.fields['captcha'] = CaptchaField(label=_('Type the code below'))

        self.add_form_control_class()

Example 46

Project: tendenci
Source File: lib.py
View license
def send_templated_mail(template_name, email_context, recipients, sender=None, bcc=None, fail_silently=False, files=None):
    """
    send_templated_mail() is a warpper around Django's e-mail routines that
    allows us to easily send multipart (text/plain & text/html) e-mails using
    templates that are stored in the database. This lets the admin provide
    both a text and a HTML template for each message.

    template_name is the slug of the template to use for this message (see
        models.EmailTemplate)

    email_context is a dictionary to be used when rendering the template

    recipients can be either a string, eg '[email protected]', or a list of strings.

    sender should contain a string, eg 'My Site <[email protected]>'. If you leave it
        blank, it'll use settings.DEFAULT_FROM_EMAIL as a fallback.

    bcc is an optional list of addresses that will receive this message as a
        blind carbon copy.

    fail_silently is passed to Django's mail routine. Set to 'True' to ignore
        any errors at send time.

    files can be a list of tuple. Each tuple should be a filename to attach, 
        along with the File objects to be read. files can be blank.

    """
    from django import VERSION
    from django.conf import settings
    from django.core.mail import EmailMultiAlternatives
    from django.template import loader, Context

    from tendenci.apps.helpdesk.models import EmailTemplate
    from tendenci.apps.helpdesk.settings import HELPDESK_EMAIL_SUBJECT_TEMPLATE
    import os

    # RemovedInDjango110Warning: render() must be called with a dict, not a Context.
    if VERSION >= (1, 8):
        context = email_context
    else:
        context = Context(email_context)

    if hasattr(context['queue'], 'locale'):
        locale = getattr(context['queue'], 'locale', '')
    else:
        locale = context['queue'].get('locale', 'en')
    if not locale:
        locale = 'en'

    t = None
    try:
        t = EmailTemplate.objects.get(template_name__iexact=template_name, locale=locale)
    except EmailTemplate.DoesNotExist:
        pass

    if not t:
        try:
            t = EmailTemplate.objects.get(template_name__iexact=template_name, locale__isnull=True)
        except EmailTemplate.DoesNotExist:
            logger.warning('template "%s" does not exist, no mail sent' %
			   template_name)
            return # just ignore if template doesn't exist

    if not sender:
        sender = settings.DEFAULT_FROM_EMAIL

    footer_file = os.path.join('helpdesk', locale, 'email_text_footer.txt')
    
    # get_template_from_string was removed in Django 1.8 http://django.readthedocs.org/en/1.8.x/ref/templates/upgrading.html
    try:
        from django.template import engines
        template_func = engines['django'].from_string
    except ImportError:  # occurs in django < 1.8
        template_func = loader.get_template_from_string

    text_part = template_func(
        "%s{%% include '%s' %%}" % (t.plain_text, footer_file)
        ).render(context)

    email_html_base_file = os.path.join('helpdesk', locale, 'email_html_base.html')


    ''' keep new lines in html emails '''
    from django.utils.safestring import mark_safe

    if 'comment' in context:
        html_txt = context['comment']
        html_txt = html_txt.replace('\r\n', '<br>')
        context['comment'] = mark_safe(html_txt)

    # get_template_from_string was removed in Django 1.8 http://django.readthedocs.org/en/1.8.x/ref/templates/upgrading.html
    html_part = template_func(
        "{%% extends '%s' %%}{%% block title %%}%s{%% endblock %%}{%% block content %%}%s{%% endblock %%}" % (email_html_base_file, t.heading, t.html)
        ).render(context)

    # get_template_from_string was removed in Django 1.8 http://django.readthedocs.org/en/1.8.x/ref/templates/upgrading.html
    subject_part = template_func(
        HELPDESK_EMAIL_SUBJECT_TEMPLATE % {
            "subject": t.subject,
        }).render(context)

    if isinstance(recipients, str):
        if recipients.find(','):
            recipients = recipients.split(',')
    elif type(recipients) != list:
        recipients = [recipients,]

    msg = EmailMultiAlternatives(   subject_part.replace('\n', '').replace('\r', ''),
                                    text_part,
                                    sender,
                                    recipients,
                                    bcc=bcc)
    msg.attach_alternative(html_part, "text/html")

    if files:
        for attachment in files:
            file_to_attach = attachment[1]
            file_to_attach.open()
            msg.attach(filename=attachment[0], content=file_to_attach.read())
            file_to_attach.close()

    return msg.send(fail_silently)

Example 47

Project: tendenci
Source File: widgets.py
View license
    def render(self, name, value, attrs=None):
        if not isinstance(value, list):
            value = self.decompress(value)

        final_attrs = self.build_attrs(attrs)
        id_ = final_attrs.get('id', None)

        custom_field_final_attrs = final_attrs.copy()
        if 'class' in custom_field_final_attrs:
            classes = custom_field_final_attrs["class"].split(" ")
            custom_field_final_attrs['class'] = " ".join([cls for cls in classes if cls != "form-control"])

        # period type
        period_type_widget = self.pos_d['period_type'][1]
        period_type_widget.choices = PERIOD_CHOICES
        #self.widgets.append(period_type_widget)
        rendered_period_type = self.render_widget(period_type_widget,
                                                  name, value, final_attrs, self.pos_d['period_type'][0], id_)

        # period
        period_widget = self.pos_d['period'][1]
        period_widget.attrs = {'size':'8'}
        rendered_period = self.render_widget(period_widget, name, value, final_attrs,
                                             self.pos_d['period'][0], id_)

        # period_unit
        period_unit_widget = self.pos_d['period_unit'][1]
        period_unit_widget.choices = PERIOD_UNIT_CHOICE
        rendered_period_unit = self.render_widget(period_unit_widget,
                                                  name, value, final_attrs, self.pos_d['period_unit'][0], id_)
        # expiration_method_day
        rolling_option1_day_widget = self.pos_d['rolling_option1_day'][1]
        rolling_option1_day_widget.attrs = {'size':'8'}
        rendered_rolling_option1_day = self.render_widget(rolling_option1_day_widget,
                                                            name, value, final_attrs,
                                                            self.pos_d['rolling_option1_day'][0], id_)
        # expiration_method
        JOIN_EXP_METHOD_CHOICE = (
                                  ("0", _("End of full period")),
                                  ("1", mark_safe("%s day(s) at signup month" % \
                                                  rendered_rolling_option1_day)),)
        rolling_option_widget = self.pos_d['rolling_option'][1]
        rolling_option_widget.choices=JOIN_EXP_METHOD_CHOICE
        rendered_rolling_option = self.render_widget(rolling_option_widget,
                                                  name, value, final_attrs,
                                                  self.pos_d['rolling_option'][0], id_)

        # rolling_renew_option1_day
        rolling_renew_option1_day_widget = self.pos_d['rolling_renew_option1_day'][1]
        rolling_renew_option1_day_widget.attrs = {'size':'8'}
        rendered_rolling_renew_option1_day = self.render_widget(rolling_renew_option1_day_widget,
                                                            name, value, final_attrs,
                                                            self.pos_d['rolling_renew_option1_day'][0], id_)
        # renew_expiration_day2
        rolling_renew_option2_day_widget = self.pos_d['rolling_renew_option2_day'][1]
        rolling_renew_option2_day_widget.attrs = {'size':'8'}
        rendered_rolling_renew_option2_day = self.render_widget(rolling_renew_option2_day_widget,
                                                            name, value, final_attrs,
                                                           self.pos_d['rolling_renew_option2_day'][0], id_)
        # renew_expiration_method
        RENEW_EXP_METHOD_CHOICE = (
                                  ("0", _("End of full period")),
                                  ("1", mark_safe("%s day(s) at signup month" % \
                                                  rendered_rolling_renew_option1_day)),
                                  ("2", mark_safe("%s day(s) at renewal month" % \
                                                  rendered_rolling_renew_option2_day)),)
        rolling_renew_option_widget = self.pos_d['rolling_renew_option'][1]
        rolling_renew_option_widget.choices=RENEW_EXP_METHOD_CHOICE
        rendered_rolling_renew_option = self.render_widget(rolling_renew_option_widget,
                                                  name, value, final_attrs,
                                                  self.pos_d['rolling_renew_option'][0], id_)
        # fixed_option1_day
        fixed_option1_day_widget = self.pos_d['fixed_option1_day'][1]
        fixed_option1_day_widget.choices=DAYS_CHOICES
        rendered_fixed_option1_day = self.render_widget(fixed_option1_day_widget,
                                                            name, value, final_attrs,
                                                            self.pos_d['fixed_option1_day'][0], id_)
        # fixed_option1_month
        fixed_option1_month_widget = self.pos_d['fixed_option1_month'][1]
        fixed_option1_month_widget.choices=MONTHS_CHOICES
        rendered_fixed_option1_month = self.render_widget(fixed_option1_month_widget,
                                                            name, value, final_attrs,
                                                            self.pos_d['fixed_option1_month'][0], id_)
        # dynamically generate the year choices for fixed_option1_year
        fixed_option1_year = ''
        if value:
            try:
                fixed_option1_year = int(value[self.pos_d['fixed_option1_year'][0]])
            except:
                pass
        if not fixed_option1_year:
            fixed_option1_year = int(datetime.date.today().year)
        years = [(year, year) for year in range(fixed_option1_year-1, fixed_option1_year+20)]

        #fixed_expiration_year
        fixed_option1_year_widget =  self.pos_d['fixed_option1_year'][1]
        fixed_option1_year_widget.choices=years
        rendered_fixed_option1_year = self.render_widget(fixed_option1_year_widget,
                                                            name, value, final_attrs,
                                                            self.pos_d['fixed_option1_year'][0], id_)
        # fixed_option2_day
        fixed_option2_day_widget = self.pos_d['fixed_option2_day'][1]
        fixed_option2_day_widget.choices=DAYS_CHOICES
        rendered_fixed_option2_day = self.render_widget(fixed_option2_day_widget,
                                                            name, value, final_attrs,
                                                            self.pos_d['fixed_option2_day'][0], id_)
        #fixed_option2_month
        fixed_option2_month_widget = self.pos_d['fixed_option2_month'][1]
        fixed_option2_month_widget.choices=MONTHS_CHOICES
        rendered_fixed_option2_month = self.render_widget(fixed_option2_month_widget,
                                                            name, value, final_attrs,
                                                            self.pos_d['fixed_option2_month'][0], id_)
        FIXED_EXP_METHOD_CHOICE = (
                                  ("0", mark_safe("%s %s %s" % (rendered_fixed_option1_month,
                                                      rendered_fixed_option1_day,
                                                      rendered_fixed_option1_year))),
                                  ("1", mark_safe("%s %s of current year" % \
                                                  (rendered_fixed_option2_month,
                                                   rendered_fixed_option2_day))))

        # fixed_option
        fixed_option_widget = self.pos_d['fixed_option'][1]
        fixed_option_widget.choices=FIXED_EXP_METHOD_CHOICE
        rendered_fixed_option = self.render_widget(fixed_option_widget,
                                                  name, value, final_attrs,
                                                  self.pos_d['fixed_option'][0], id_)
        # fixed_option2_rollover_days
        fixed_option2_rollover_days_widget = self.pos_d['fixed_option2_rollover_days'][1]
        fixed_option2_rollover_days_widget.attrs={'size':'8'}
        rendered_fixed_option2_rollover_days = self.render_widget(fixed_option2_rollover_days_widget,
                                                            name, value, final_attrs,
                                                            self.pos_d['fixed_option2_rollover_days'][0], id_)
        # fixed_option2_can_rollover
        fixed_option2_can_rollover_widget = self.pos_d['fixed_option2_can_rollover'][1]
        can_rollover_attrs = final_attrs.copy()
        if "class" in can_rollover_attrs:
            can_rollover_attrs["class"] = "%s checkbox" % can_rollover_attrs["class"]
        else:
            can_rollover_attrs["class"] = "checkbox"
        rendered_fixed_option2_can_rollover = self.render_widget(fixed_option2_can_rollover_widget,
                                                       name, value, can_rollover_attrs,
                                                       self.pos_d['fixed_option2_can_rollover'][0], id_)

        output_html = """
                        <div id="exp-method-box">
                            <div>%s</div>

                            <div style="margin: 1em 0 0 3em;">
                                <div id="rolling-box" class="form-group">
                                    <div class="form-inline"><label for="%s_%s">Period</label> %s %s</div>
                                    <div><label for="%s_%s">Expires On</label> %s</div>
                                    <div><label for="%s_%s">Renew Expires On</label> %s</div>
                                </div>

                                <div id="fixed-box" class="form-group">
                                    <div><label for="%s_%s">Expires On</label> %s</div>
                                    <div class="form-inline">%s For option 2, grace period %s day(s) before expiration then expires in the next year</div>
                                </div>
                            </div>

                        </div>
                      """ % (rendered_period_type,
                           name, self.pos_d['period'][0],
                           rendered_period, rendered_period_unit,
                           name, self.pos_d['rolling_option'][0], rendered_rolling_option,
                           name, self.pos_d['rolling_renew_option'][0], rendered_rolling_renew_option,
                           name, self.pos_d['fixed_option'][0], rendered_fixed_option,
                           rendered_fixed_option2_can_rollover, rendered_fixed_option2_rollover_days)

        return mark_safe(output_html)

Example 48

Project: tendenci
Source File: models.py
View license
def send_emails(emails, label, extra_context=None, on_site=True):
    """
    This method accepts a list of email addresses
    as opposed to a list of users. This is a custom method
    as opposed to send(), send_now(), and queue()

    Just send the notice to a list of emails immediately.
    No new notice created here
    notification.send_emails(email_list, 'friends_invite_sent', {
        'spam': 'eggs',
        'foo': 'bar',
    )
    """
    if extra_context is None:
        extra_context = {}

    try:
        notice_type = NoticeType.objects.get(label=label)
    except:
        # Stop here because we need a notice_type
        return None

    headers = {}
    protocol = getattr(settings, "DEFAULT_HTTP_PROTOCOL", "http")
    current_site = Site.objects.get_current()

    notices_url = u"%s://%s%s" % (
        protocol,
        unicode(current_site),
        reverse("notification_notices"),
    )

    formats = (
        'full.html',
        'short.txt',
        'notice.html',
    )  # TODO make formats configurable

    # test for request in the extra_context
    if 'request' in extra_context.keys():
        context = RequestContext(extra_context['request'])
        extra_context.update({
            "notice": ugettext(notice_type.display),
            "notices_url": notices_url,
            "current_site": current_site,
        })
        context.update(extra_context)
    else:
        # update context with user specific translations
        context = Context({
            "notice": ugettext(notice_type.display),
            "notices_url": notices_url,
            "current_site": current_site,
        })
        context.update(extra_context)

    # get prerendered format messages
    messages = get_formatted_messages(formats, label, context)

    if 'admin' in label:
        subject = messages['short']
        body = messages['full']

    else:
        subject = render_to_string(
            'notification/email_subject.txt',
            {'message': mark_safe(messages['short'])},
            context)

        body = render_to_string(
            'notification/email_body.txt',
            {'message': mark_safe(messages['full'])},
            context)

    if 'reply_to' in extra_context.keys():
        reply_to = extra_context['reply_to']
        headers['Reply-To'] = reply_to
    else:
        reply_to = ''

    sender = extra_context.get('sender', '')
    if not sender:
        sender = get_setting('site', 'global', 'siteemailnoreplyaddress') or settings.DEFAULT_FROM_EMAIL
        if not sender:
            sender = settings.DEFAULT_FROM_EMAIL

    sender_display = extra_context.get('sender_display', '')
    # Add quotes around display name to prevent errors on sending
    # when display name contains comma or other control characters, - jennyq
    from_display = '"%s"<%s>' % (sender_display, sender)

    if sender_display:
        headers['From'] = from_display

    recipient_bcc = extra_context.get('recipient_bcc') or []
    content_type = 'html'

    # removing newlines
    subject = ''.join(subject.splitlines())

    for email_addr in emails:
        recipients = [email_addr]

        if recipient_bcc:
            email = EmailMessage(subject, body, sender,
                                 recipients, recipient_bcc, headers=headers)
        else:
            email = EmailMessage(subject, body, sender,
                                 recipients, headers=headers)
        email.content_subtype = content_type

        try:
            email.send(fail_silently=True)  # should we raise exception or not?
        except UnicodeError:
            pass

    to = ','.join(emails)
    bcc = ','.join(recipient_bcc)
    reply_to = reply_to or unicode()

    NoticeEmail.objects.create(
        emails=to,
        sender=sender,
        bcc=bcc,
        title=subject,
        content=body,
        reply_to=reply_to,
        from_display=from_display,
        notice_type=notice_type
    )

Example 49

Project: tendenci
Source File: forms.py
View license
def build_settings_form(user, settings):
    """
        Create a set of fields and builds a form class
        returns SettingForm class
    """
    fields = OrderedDict()
    for setting in settings:
        setting_label = mark_safe('{0} <a href="#id_{1}" title="Permalink to this setting"><i class="fa fa-link" aria-hidden="true"></i></a>'.format(
                                    setting.label, setting.name))

        # Do not display standard regform settings
        if setting.scope_category == 'events' and setting.name.startswith('regform_'):
            continue

        try:
            setting_value = force_unicode(setting.get_value())
        except DjangoUnicodeDecodeError:
            setting_value = ''

        if setting.input_type in ['text', 'textarea']:
            options = {
                'label': setting_label,
                'help_text': setting.description,
                'initial': setting_value,
                'required': False,
                'label_suffix': "",
            }
            if setting.input_type == 'textarea':
                options['widget'] = forms.Textarea(attrs={'rows': 5, 'cols': 30});

            if setting.client_editable:
                fields.update({"%s" % setting.name: forms.CharField(**options)})
            else:
                if user.is_superuser:
                    fields.update({"%s" % setting.name: forms.CharField(**options)})
            
        elif setting.input_type in ['select', 'selectmultiple']:
            if setting.input_value == '<form_list>':
                choices = get_form_list(user)
                required = False
            elif setting.input_value == '<box_list>':
                choices = get_box_list(user)
                required = False
            elif setting.input_value == '<group_list>':
                choices, initial = get_group_list(user)
                required = True
                if not setting_value:
                    setting_value = initial
            elif setting.input_value == '<timezone_list>':
                choices = zones.PRETTY_TIMEZONE_CHOICES
                required = True
            elif setting.input_value == '<language_list>':
                choices = get_languages_with_local_name()
                required = True
            elif setting.input_value == '<country_list>':
                choices = (('', '-----------'),) + tuple(COUNTRIES)
                required = False
                if setting.name == 'countrylistinitialchoices':
                    setting_value = literal_eval(setting.get_value())
            else:
                # Allow literal_eval in settings in order to pass a list from the setting
                # This is useful if you want different values and labels for the select options
                try:
                    choices = tuple([(k, v)for k, v in literal_eval(setting.input_value)])
                    required = False

                    # By adding #<box_list> on to the end of a setting, this will append the boxes
                    # as select items in the list as well.
                    if '<box_list>' in setting.input_value:
                        box_choices = get_box_list(user)[1:]
                        choices = (('Content', choices), ('Boxes', box_choices))
                except:
                    choices = tuple([(s.strip(), s.strip())for s in setting.input_value.split(',')])
                    required = True

            options = {
                'label': setting_label,
                'help_text': setting.description,
                'initial': setting_value,
                'choices': choices,
                'required': required,
                'label_suffix': "",
            }
            if setting.client_editable or user.is_superuser:
                if setting.input_type == 'selectmultiple':
                    fields.update({"%s" % setting.name: forms.MultipleChoiceField(**options)})
                else:
                    fields.update({"%s" % setting.name: forms.ChoiceField(**options)})

        elif setting.input_type == 'file':
            from tendenci.apps.files.models import File as TendenciFile
            file_display = ''
            try:
                try:
                    val = int(setting_value)
                except ValueError:
                    val = 0

                try:
                    tfile = TendenciFile.objects.get(pk=val)
                except Exception:
                    tfile = None

                if tfile:
                    if tfile.file.name.lower().endswith(('.jpg', '.jpe', '.png', '.gif', '.svg')):
                        tfile_alt = tfile.file.name.lower()[:-4]
                        file_display = '<img src="/files/%s/" alt="%s" title="%s">' % (tfile.pk, tfile_alt, tfile_alt)
                    else:
                        file_display = tfile.file.name
            except TendenciFile.DoesNotExist:
                file_display = "No file"
            options = {
                'label': setting_label,
                'help_text': "%s<br> Current File: %s" % (setting.description, file_display),
                #'initial': tfile and tfile.file, # Removed this so the file doesn't save over and over
                'required': False,
                'label_suffix': "",
            }
            if setting.client_editable:
                fields.update({"%s" % setting.name: forms.FileField(**options)})
            else:
                if user.is_superuser:
                    fields.update({"%s" % setting.name: forms.FileField(**options)})

    attributes = {
        'settings': settings,
        'base_fields': fields,
        'clean': clean_settings_form,
        'save': save_settings_form,
        'user': user,
    }
    return type('SettingForm', (forms.BaseForm,), attributes)

Example 50

Project: helios-server
Source File: widgets.py
View license
    def render(self, name, value, attrs=None):
        try: # try to get time values from a datetime.time object (value)
            hour_val, minute_val = value.hour, value.minute
            if self.twelve_hr:
                if hour_val >= 12:
                    self.meridiem_val = 'p.m.'
                else:
                    self.meridiem_val = 'a.m.'
        except AttributeError:
            hour_val = minute_val = 0
            if isinstance(value, basestring):
                match = RE_TIME.match(value)
                if match:
                    time_groups = match.groups();
                    hour_val = int(time_groups[HOURS]) % 24 # force to range(0-24)
                    minute_val = int(time_groups[MINUTES]) 
                    
                    # check to see if meridiem was passed in
                    if time_groups[MERIDIEM] is not None:
                        self.meridiem_val = time_groups[MERIDIEM]
                    else: # otherwise, set the meridiem based on the time
                        if self.twelve_hr:
                            if hour_val >= 12:
                                self.meridiem_val = 'p.m.'
                            else:
                                self.meridiem_val = 'a.m.'
                        else:
                            self.meridiem_val = None
                    

        # If we're doing a 12-hr clock, there will be a meridiem value, so make sure the
        # hours get printed correctly
        if self.twelve_hr and self.meridiem_val:
            if self.meridiem_val.lower().startswith('p') and hour_val > 12 and hour_val < 24:
                hour_val = hour_val % 12
        elif hour_val == 0:
            hour_val = 12
            
        output = []
        if 'id' in self.attrs:
            id_ = self.attrs['id']
        else:
            id_ = 'id_%s' % name

        # For times to get displayed correctly, the values MUST be converted to unicode
        # When Select builds a list of options, it checks against Unicode values
        hour_val = u"%.2d" % hour_val
        minute_val = u"%.2d" % minute_val

        hour_choices = [("%.2d"%i, "%.2d"%i) for i in self.hours]
        local_attrs = self.build_attrs(id=self.hour_field % id_)
        select_html = Select(choices=hour_choices).render(self.hour_field % name, hour_val, local_attrs)
        output.append(select_html)

        minute_choices = [("%.2d"%i, "%.2d"%i) for i in self.minutes]
        local_attrs['id'] = self.minute_field % id_
        select_html = Select(choices=minute_choices).render(self.minute_field % name, minute_val, local_attrs)
        output.append(select_html)

        if self.twelve_hr:
            #  If we were given an initial value, make sure the correct meridiem gets selected.
            if self.meridiem_val is not None and  self.meridiem_val.startswith('p'):
                    meridiem_choices = [('p.m.','p.m.'), ('a.m.','a.m.')]
            else:
                meridiem_choices = [('a.m.','a.m.'), ('p.m.','p.m.')]

            local_attrs['id'] = local_attrs['id'] = self.meridiem_field % id_
            select_html = Select(choices=meridiem_choices).render(self.meridiem_field % name, self.meridiem_val, local_attrs)
            output.append(select_html)

        return mark_safe(u'\n'.join(output))