예제 #1
0
파일: models.py 프로젝트: ikicic/skoljka
    def get_link(self, tooltip=False, url_suffix=''):
        # TODO: EDIT permission should immediately imply view permission
        # everywhere, not only here.

        # If prerequisites not met, do not output link.
        if EDIT not in getattr(self, '_cache_perm', []) \
                and not getattr(self, 'cache_prerequisites_met', False):
            # Do not show if this is a file or not, it doesn't matter.
            # Especially, don't put the link to the file itself!
            return mark_safe(u'<i class="icon-lock" title="Niste riješili neke '
                u'od preduvjeta za ovaj zadatak!"></i> '
                u'<span class="task-locked">{}</span>'.format(
                    xss.escape(self.name)))

        if self.file_attachment_id:
            url = self.cache_file_attachment_url
            icon = 'icon-book' if self.is_lecture else 'icon-file'
            file = u'<a href="{}" title="{}">'      \
                    u'<i class="{}"></i>'    \
                    u'</a> '.format(url, url[url.rfind('/') + 1:], icon)
        else:
            file = u''

        # If not solvable, automatically there is no tooltip.
        return mark_safe(u'{}<a href="/task/{}/{}" class="task{}">{}</a>'.format(
            file, self.id, url_suffix,
            ' task-tt-marker' if tooltip and self.solvable else '',
            xss.escape(self.name)))
예제 #2
0
파일: forms.py 프로젝트: ikicic/skoljka
    def __init__(self, *args, **kwargs):
        self.competition = kwargs.pop('competition')
        self.evaluator = get_evaluator(self.competition.evaluator_version)
        self.fixed_score = self.competition.fixed_task_score
        user = kwargs.pop('user')
        super(CompetitionTaskForm, self).__init__(*args, **kwargs)

        self.t_comment_extra_class = "ctask-comment"
        if self.instance.pk:
            self.fields['text'].initial = self.instance.task.content.text
            self.fields['comment'].initial = self.instance.comment.text
            self.t_comment_extra_class += \
                    " " + ctask_comment_class(self.instance, user)

        descriptor = self.initial.get('descriptor')
        if descriptor:
            variables = safe_parse_descriptor(self.evaluator, descriptor)
            self.fields['descriptor'].help_text = get_solution_help_text(
                    variables, error_message=_("Invalid!"), show_types=True)
        self.fields['descriptor'].label = mark_safe(
                xss.escape(_("Solution")) + \
                ' <a href="' + comp_url(self.competition, 'rules') +
                '" target="_blank"><i class="icon-question-sign" title="' +
                xss.escape(_("Help")) + '"></i></a>')
        if self.fixed_score:
            del self.fields['score']

        self.fields['text'].widget.attrs.update(
                {'class': 'comp-mathcontent-text', 'rows': 5})
        self.fields['comment'].widget.attrs.update(
                {'class': 'comp-mathcontent-text ctask-comment', 'rows': 3})
예제 #3
0
파일: __init__.py 프로젝트: ikicic/skoljka
def get_latex_html(latex_element, force_inline):
    """Given LatexElement instance generate <img> HTML."""
    inline = force_inline or latex_element.format in ['$%s$', '\(%s\)']
    latex_escaped = xss.escape(latex_element.text)
    depth = latex_element.depth

    if depth == ERROR_DEPTH_VALUE:
        # TODO: link to the log file.
        return u'<span class="mc-error-source" title="{}">{}</span>'.format(
                xss.escape(_("Invalid LaTeX.")),
                xss.escape(latex_element.format % latex_element.text))

    hash = latex_element.hash
    url = '%s%s/%s/%s/%s.png' % (IMG_URL_PATH, hash[0], hash[1], hash[2], hash)
    if inline:
        return u'<img src="%s" alt="%s" class="latex" ' \
                'style="vertical-align:%dpx">' % (url, latex_escaped, -depth)
    else:
        return u'<img src="%s" alt="%s" class="latex-center">' % \
                (url, latex_escaped)

    # # FIXME: don't save error message to depth
    # hash, depth = generate_svg(latex, format, inline)
    # if depth == ERROR_DEPTH_VALUE:
    #     # TODO: link to the log file.
    #     out.append('{{ INVALID LATEX }}')
    # else:
    #     url = '%s%s/%s/%s/%s.svg' % (IMG_URL_PATH, hash[0], hash[1], hash[2], hash)
    #     if inline:
    #         obj = '<object data="%s" type="image/svg+xml" alt="%s" class="latex" style="vertical-align:%fpt"></object>' % (url, latex_escaped, -depth)
    #     else:
    #         obj = '<object data="%s" type="image/svg+xml" alt="%s" class="latex-center"></object>' % (url, latex_escaped)
    return img
예제 #4
0
파일: bbcode.py 프로젝트: ikicic/skoljka
 def to_html(self, token, converter):
     if token.is_open():
         if len(token.attrs) > 1:
             raise BBUnexpectedParameters()
         if token.content is not None:
             return u'<a href="{}" rel="nofollow">{}</a>'.format(
                     xss.escape(token.content), xss.escape(token.content))
         return u'<a href="{}" rel="nofollow">'.format(
                 xss.escape(dict(token.attrs)['url']))
     return '</a>'
예제 #5
0
def _handle_latex_html(cnt, latex):
    """
        Generates LaTeX PNGs and outputs <img> tag.
    """
    latex_escaped = xss.escape(latex)

    inline = cnt == 1
    if cnt == 1:
        format = inline_format
    elif cnt == 2:
        format = block_format
    else:
        format = advanced_format

    # FIXME: don't save error message to depth
    hash, depth = generate_png(latex, format)
    if depth == ERROR_DEPTH_VALUE:
        return '{{ INVALID LATEX }}'
    else:
        url = '%s%s/%s/%s/%s.png' % (img_url_path, hash[0], hash[1], hash[2], hash)
        if inline:
            img = '<img src="%s" alt="%s" class="latex" style="vertical-align:%dpx">' % (url, latex_escaped, -depth)
        else:
            img = '<img src="%s" alt="%s" class="latex_center">' % (url, latex_escaped)

        return img
예제 #6
0
def _handle_latex_html(cnt, latex):
    """Generate LaTeX PNGs and outputs <img> tag."""
    latex_escaped = xss.escape(latex)

    inline = cnt == 1
    if cnt == 1:
        format = inline_format
    elif cnt == 2:
        format = block_format
    else:
        format = advanced_format

    # FIXME: don't save error message to depth
    latex_element = get_or_generate_png(format, latex)
    if latex_element.depth == ERROR_DEPTH_VALUE:
        return '{{ INVALID LATEX }}'
    else:
        hash = latex_element.hash
        url = '%s%s/%s/%s/%s.png' % (IMG_URL_PATH, hash[0], hash[1], hash[2], hash)
        if inline:
            img = '<img src="%s" alt="%s" class="latex" style="vertical-align:%dpx">' % (url, latex_escaped, -latex_element.depth)
        else:
            img = '<img src="%s" alt="%s" class="latex-center">' % (url, latex_escaped)

        return img
예제 #7
0
def userlink(user, what=None):
    name = None
    if what == 'full':
        name = user.get_full_name().strip()
    elif what:
        name = getattr(user, what, None)

    # full_name kao default bi stvarao gadne probleme kod PM-a
    if not name:
        name = user.username

    return mark_safe(u'<a href="/profile/%d/" title="%s">%s</a>' % (user.pk, escape(user.get_full_name()), escape(name)))
예제 #8
0
파일: bbcode.py 프로젝트: ikicic/skoljka
    def to_html(self, token, converter):
        if not token.is_open():
            return '</div></div>'
        if len(token.attrs) != 1:
            raise BBUnexpectedParameters()

        if token.attrs[0][1]:
            link_text = xss.escape(token.attrs[0][1])
        else:
            link_text = '+/-'
        return u'<div><a href="#" class="mc-hide-link">{}</a>' \
                u'<div class="mc-hide-content" style="display:none;">'.format(
                        link_text)
예제 #9
0
def generate_get_query_string(context, *args, **kwargs):
    """
        Generates GET part of URL given keys to remove (*args) and
        key-value pairs to add (**kwargs). Additionally, removes all
        keys specified in context[GENERATE_URL_TMP_KEYS] set.
        (for more info about this set, look at temporary_get_key)
    """

    get = context['request'].GET.copy()
    for key in args:
        if key in get:
            del get[key]
    for key in context.get(GENERATE_URL_TMP_KEYS, []):
        if key in get:
            del get[key]
    for key, value in kwargs.iteritems():
        get[key] = value
    return escape(get.urlencode())
예제 #10
0
파일: action.py 프로젝트: ikicic/skoljka
def add(actor, type_desc, **kwargs):
    type, subtype = type_desc
    action = Action(actor=actor, type=type, subtype=subtype, **kwargs)

    # can this be DRY-ed somehow?
    # ----- global -----
    if action.action_object:
        if hasattr(action.action_object, "name"):
            action.action_object_cache = action.action_object.name
        elif hasattr(action.action_object, "username"):
            action.action_object_cache = action.action_object.username
        elif hasattr(action.action_object, "value"):    # rating
            action.action_object_cache = str(action.action_object.value)

    if action.target:
        if hasattr(action.target, "name"):
            action.target_cache = action.target.name
        elif hasattr(action.target, "username"):
            action.target_cache = action.target.username
        elif action.target._meta.app_label == 'solution' and action.target._meta.module_name == 'solution':
            data = [
                action.target.author_id,
                action.target.author.username,
                action.target.task_id,
                action.target.task.name,
                action.target.task.author_id,
            ]
            # 250 chars should be enough for this
            action.target_cache = POST_SEND_CACHE_SEPARATOR.join([xss.escape(unicode(x)) for x in data])

    # ----- type specific -----
    if type == POST_SEND:
        T = action.action_object.content.text
        action.action_object_cache = T[:78] + '...' if len(T) > 80 else T

    action.save()
예제 #11
0
파일: bbcode.py 프로젝트: ikicic/skoljka
 def to_html(self, token, converter):
     if len(token.attrs) != 1 or token.attrs[0][1] is not None:
         raise BBUnexpectedParameters()
     return self.html_open + xss.escape(token.content) + self.html_close
예제 #12
0
파일: models.py 프로젝트: ikicic/skoljka
 def get_link(self):
     return mark_safe(u'<a href="{}">{}</a>'.format(
             self.get_absolute_url(), xss.escape(self.get_name())))
예제 #13
0
def _convert(T, type, handle_latex_func, escape_table, content=None,
        attachment_path=None): # XSS danger!!! Be careful
    """
        Converts MathContent format to HTML (type 0) or LaTeX (type 1)

        To support features like [img], it must be called with a
        a content instance.
    """

    # force strip
    T = T.strip()

    if type == TYPE_HTML:
        newline = '<br>'
    else:
        newline = '\n'

    i = 0
    n = len(T)
    out = []
    tag_stack = []
    while i < n:
        if T[i] == '\\':
            # parse \$ and similar
            if i + 1 < n:
                out.append(escape_table.get(T[i + 1], T[i + 1]))
            i += 2
        elif T[i:i+2] == '\r\n':
            out.append(newline)
            i += 2
        elif T[i] == '\r' or T[i] == '\n':
            out.append(newline)
            i += 1
        elif T[i] == '[':   # BBCode
            # TODO: [url] can't contain ]
            end = T.find(']', i)
            if end == -1:
                out.append('[')     # no error messages for now
                i += 1
            elif end == i + 1:
                out.append('[]')
                i += 2
            elif end == i + 2 and T[i+1] == '/':
                out.append('[/]')
                i += 3
            else: # non empty tag
                # here we make difference between TYPE_HTML and TYPE_LATEX
                # TYPE_HTML = first element of tag tuple
                # TYPE_LATEX = second element of tag tuple

                try:
                    tag, attrs = parse_bb_code(T[i+1:end])
                except:
                    # if bb code not valid (or if not bb code at all), output original text
                    out.append('[%s]' % T[i+1:end])
                    i = end + 1
                    continue

                if tag[0] == '/':
                    tag = tag[1:]
                    if not tag_stack or tag_stack[-1] != tag:
                        out.append('{{ Poredak otvorenih i zatvorenih tagova nije valjan. }}')
                    else:
                        out.append(tag_close[tag_stack.pop()][type])
                elif tag not in tag_open:
                    out.append('{{ Nevaljan tag &quot;%s&quot; }}' % xss.escape(tag))
                else:
                    # ask for close tag if there should be one
                    if tag_close.get(tag, None) is not None:
                        tag_stack.append(tag)

                    open = tag_open[tag][type]

                    # process attributes
                    # WARNING: currently HTML and LaTeX use same attribute names and formats!
                    extra = ''
                    if tag in tag_attrs:
                        for key, value in attrs.iteritems():
                            if key in tag_attrs[tag]:
                                if type == TYPE_HTML:
                                    extra += ' %s="%s"' % (key, xss.escape(attrs[key]))
                                else:
                                    extra += ',%s=%s' % (key, xss.escape(attrs[key]))

                    if tag == 'img':
                        if not content:
                            open = u'{{ Slika nije dostupna u pregledu }}'
                        elif 'attachment' not in attrs:
                            open = u'{{ Nedostaje "attachment" atribut }}'
                        else:
                            try:
                                k = int(attrs['attachment']) - 1
                                file = content.attachments.order_by('id')[k]
                                if type == TYPE_HTML:
                                    extra += ' src="%s"' % xss.escape(file.get_url())
                                else: # type == TYPE_LATEX
                                    if attachment_path:
                                        filename = '{}/{}/{}'.format(
                                            attachment_path, k, file.get_filename())
                                    else:
                                        filename = file.get_full_path_and_filename()
                                    extra = '[%s]{%s}' % (extra[1:], filename)

                            except:
                                open = u'{{ Greška pri preuzimanju img datoteke. (Nevaljan broj?) }}'
                    elif tag == 'url':
                        # TODO: show icon for external URLs
                        # Manually get the URL if not given.
                        if 'url' not in attrs:
                            url_end = T.find('[/url]', i)
                            if url_end == -1:
                                open = u'{{ Nedostaje [/url] }}'
                            else:
                                attrs['url'] = T[i + 5:url_end]
                        attrs['url'] = xss.escape(attrs.get('url', ''))

                    attrs.update({'extra': extra})
                    open %= attrs
                    out.append(open)
                i = end + 1
        elif T[i] == '$':
            # parse $  $, $$  $$ and $$$  $$$
            cnt = 0
            while i < n and T[i] == '$':
                cnt += 1
                i += 1
            if cnt > 3:
                cnt = 3

            # this should cover all weird cases with \\ and \$
            latex = []
            while i < n:
                if T[i:i+2] == '\\$' or T[i:i+2] == '\\\\':
                    latex.append(T[i:i+2])
                    i += 2
                elif cnt <= 2 and T[i] == '$' or cnt == 3 and T[i:i+2] == '$$':
                # It is possible to use $ ... $ inside inside of $$$ ... $$$.
                # This could be also written more strictly as
                # elif T[i:i+cnt] == '$' * cnt:
                    break;
                else:
                    latex.append(T[i])
                    i += 1

            # don't care how many $ are there, just skip them
            while i < n and T[i] == '$':
                i += 1

            latex = u''.join(latex)

            out.append(handle_latex_func(cnt, latex))
        else:
            out.append(escape_table.get(T[i], T[i]))
            i += 1

    if tag_stack:
        out.append('{{ Neki tagovi nisu zatvoreni }}')
        while tag_stack:
            out.append(tag_close[tag_stack.pop()][type])
    return u''.join(out)
예제 #14
0
def grouplink(group):
    return mark_safe(u'<a href="/usergroup/{}/">{}</a>'.format(
            group.id, xss.escape(group.name)))
예제 #15
0
def append_get_parameters(context):
    """Generate "?a=b" part of the URL.

    Returns an empty string if GET is empty."""
    get = context['request'].GET
    return '?' + escape(get.urlencode()) if get else ''
예제 #16
0
파일: bbcode.py 프로젝트: ikicic/skoljka
 def to_html(self, token, converter):
     val, index, attachment = self._check(token, converter)
     return u'<img src="{}" alt="Attachment #{}" class="latex"{}>'.format(
             xss.escape(attachment.get_url()), val,
             img_params_to_html(token.attrs))
예제 #17
0
파일: models.py 프로젝트: ikicic/skoljka
 def get_link(self):
     return mark_safe(u'<a href="{}" class="{}">{}</a>'.format(
             self.get_absolute_url(), self.get_type_css_class(),
             xss.escape(self.name)))
예제 #18
0
파일: __init__.py 프로젝트: ikicic/skoljka
    def convert_to_html(self):
        tokens = self._pre_convert_to_html()
        if self.errors_mode == Converter.ERRORS_ENABLED:
            error_func = lambda token: u'<span class="mc-error">' \
                    u'<span class="mc-error-source">{}</span> {}</span>'.format(
                        token.content, token.error_message)
        elif self.errors_mode == Converter.ERRORS_TESTING:
            error_func = lambda token: u"<<ERROR>>"
        else:
            error_func = lambda token: u""

        class HTMLConverterState(object):
            def __init__(self):
                self.any_content_yet = False
                self.is_in_paragraph = False
                self.indent_next = False
                self.all_no_indent = False

                # List of all supported lengths. None stands for the default
                # value. These are the HTML values.
                self.lengths_html = {'\\parindent': None, '\\parskip': None}


        self._state_stack = [HTMLConverterState()]
        self.state = self._state_stack[-1]

        output = []
        def add_content_par(content):
            """First check if paragraph should be added and then add content.
            No-op if content evaluates to False."""
            if not content:
                return

            state = self.state
            state.any_content_yet = True
            if not self.paragraphs_disabled and not state.is_in_paragraph:
                indent = state.indent_next and not state.all_no_indent

                css_class = ""
                css_style = ""
                parskip = state.lengths_html['\\parskip']
                if parskip is not None:
                    # It seems to be the top, not the bottom that's affected.
                    css_style += "margin-top:{};".format(parskip)

                if indent:
                    parindent = state.lengths_html['\\parindent']
                    if parindent is not None:
                        css_style += "text-indent:{};".format(parindent)
                    else:
                        css_class = "mc-indent"
                else:
                    css_class = "mc-noindent"

                output.append("<p{}{}>".format(
                    " class=\"{}\"".format(css_class) if css_class else "",
                    " style=\"{}\"".format(css_style) if css_style else ""))
            output.append(content)
            state.is_in_paragraph = True

        for token in tokens:
            if isinstance(token, TokenComment):
                continue
            elif isinstance(token, TokenOpenCurly):
                self.push_state()
            elif isinstance(token, TokenClosedCurly):
                if len(self._state_stack) == 1:
                    output.append(TokenError(_("Unexpected '}'"), '}'))
                else:
                    self.pop_state()
            elif isinstance(token, TokenMath):
                element = self.maths[(token.format, token.content)]
                add_content_par(
                        self.get_latex_html__func(element, token.force_inline))
            elif isinstance(token, TokenText):
                add_content_par(xss.escape(token.text).replace('~', '&nbsp;'))
            elif isinstance(token, TokenSimpleWhitespace):
                if self.state.any_content_yet:
                    output.append(" ")  # Single whitespace is enough.
            elif isinstance(token, TokenMultilineWhitespace):
                if self.paragraphs_disabled:
                    output.append("<br>")
                elif self.state.any_content_yet:
                    self.state.is_in_paragraph = False
                    self.state.indent_next = True
            elif isinstance(token, TokenError):
                add_content_par(error_func(token))
            elif isinstance(token, TokenCommand):
                command = latex_commands[token.command]
                # TODO: \begin{equation}...\end{equation}
                try:
                    if token.command in ['begin', 'end']:
                        output.append(command.to_html(token, self))
                    else:
                        add_content_par(command.to_html(token, self))
                except LatexValueError as e:
                    output.append(TokenError(e.message, '\\' + token.command))
            elif isinstance(token, TokenBBCode):
                add_content_par(self.process_bb(token, TYPE_HTML))
            else:
                raise NotImplementedError(repr(token))
        return self.finalize_output(output, error_func)