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 ""), )
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)
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() })
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))
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
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), }
def _prepare_regexp_html(regexp): """Return HTML for a given regexp. Includes wordbreaks.""" if not regexp: return '' else: regexp_html = (escape_html(regexp).replace('|', '|​').replace( ']', ']​').replace(')', ')​')) return mark_safe(regexp_html)
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 description_inject(row_data): description = \ escape_html(str(row_data.description)).replace("\n", "<br/>") description = description.replace("\t", " ") description = description.replace(" " * 4, " " * 4) description = description.replace(" " * 3, " " * 3) description = description.replace(" " * 2, " " * 2) return mark_safe(description)
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
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
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)
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)
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)
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)
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
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
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)
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))
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 `<` => `&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
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
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])
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])
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
def maybe_escape(self, text): if not self.escape: return text return escape_html(text)
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)