Beispiel #1
0
     def make_widget(key, label, widget, help_text, show_for_types):
         if key != "_remaining_":
             if value is not None and key in value:
                 val = value[key]
                 del value[
                     key]  # only the unrecognized keys are left at the end
             else:
                 val = ""
         elif value is None:
             # Nothing unrecognized.
             val = ""
         else:
             # Serialize unrecognized keys in YAML.
             import rtyaml
             val = rtyaml.dump(value)
         return """
 	    	<div style="clear: both; padding-bottom: .75em" class="{}">
 	        	<label for="id_{}_{}">{}:</label>
 	    		{}
 	    		<p class="help">{}</p>
 	    	</div>""".format(
             ("show_if_type " + " ".join(
                 ("show_if_type_" + s)
                 for s in show_for_types) if show_for_types else ""),
             escape_html(name),
             key,
             escape_html(label),
             widget.render(name + "_" + key, val),
             escape_html(help_text or ""),
         )
Beispiel #2
0
def fetch_quantitative_questions(request):
    """
    Fetch quantitative question data as JSON.

    Args:
        request: This parameter is ignored.

    Returns:
        A ``JsonResponse`` containing a JSON object of the form::

            [
                {
                    "id": <question.id>,
                    "prompts": {
                        "<language-code>": "<translated question.prompt>",
                        ...
                    },
                    "left-anchors": {
                        "<language-code>": "<translated question.left_anchor>",
                        ...
                    },
                    "right-anchors": {
                        "<language-code>": "<translated question.right_anchor>",
                        ...
                    },
                    "min-score": <question.min_score>,
                    "max-score": <question.max_score>,
                    "input-type": <question.input_type>,
                    "order": <question.order>,
                    "show-statistics": <question.show-statistics>
                },
                ...
            ]

        Each language code is obtained from ``settings.LANGUAGES``.
    """
    # pylint: disable=unused-argument
    return JsonResponse([
        {
            'id': question.id,
            'prompts': {
                code: escape_html(translate(question.prompt, code))
                for code, _ in settings.LANGUAGES
            },
            'left-anchors': {
                code: escape_html(translate(question.left_anchor, code))
                for code, _ in settings.LANGUAGES
            },
            'right-anchors': {
                code: escape_html(translate(question.right_anchor, code))
                for code, _ in settings.LANGUAGES
            },
            'min-score': question.min_score,
            'max-score': question.max_score,
            'input-type': question.input_type,
            'order': question.order,
            "show-statistics": question.show_statistics,
        } for question in QuantitativeQuestion.active_objects.iterator()
    ], safe=False)
Beispiel #3
0
def fetch_qualitative_questions(request):
    """
    Fetch qualitative question data as JSON.

    Args:
        request: This parameter is ignored.

    Returns:
        A ``JsonResponse`` containing a JSON object of the form::

            {
                "<question.id>": {
                    "<language-code>": "<translated question.prompt>",
                    ...
                },
                ...
            }

        Each language code is obtained from ``settings.LANGUAGES``.
    """
    # pylint: disable=unused-argument
    return JsonResponse({
        unicode(question.id): {
            code: escape_html(translate(question.prompt, code))
            for code, _ in settings.LANGUAGES
        }
        for question in QualitativeQuestion.objects.iterator()
    })
Beispiel #4
0
def get_search_fields(rendered_content, subject, content_matches,
                      subject_matches):
    # type: (text_type, text_type, Iterable[Tuple[int, int]], Iterable[Tuple[int, int]]) -> Dict[str, text_type]
    return dict(match_content=highlight_string(rendered_content,
                                               content_matches),
                match_subject=highlight_string(escape_html(subject),
                                               subject_matches))
Beispiel #5
0
 def render(self, name, value, attrs=None):
     value = json.loads(value or "{}") or {}
     ret = ""
     for path, label, widget, infunc, help_text in CampaignExtraWidget.fields:
         ret += """<div style="clear: both; padding-top: .5em">
             <label for="id_%s">%s:</label>
         %s
         <div class="help">%s</div></div>""" % (
         escape_html(name) + "_" + path,
         escape_html(label),
         widget.render(name + "_" + path, CampaignExtraWidget.get_dict_value(value, path)),
         escape_html(help_text or ""),
         )
     ret += """<input type="hidden" name="%s" value="%s">""" % (
         escape_html(name) + "__base", escape_html(json.dumps(value)))
     return ret
    def render_table(self, arguments: List[Dict[str, Any]]) -> List[str]:
        table = []
        beginning = """
<table class="table">
  <thead>
    <tr>
      <th>Argument</th>
      <th>Example</th>
      <th>Required</th>
      <th>Description</th>
    </tr>
  </thead>
<tbody>
"""
        tr = """
<tr>
  <td><code>{argument}</code></td>
  <td><code>{example}</code></td>
  <td>{required}</td>
  <td>{description}</td>
</tr>
"""

        table.append(beginning)

        md_engine = markdown.Markdown(extensions=[])

        for argument in arguments:
            description = argument['description']

            oneof = [
                '`' + item + '`'
                for item in argument.get('schema', {}).get('enum', [])
            ]
            if oneof:
                description += '\nMust be one of: {}.'.format(', '.join(oneof))

            default = argument.get('schema', {}).get('default')
            if default is not None:
                description += '\nDefaults to `{}`.'.format(
                    ujson.dumps(default))

            # TODO: Swagger allows indicating where the argument goes
            # (path, querystring, form data...). A column in the table should
            # be added for this.
            table.append(
                tr.format(
                    argument=argument.get('argument') or argument.get('name'),
                    # Show this as JSON to avoid changing the quoting style, which
                    # may cause problems with JSON encoding.
                    example=escape_html(ujson.dumps(argument['example'])),
                    required='Yes' if argument.get('required') else 'No',
                    description=md_engine.convert(description),
                ))

        table.append("</tbody>")
        table.append("</table>")

        return table
Beispiel #7
0
def get_search_fields(
        rendered_content: str, topic_name: str,
        content_matches: Iterable[Tuple[int, int]],
        topic_matches: Iterable[Tuple[int, int]]) -> Dict[str, str]:
    return {
        'match_content': highlight_string(rendered_content, content_matches),
        MATCH_TOPIC: highlight_string(escape_html(topic_name), topic_matches),
    }
Beispiel #8
0
def _prepare_regexp_html(regexp):
    """Return HTML for a given regexp. Includes wordbreaks."""
    if not regexp:
        return ''
    else:
        regexp_html = (escape_html(regexp).replace('|', '|&#8203;').replace(
            ']', ']&#8203;').replace(')', ')&#8203;'))
        return mark_safe(regexp_html)
Beispiel #9
0
 def render(self, name, value, attrs=None):
     value = json.loads(value or "{}") or {}
     ret = ""
     for path, label, widget, infunc, help_text in CampaignExtraWidget.fields:
         ret += """<div style="clear: both; padding-top: .5em">
             <label for="id_%s">%s:</label>
         %s
         <div class="help">%s</div></div>""" % (
             escape_html(name) + "_" + path,
             escape_html(label),
             widget.render(name + "_" + path,
                           CampaignExtraWidget.get_dict_value(value, path)),
             escape_html(help_text or ""),
         )
     ret += """<input type="hidden" name="%s" value="%s">""" % (
         escape_html(name) + "__base", escape_html(json.dumps(value)))
     return ret
Beispiel #10
0
 def description_inject(row_data):
     description = \
         escape_html(str(row_data.description)).replace("\n", "<br/>")
     description = description.replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;")
     description = description.replace(" " * 4, "&nbsp;" * 4)
     description = description.replace(" " * 3, "&nbsp;" * 3)
     description = description.replace(" " * 2, "&nbsp;" * 2)
     return mark_safe(description)
Beispiel #11
0
    def render_table(self, arguments: Sequence[Mapping[str,
                                                       Any]]) -> List[str]:
        # TODO: Fix naming now that this no longer renders a table.
        table = []
        argument_template = """
<div class="api-argument">
    <p class="api-argument-name"><strong>{argument}</strong> {required}</p>
    <div class="api-example">
        <span class="api-argument-example-label">Example</span>: <code>{example}</code>
    </div>
    <div class="api-description">{description}</div>
    <hr>
</div>"""

        md_engine = markdown.Markdown(extensions=[])

        for argument in arguments:
            description = argument['description']
            oneof = [
                '`' + str(item) + '`'
                for item in argument.get('schema', {}).get('enum', [])
            ]
            if oneof:
                description += '\nMust be one of: {}.'.format(', '.join(oneof))

            default = argument.get('schema', {}).get('default')
            if default is not None:
                description += f'\nDefaults to `{json.dumps(default)}`.'

            # TODO: OpenAPI allows indicating where the argument goes
            # (path, querystring, form data...).  We should document this detail.
            example = ""
            if 'example' in argument:
                example = argument['example']
            else:
                example = json.dumps(
                    argument['content']['application/json']['example'])

            required_string: str = "required"
            if argument.get('in', '') == 'path':
                # Any path variable is required
                assert argument['required']
                required_string = 'required in path'

            if argument.get('required', False):
                required_block = f'<span class="api-argument-required">{required_string}</span>'
            else:
                required_block = '<span class="api-argument-optional">optional</span>'

            table.append(
                argument_template.format(
                    argument=argument.get('argument') or argument.get('name'),
                    example=escape_html(example),
                    required=required_block,
                    description=md_engine.convert(description),
                ))

        return table
    def render_table(self, arguments: List[Dict[str, Any]]) -> List[str]:
        table = []
        beginning = """
<table class="table">
  <thead>
    <tr>
      <th>Argument</th>
      <th>Example</th>
      <th>Required</th>
      <th>Description</th>
    </tr>
  </thead>
<tbody>
"""
        tr = """
<tr>
  <td><code>{argument}</code></td>
  <td class="json-api-example"><code>{example}</code></td>
  <td>{required}</td>
  <td>{description}</td>
</tr>
"""

        table.append(beginning)

        md_engine = markdown.Markdown(extensions=[])

        for argument in arguments:
            description = argument['description']

            oneof = ['`' + item + '`'
                     for item in argument.get('schema', {}).get('enum', [])]
            if oneof:
                description += '\nMust be one of: {}.'.format(', '.join(oneof))

            default = argument.get('schema', {}).get('default')
            if default is not None:
                description += '\nDefaults to `{}`.'.format(ujson.dumps(default))

            # TODO: Swagger allows indicating where the argument goes
            # (path, querystring, form data...). A column in the table should
            # be added for this.
            table.append(tr.format(
                argument=argument.get('argument') or argument.get('name'),
                # Show this as JSON to avoid changing the quoting style, which
                # may cause problems with JSON encoding.
                example=escape_html(ujson.dumps(argument['example'])),
                required='Yes' if argument.get('required') else 'No',
                description=md_engine.convert(description),
            ))

        table.append("</tbody>")
        table.append("</table>")

        return table
Beispiel #13
0
def fetch_option_questions(request):
    """
    Fetch option question data as JSON.

    Args:
        request: This parameter is ignored.

    Returns:
        A ``JsonResponse`` containing a JSON object with the following structure::

          {
              "id": <question.id>,
              "prompts": {
                  "<language-code>": "<translated question.prompt>",
                  ...
              },
              "options": {
                  "<language-code>": ["<translated member of question.options>", ...],
                  ...
              },
              "input-type": "<question.input_type>",
              "order": <question.order>
          }
    """
    # pylint: disable=unused-argument
    return JsonResponse([{
        'id': question.id,
        'prompts': {
            code: escape_html(translate(question.prompt, code))
            for code, _ in settings.LANGUAGES
        },
        'options': {
            code: [
                escape_html(translate(option, code))
                for option in question.options
            ]
            for code, _ in settings.LANGUAGES
        },
        'input-type': question.input_type,
        'order': question.order,
    } for question in OptionQuestion.objects.iterator()],
                        safe=False)
    def render_table(self, arguments: List[Dict[str, Any]]) -> List[str]:
        # TODO: Fix naming now that this no longer renders a table.
        table = []
        argument_template = """
<div class="api-argument">
    <p class="api-argument-name"><strong>{argument}</strong> {required}</p>
    <div class="api-example">
        <span class="api-argument-example-label">Example</span>: <code>{example}</code>
    </div>
    <div class="api-description">{description}</div>
    <hr />
</div>"""

        md_engine = markdown.Markdown(extensions=[])

        for argument in arguments:
            description = argument['description']

            oneof = [
                '`' + str(item) + '`'
                for item in argument.get('schema', {}).get('enum', [])
            ]
            if oneof:
                description += '\nMust be one of: {}.'.format(', '.join(oneof))

            default = argument.get('schema', {}).get('default')
            if default is not None:
                description += '\nDefaults to `{}`.'.format(
                    json.dumps(default))

            # TODO: OpenAPI allows indicating where the argument goes
            # (path, querystring, form data...).  We should document this detail.
            table.append(
                argument_template.format(
                    argument=argument.get('argument') or argument.get('name'),
                    # Show this as JSON to avoid changing the quoting style, which
                    # may cause problems with JSON encoding.
                    example=escape_html(json.dumps(argument['example'])),
                    required=
                    '<span class="api-argument-required">required</span>'
                    if argument.get('required') else
                    '<span class="api-argument-optional">optional</span>',
                    description=md_engine.convert(description),
                ))

        return table
Beispiel #15
0
    def _parse_trans(self, token, parser, original_string):
        """Parse a {% trans %} token and return a migration object.

        :param django.template.base.Token token: the token object
        :param django.template.base.parser: the parser object
        :param unicode original_string: the string found in the template
        """

        # Use Django's do_translate() method to parse the token
        trans_node = do_translate(parser, token)

        confidence = Confidence.LOW if trans_node.noop else Confidence.HIGH

        message_context = trans_node.message_context
        # Our SDK supports filter expressions
        text = trans_node.filter_expression.token

        # Source strings that contain XML symbols should use 'ut'. We determine
        # whether the string contains XML symbols by testing if an escaping
        # attempt changes it in any way.
        # eg `{% trans "a b" %}`            => `{% t "a b" %}`
        #    `{% trans "<xml>a</xml> b" %}` => `{% ut "<xml>a</xml> b" %}`
        if isinstance(trans_node.filter_expression.var, string_types):
            literal = trans_node.filter_expression.var
        else:
            literal = trans_node.filter_expression.var.literal
        if (isinstance(literal, string_types)
                and escape_html(literal) != literal):
            tag_name = "ut"
        else:
            tag_name = "t"

        params = {'_context': message_context, '_comment': self._comment}
        # Reset the stored comment, so that it doesn't leak to the next token
        self._comment = None

        # Render the final output
        t_tag = ['{%', tag_name, text, _render_params(params)]
        if trans_node.asvar:
            t_tag.extend(['as', trans_node.asvar])
        t_tag.append('%}')
        t_tag = ' '.join((thing.strip() for thing in t_tag if thing.strip()))

        return self._final_string_migration(original_string,
                                            t_tag,
                                            confidence=confidence)
Beispiel #16
0
 def render(self, name, value, attrs=None):
     try:
         # Create separate form fields per outcome & attribute.
         vote_key_str = {"+": "Aye/Yea Vote", "-": "Nay/No Vote"}
         ret = """<div style="clear: both">"""
         for i, outcome in enumerate(json.loads(value)):
             n = escape_html(name) + "_" + str(i)
             ret += """<div style="padding: 1em 0">"""
             ret += """<div style="font-weight: bold; margin-bottom: .5em">Outcome #%d - %s</div>""" % (
                 i + 1, outcome.get("_default", {}).get("label")
                 or vote_key_str.get(outcome.get("vote_key"), ""))
             for key, label, help_text in (
                 ("label", "Label",
                  "Primary text on the button to take action."),
                 ("tip", "Tip",
                  "Optional small text displayed below the label."),
                 ("object", "Objective",
                  "Finishes the sentence \"blah blah voted....\" ")):
                 ret += """<div>
                     <label for="id_%s">%s:</label>
                     <input class="vTextField" id="id_%s" maxlength="256" name="%s" type="text" value="%s" placeholder="%s" style="width: 30em; margin-bottom: 0">
                     <p class="help">%s</p>
                     </div>""" % (
                     n + "_" + key,
                     escape_html(label),
                     n + "_" + key,
                     n + "_" + key,
                     escape_html(outcome.get(key, "")
                                 or ""),  # None => empty string
                     escape_html(outcome.get("_default", {}).get(key, "")),
                     escape_html(help_text),
                 )
             # round-trip any keys that aren't submitted in form fields
             other_keys = {
                 key: value
                 for key, value in outcome.items()
                 if key not in ("label", "tip", "object", "_default")
             }
             ret += """<input type="hidden" name="%s" value="%s">""" % (
                 n + "_otherkeys", escape_html(json.dumps(other_keys)))
             ret += """<div>"""
         #ret += """<pre>""" + escape_html(value) + """</pre>"""
         ret += """<div>"""
         return ret
     except Exception:
         # fallback
         return admin.widgets.AdminTextareaWidget().render(name,
                                                           value,
                                                           attrs=attrs)
Beispiel #17
0
    def value_from_datadict(self, data, files, name):
        if name in data:
            # fallback if we didn't replace the widget
            return admin.widgets.AdminTextareaWidget().value_from_datadict(data, files, name)

        outcomes = []
        i = 0
        while True:
            n = escape_html(name) + "_" + str(i)
            if n + "_label" not in data: break # no more outcomes
            outcome = json.loads(data[n + "_otherkeys"]) # default data
            for key in ("label", "tip", "object"):
                # set if string is truthy - don't create key if value is empty
                value = data[n + "_" + key].strip()
                if value:
                    outcome[key] = value
            outcomes.append(outcome)
            i += 1

        return json.dumps(outcomes)
Beispiel #18
0
    def value_from_datadict(self, data, files, name):
        if name in data:
            # fallback if we didn't replace the widget
            return admin.widgets.AdminTextareaWidget().value_from_datadict(
                data, files, name)

        outcomes = []
        i = 0
        while True:
            n = escape_html(name) + "_" + str(i)
            if n + "_label" not in data: break  # no more outcomes
            outcome = json.loads(data[n + "_otherkeys"])  # default data
            for key in ("label", "tip", "object"):
                # set if string is truthy - don't create key if value is empty
                value = data[n + "_" + key].strip()
                if value:
                    outcome[key] = value
            outcomes.append(outcome)
            i += 1

        return json.dumps(outcomes)
Beispiel #19
0
    def boxes_to_xml(self, leaves, **options):
        elements, axes, ticks, calc_dimensions, boxscale = \
            self._prepare_elements(leaves, options)

        elements._apply_boxscaling(boxscale)

        json_repr = elements.to_json()

        xmin, xmax, ymin, ymax, zmin, zmax, boxscale = calc_dimensions()

        # TODO: Cubeoid (like this)
        # json_repr = [{'faceColor': (1, 1, 1, 1), 'position': [(0,0,0), None],
        # 'size':[(1,1,1), None], 'type': 'cube'}]

        json_repr = json.dumps({
            'elements': json_repr,
            'axes': {
                'hasaxes': axes,
                'ticks': ticks,
            },
            'extent': {
                'xmin': xmin,
                'xmax': xmax,
                'ymin': ymin,
                'ymax': ymax,
                'zmin': zmin,
                'zmax': zmax,
            },
            'lighting': self.lighting,
            'viewpoint': self.viewpoint,
        })

        # return "<mn>3</mn>"

        # xml = ('<graphics3d xmin="%f" xmax="%f" ymin="%f" ymax="%f" '
        #        'zmin="%f" zmax="%f" data="%s" />') % (
        #           xmin, xmax, ymin, ymax, zmin, zmax, json_repr)
        xml = '<graphics3d data="{0}" />'.format(escape_html(json_repr))
        xml = '<mtable><mtr><mtd>{0}</mtd></mtr></mtable>'.format(xml)
        return xml
Beispiel #20
0
    def boxes_to_xml(self, leaves, **options):
        elements, axes, ticks, calc_dimensions, boxscale = \
            self._prepare_elements(leaves, options)

        elements._apply_boxscaling(boxscale)

        json_repr = elements.to_json()

        xmin, xmax, ymin, ymax, zmin, zmax, boxscale = calc_dimensions()

        # TODO: Cubeoid (like this)
        # json_repr = [{'faceColor': (1, 1, 1, 1), 'position': [(0,0,0), None],
        # 'size':[(1,1,1), None], 'type': 'cube'}]

        json_repr = json.dumps({
            'elements': json_repr,
            'axes': {
                'hasaxes': axes,
                'ticks': ticks,
            },
            'extent': {
                'xmin': xmin,
                'xmax': xmax,
                'ymin': ymin,
                'ymax': ymax,
                'zmin': zmin,
                'zmax': zmax,
            },
            'lighting': self.lighting,
            'viewpoint': self.viewpoint,
        })

        # return "<mn>3</mn>"

        # xml = ('<graphics3d xmin="%f" xmax="%f" ymin="%f" ymax="%f" '
        #        'zmin="%f" zmax="%f" data="%s" />') % (
        #           xmin, xmax, ymin, ymax, zmin, zmax, json_repr)
        xml = '<graphics3d data="{0}" />'.format(escape_html(json_repr))
        xml = '<mtable><mtr><mtd>{0}</mtd></mtr></mtable>'.format(xml)
        return xml
Beispiel #21
0
 def render(self, name, value, attrs=None):
     try:
         # Create separate form fields per outcome & attribute.
         vote_key_str = { "+": "Aye/Yea Vote", "-": "Nay/No Vote" }
         ret = """<div style="clear: both">"""
         for i, outcome in enumerate(json.loads(value)):
             n = escape_html(name) + "_" + str(i)
             ret += """<div style="padding: 1em 0">"""
             ret += """<div style="font-weight: bold; margin-bottom: .5em">Outcome #%d - %s</div>""" % (
                 i+1,
                 outcome.get("_default", {}).get("label") or 
                     vote_key_str.get(outcome.get("vote_key"), "")
                 )
             for key, label, help_text in (
                 ("label", "Label", "Primary text on the button to take action."),
                 ("tip", "Tip", "Optional small text displayed below the label."),
                 ("object", "Objective", "Finishes the sentence \"blah blah voted....\" ")):
                 ret += """<div>
                     <label for="id_%s">%s:</label>
                     <input class="vTextField" id="id_%s" maxlength="256" name="%s" type="text" value="%s" placeholder="%s" style="width: 30em; margin-bottom: 0">
                     <p class="help">%s</p>
                     </div>""" % (
                         n + "_" + key,
                         escape_html(label),
                         n + "_" + key,
                         n + "_" + key,
                         escape_html(outcome.get(key, "") or ""), # None => empty string
                         escape_html(outcome.get("_default", {}).get(key, "")),
                         escape_html(help_text),
                     )
             # round-trip any keys that aren't submitted in form fields
             other_keys = { key: value for key, value in outcome.items()
                 if key not in ("label", "tip", "object", "_default") }
             ret += """<input type="hidden" name="%s" value="%s">""" % (
                 n + "_otherkeys", escape_html(json.dumps(other_keys)))
             ret += """<div>"""
         #ret += """<pre>""" + escape_html(value) + """</pre>"""
         ret += """<div>"""
         return ret
     except Exception:
         # fallback
         return admin.widgets.AdminTextareaWidget().render(name, value, attrs=attrs)
Beispiel #22
0
def get_search_fields(rendered_content, subject, content_matches, subject_matches):
    # type: (Text, Text, Iterable[Tuple[int, int]], Iterable[Tuple[int, int]]) -> Dict[str, Text]
    return dict(match_content=highlight_string(rendered_content, content_matches),
                match_subject=highlight_string(escape_html(subject), subject_matches))
Beispiel #23
0
    def render(self, context):
        if isinstance(self.source_string.var, string_types):
            # Tag had a string literal or used block syntax
            source_icu_template = self.source_string.var
        else:
            # We resolve the *variable* of the filter expression, not the
            # expression itself, because we want to apply the filters to the
            # *translation* afterwards. Also, we use autoescape=False in order
            # to ignore django's attempts to escape the source string at this
            # point because we want to use the raw string to look for a
            # translation
            safe_context = copy(context)
            safe_context.autoescape = False
            source_icu_template = self.source_string.var.resolve(safe_context)

        # The values of self.params are filter expressions that can be resolved
        params = {
            key: value.resolve(context)
            for key, value in self.params.items()
        }

        # Perform the translation in two steps: First, we get the translation
        # ICU template. Then we perform ICU rendering against 'params'.
        # In between the two steps, if the tag used was 't' and not 'ut', we
        # perform escaping on the ICU template.
        is_source = get_language() == settings.LANGUAGE_CODE
        locale = to_locale(get_language())  # e.g. from en-us to en_US
        translation_icu_template = tx.get_translation(
            source_string=source_icu_template,
            language_code=locale,
            _context=params.get('_context', None),
            is_source=is_source,
            _key=params.get('_key', None),
        )

        # The ICU template can compile against explicitly passed params as well
        # as any context variable. In order to avoid passing and potentially
        # escaping *every* variable in the context for optimization reasons, we
        # need to filter down to the ones that the ICU template will actually
        # need
        keys = get_icu_keys(source_icu_template)
        if translation_icu_template is not None:
            keys.update(get_icu_keys(translation_icu_template))
        for key in keys:
            if key in params:
                continue
            try:
                params[key] = context[key]
            except KeyError:
                pass

        for key, value in params.items():
            # Django doesn't escape strings until the last moment. For now,
            # escaped strings are "marked" as escaped, using the EscapeData
            # class. Because the low-level transifex toolkit doesn't know about
            # django's escape marking, we perform the escaping manually, if
            # needed.
            should_escape = (isinstance(value, string_types) and (
                (context.autoescape and not isinstance(value, SafeData)) or
                (not context.autoescape and isinstance(value, EscapeData))))
            if should_escape:
                params[key] = escape_html(value)

        if self.tag_name == "t":
            source_icu_template = escape_html(source_icu_template)
            if translation_icu_template is not None:
                translation_icu_template = escape_html(
                    translation_icu_template)

        result = tx.render_translation(translation_icu_template,
                                       params,
                                       source_icu_template,
                                       locale,
                                       escape=False)

        # `self` is not supposed to mutate between invocations of `render`
        # because Django may parse the template once per thread and reuse the
        # nodes between renders ("parse" = "process text into nodes"). To that
        # end, let's safekeep the old value of `self.source_string.var` to put
        # it back in place before returning from render.
        # https://docs.djangoproject.com/en/1.11/howto/custom-template-tags/#thread-safety-considerations  # noqa
        old_source_string_var = self.source_string.var

        # Now we resolve the full source filter expression, after having
        # replaced its text with the outcome of the translation, in order to
        # apply the expression's filters to the translation. The translation is
        # marked as safe in order to prevent further escaping attempts that
        # would introduce the danger of double escaping (eg `<` => `&amp;lt;`)
        self.source_string.var = mark_safe(result)
        result = self.source_string.resolve(context)
        self.source_string.var = old_source_string_var

        if self.asvar is not None:
            # Save the translation outcome to a context variable
            context[self.asvar] = result
            return ""
        else:
            return result
Beispiel #24
0
 def maybe_escape(self, text):
     if not self.escape:
         return text
     return escape_html(text)
    def render_parameters(self, arguments: Sequence[Mapping[str, Any]]) -> List[str]:
        parameters = []

        md_engine = markdown.Markdown(extensions=[])
        arguments = sorted(arguments, key=lambda argument: "deprecated" in argument)
        for argument in arguments:
            name = argument.get("argument") or argument.get("name")
            description = argument["description"]
            enums = argument.get("schema", {}).get("enum")
            if enums is not None:
                formatted_enums = [
                    OBJECT_CODE_TEMPLATE.format(value=json.dumps(enum)) for enum in enums
                ]
                description += "\nMust be one of: {}. ".format(", ".join(formatted_enums))

            default = argument.get("schema", {}).get("default")
            if default is not None:
                description += f"\nDefaults to `{json.dumps(default)}`."
            data_type = ""
            if "schema" in argument:
                data_type = generate_data_type(argument["schema"])
            else:
                data_type = generate_data_type(argument["content"]["application/json"]["schema"])

            # TODO: OpenAPI allows indicating where the argument goes
            # (path, querystring, form data...).  We should document this detail.
            example = ""
            if "example" in argument:
                # We use this style without explicit JSON encoding for
                # integers, strings, and booleans.
                # * For booleans, JSON encoding correctly corrects for Python's
                #   str(True)="True" not matching the encoding of "true".
                # * For strings, doing so nicely results in strings being quoted
                #   in the documentation, improving readability.
                # * For integers, it is a noop, since json.dumps(3) == str(3) == "3".
                example = json.dumps(argument["example"])
            else:
                example = json.dumps(argument["content"]["application/json"]["example"])

            required_string: str = "required"
            if argument.get("in", "") == "path":
                # Any path variable is required
                assert argument["required"]
                required_string = "required in path"

            if argument.get("required", False):
                required_block = f'<span class="api-argument-required">{required_string}</span>'
            else:
                required_block = '<span class="api-argument-optional">optional</span>'

            check_deprecated_consistency(argument, description)
            if argument.get("deprecated", False):
                deprecated_block = '<span class="api-argument-deprecated">Deprecated</span>'
            else:
                deprecated_block = ""

            object_block = ""
            # TODO: There are some endpoint parameters with object properties
            # that are not defined in `zerver/openapi/zulip.yaml`
            if "object" in data_type:
                if "schema" in argument:
                    object_schema = argument["schema"]
                else:
                    object_schema = argument["content"]["application/json"]["schema"]

                if "items" in object_schema and "properties" in object_schema["items"]:
                    object_block = self.render_object_details(object_schema["items"], str(name))
                elif "properties" in object_schema:
                    object_block = self.render_object_details(object_schema, str(name))

            parameters.append(
                API_PARAMETER_TEMPLATE.format(
                    argument=name,
                    example=escape_html(example),
                    required=required_block,
                    deprecated=deprecated_block,
                    description=md_engine.convert(description),
                    type=(data_type),
                    object_details=object_block,
                )
            )

        return parameters
Beispiel #26
0
def get_search_fields(rendered_content, subject, content_matches, subject_matches):
    return dict(match_content=highlight_string(rendered_content, content_matches),
                match_subject=highlight_string(escape_html(subject), subject_matches))
    def render_table(self, arguments: Sequence[Mapping[str,
                                                       Any]]) -> List[str]:
        # TODO: Fix naming now that this no longer renders a table.
        table = []
        argument_template = """
<div class="api-argument" id="parameter-{argument}">
    <p class="api-argument-name"><strong>{argument}</strong> <span class="api-field-type">{type}</span> {required} {deprecated} <a href="#parameter-{argument}" class="api-argument-hover-link"><i class="fa fa-chain"></i></a></p>
    <div class="api-example">
        <span class="api-argument-example-label">Example</span>: <code>{example}</code>
    </div>
    <div class="api-description">{description}</div>
    <hr>
</div>"""

        md_engine = markdown.Markdown(extensions=[])
        arguments = sorted(arguments,
                           key=lambda argument: "deprecated" in argument)
        for argument in arguments:
            description = argument["description"]
            oneof = [
                "`" + str(item) + "`"
                for item in argument.get("schema", {}).get("enum", [])
            ]
            if oneof:
                description += "\nMust be one of: {}.".format(", ".join(oneof))

            default = argument.get("schema", {}).get("default")
            if default is not None:
                description += f"\nDefaults to `{json.dumps(default)}`."
            data_type = ""
            if "schema" in argument:
                data_type = generate_data_type(argument["schema"])
            else:
                data_type = generate_data_type(
                    argument["content"]["application/json"]["schema"])

            # TODO: OpenAPI allows indicating where the argument goes
            # (path, querystring, form data...).  We should document this detail.
            example = ""
            if "example" in argument:
                example = argument["example"]
            else:
                example = json.dumps(
                    argument["content"]["application/json"]["example"])

            required_string: str = "required"
            if argument.get("in", "") == "path":
                # Any path variable is required
                assert argument["required"]
                required_string = "required in path"

            if argument.get("required", False):
                required_block = f'<span class="api-argument-required">{required_string}</span>'
            else:
                required_block = '<span class="api-argument-optional">optional</span>'

            check_deprecated_consistency(argument, description)
            if argument.get("deprecated", False):
                deprecated_block = '<span class="api-argument-deprecated">Deprecated</span>'
            else:
                deprecated_block = ""

            table.append(
                argument_template.format(
                    argument=argument.get("argument") or argument.get("name"),
                    example=escape_html(example),
                    required=required_block,
                    deprecated=deprecated_block,
                    description=md_engine.convert(description),
                    type=data_type,
                ))

        return table
    def render_object_details(self, schema: Mapping[str, Any], name: str) -> str:
        md_engine = markdown.Markdown(extensions=[])
        li_elements = []

        object_values = schema.get("properties", {})
        for value in object_values:

            description = ""
            if "description" in object_values[value]:
                description = object_values[value]["description"]

            # check for default, enum, required or example in documentation
            additions: List[str] = []

            default = object_values.get(value, {}).get("default")
            if default is not None:
                formatted_default = OBJECT_CODE_TEMPLATE.format(value=json.dumps(default))
                additions += f"Defaults to {formatted_default}. "

            enums = object_values.get(value, {}).get("enum")
            if enums is not None:
                formatted_enums = [
                    OBJECT_CODE_TEMPLATE.format(value=json.dumps(enum)) for enum in enums
                ]
                additions += "Must be one of: {}. ".format(", ".join(formatted_enums))

            if "example" in object_values[value]:
                example = json.dumps(object_values[value]["example"])
                formatted_example = OBJECT_CODE_TEMPLATE.format(value=escape_html(example))
                additions += (
                    f'<span class="api-argument-example-label">Example</span>: {formatted_example}'
                )

            if len(additions) > 0:
                additional_information = "".join(additions).strip()
                description_final = OBJECT_DESCRIPTION_TEMPLATE.format(
                    description=md_engine.convert(description),
                    additional_information=additional_information,
                )
            else:
                description_final = md_engine.convert(description)

            required_block = ""
            if "required" in schema:
                if value in schema["required"]:
                    required_block = '<span class="api-argument-required">required</span>'
                else:
                    required_block = '<span class="api-argument-optional">optional</span>'

            data_type = generate_data_type(object_values[value])

            details = ""
            if "object" in data_type and "properties" in object_values[value]:
                details += self.render_object_details(object_values[value], str(value))

            li = OBJECT_LIST_ITEM_TEMPLATE.format(
                value=value,
                data_type=data_type,
                required=required_block,
                description=description_final,
                object_details=details,
            )

            li_elements.append(li)

        object_details = OBJECT_DETAILS_TEMPLATE.format(
            argument=name,
            values="\n".join(li_elements),
        )
        return object_details
 def get_column_value(self, obj, column, **kwargs):
     source_value = self.get_source_value(obj, column)
     return escape_html(source_value or column.value(obj, **kwargs)[0])
Beispiel #30
0
    def _parse_blocktrans(self, token, parser, original_string):
        """Parse a {% blocktrans %} token and return a migration object.

        :param django.template.base.Token token: the token object
        :param django.template.base.parser: the parser object
        :param unicode original_string: the string found in the template
        """

        # Use Django's blocktranslate tag function to actually parse
        # the whole tag, so that we easily get all information
        # Internally, the do_block_translate() call will make the parser
        # go forward, so the call to parser.next_token() will skip
        # all tokens until {% endblocktrans %} (inclusive).
        consumed_tokens = []
        for t in parser.tokens:  # these are just the remaining tokens
            consumed_tokens.append(t)
            if t.contents in templates.ENDBLOCK_TRANSLATE_TAGS:
                break  # we assume there will be a {% endblocktrans %} token

        blocktrans_node = do_block_translate(parser, token)

        message_context = blocktrans_node.message_context
        singular_text = _render_var_tokens(blocktrans_node.singular)
        plural_text = _render_var_tokens(blocktrans_node.plural)

        # Start building the parameters supported by Transifex Native
        params = {'_context': message_context, '_comment': self._comment}

        # Plural support in Django works by using the "count" keyword
        counter_var = blocktrans_node.countervar
        if blocktrans_node.countervar:
            params[counter_var] = blocktrans_node.counter.token

        # Add any key/value pairs that hold placeholder/variable information
        # e.g. {% blocktrans user.name as username %}
        params.update({
            key: value.token
            for key, value in blocktrans_node.extra_context.items()
        })
        params = _render_params(params)

        # Retrieve any variables inside text, e.g.
        # "This is a {{ var }} and this is {{ another_var }}"
        variables_in_text = (_get_variable_names(blocktrans_node.singular) +
                             _get_variable_names(blocktrans_node.plural))

        # Reset the stored comment, so that it doesn't leak to the next token
        self._comment = None

        # Build the template of the tag for Transifex Native syntax
        is_multiline = '\n' in singular_text or '\n' in plural_text
        content = _make_plural(singular_text, plural_text, counter_var)

        # Source strings that contain XML symbols should use 'ut'. We determine
        # whether the string contains XML symbols by testing if an escaping
        # attempt changes it in any way.
        # eg `{% blocktrans %}a b{% endblocktrans %}` =>
        #        `{% t "a b" %}`
        # eg `{% blocktrans %}<xml>a</xml> b{% endblocktrans %}` =>
        #        `{% ut "<xml>a</xml> b" %}`
        if escape_html(content) != content:
            tag_name = "ut"
        else:
            tag_name = "t"

        has_apos, has_quot = "'" in content, '"' in content
        use_block = is_multiline or (has_apos and has_quot)
        if not use_block and has_quot:
            surround_with = "'"
        else:
            surround_with = '"'

        # Render the final output
        t_tag = ['{% ', tag_name]

        if not use_block:
            t_tag.extend([' ', surround_with, content, surround_with])
        if blocktrans_node.trimmed:
            if use_block:
                t_tag.append(' |trimmed')
            else:
                t_tag.append('|trimmed')
        if params.strip():
            t_tag.extend([' ', params])
        if blocktrans_node.asvar:
            t_tag.extend([' as ', blocktrans_node.asvar])
        t_tag.append(' %}')
        if use_block:
            t_tag.extend([content, '{% end', tag_name, ' %}'])
        t_tag = ''.join(t_tag)

        # Determine the confidence of the migration
        confidence = (Confidence.HIGH
                      if not variables_in_text else Confidence.LOW)

        # Create the actual migration
        return self._final_string_migration(original_string,
                                            t_tag,
                                            consumed_tokens=consumed_tokens,
                                            confidence=confidence)
 def get_column_value(self, obj, column, **kwargs):
     source_value = self.get_source_value(obj, column)
     return escape_html(source_value or column.value(obj, **kwargs)[0])
Beispiel #32
0
def get_search_fields(rendered_content, subject, content_matches, subject_matches):
    return dict(match_content=highlight_string(rendered_content, content_matches),
                match_subject=highlight_string(escape_html(subject), subject_matches))
    def render_table(self, arguments: Sequence[Mapping[str,
                                                       Any]]) -> List[str]:
        # TODO: Fix naming now that this no longer renders a table.
        table = []
        argument_template = """
<div class="api-argument" id="parameter-{argument}">
    <p class="api-argument-name"><strong>{argument}</strong> <span class="api-field-type">{type}</span> {required} {deprecated} <a href="#parameter-{argument}" class="api-argument-hover-link"><i class="fa fa-chain"></i></a></p>
    <div class="api-example">
        <span class="api-argument-example-label">Example</span>: <code>{example}</code>
    </div>
    <div class="api-description">{description}</div>
    <hr>
</div>"""

        md_engine = markdown.Markdown(extensions=[])
        arguments = sorted(arguments,
                           key=lambda argument: 'deprecated' in argument)
        for argument in arguments:
            description = argument['description']
            oneof = [
                '`' + str(item) + '`'
                for item in argument.get('schema', {}).get('enum', [])
            ]
            if oneof:
                description += '\nMust be one of: {}.'.format(', '.join(oneof))

            default = argument.get('schema', {}).get('default')
            if default is not None:
                description += f'\nDefaults to `{json.dumps(default)}`.'
            data_type = ""
            if 'schema' in argument:
                data_type = generate_data_type(argument['schema'])
            else:
                data_type = generate_data_type(
                    argument['content']['application/json']['schema'])

            # TODO: OpenAPI allows indicating where the argument goes
            # (path, querystring, form data...).  We should document this detail.
            example = ""
            if 'example' in argument:
                example = argument['example']
            else:
                example = json.dumps(
                    argument['content']['application/json']['example'])

            required_string: str = "required"
            if argument.get('in', '') == 'path':
                # Any path variable is required
                assert argument['required']
                required_string = 'required in path'

            if argument.get('required', False):
                required_block = f'<span class="api-argument-required">{required_string}</span>'
            else:
                required_block = '<span class="api-argument-optional">optional</span>'

            # Test to make sure deprecated parameters are marked so.
            if likely_deprecated_parameter(description):
                assert (argument['deprecated'])
            if argument.get('deprecated', False):
                deprecated_block = '<span class="api-argument-deprecated">Deprecated</span>'
            else:
                deprecated_block = ''

            table.append(
                argument_template.format(
                    argument=argument.get('argument') or argument.get('name'),
                    example=escape_html(example),
                    required=required_block,
                    deprecated=deprecated_block,
                    description=md_engine.convert(description),
                    type=data_type))

        return table
Beispiel #34
0
 def maybe_escape(self, text):
     if not self.escape:
         return text
     return escape_html(text)
Beispiel #35
0
def fetch_comments(request):
    """
    Fetch a list of comments as JSON.

    Args:
        request: May contain a `limit` GET parameter that specifies how many
            comments to get (by default: 300). Very high limits may decrease
            performance noticeably.

    Returns:
        A ``JsonResponse`` containing an JSON object of the form::

            {
                "<comment.id>": {
                    "msg": "<comment.message>",
                    "sem": <comment.score_sem>,
                    "pos": <author question ratings projection>,
                    "tag": "<comment.tag>",
                    "qid": <comment.question_id>
                },
                ...
            }

        The ``pos`` property is calculated by projecting the quantitative
        question ratings vector of the comment's author onto the first two
        principal components of the question ratings dataset (from
        :func:`calculate_principal_components`). This property is a list
        containing two numbers: the first and second projections, respectively.
    """
    try:
        limit = int(
            request.GET.get('limit', unicode(settings.DEFAULT_COMMENT_LIMIT)))
    except ValueError as error:
        return HttpResponseBadRequest(unicode(error))

    comments = (Comment.objects.filter(
        original=None, question__enabled=True,
        flagged=False).exclude(message='').all())
    if len(comments) > limit:
        comments = random.sample(comments, limit)

    respondent_id_map, _, ratings = generate_ratings_matrix()
    data_in_every_column = all(
        np.count_nonzero(~np.isnan(ratings[:, i]))
        for i in range(ratings.shape[1])) and ratings.size
    if data_in_every_column:
        normalized_ratings = normalize_ratings_matrix(ratings)
        components = calculate_principal_components(normalized_ratings, 2)

    data = {}
    for comment in comments:
        standard_error = comment.score_sem
        row_index = respondent_id_map[comment.respondent.id]
        position = [0, 0]
        if data_in_every_column:
            position = list(
                np.round(components.dot(normalized_ratings[row_index, :]), 3))

        # Projects the ratings by this comment's author onto the first two
        # principal components to generate the position (`pos`).
        if standard_error is None:
            standard_error = settings.DEFAULT_STANDARD_ERROR
        data[unicode(comment.id)] = {
            'msg': escape_html(comment.message),
            'sem': round(standard_error, 3),
            'pos': position,
            'tag': escape_html(comment.tag),
            'qid': comment.question_id
        }

    return JsonResponse(data)