|
Pierre-Yves Chibon |
15e568 |
# -*- coding: utf-8 -*-
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
15e568 |
"""
|
|
Pierre-Yves Chibon |
b7c63b |
(c) 2014-2018 - Copyright Red Hat Inc
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
15e568 |
Authors:
|
|
Pierre-Yves Chibon |
15e568 |
Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
15e568 |
"""
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
22a554 |
# pylint: disable=too-many-branches
|
|
Pierre-Yves Chibon |
22a554 |
# pylint: disable=too-many-arguments
|
|
Pierre-Yves Chibon |
22a554 |
# pylint: disable=too-many-locals
|
|
Pierre-Yves Chibon |
11d3da |
|
|
Pierre-Yves Chibon |
11d3da |
|
|
Pierre-Yves Chibon |
67d1cc |
from __future__ import unicode_literals, absolute_import
|
|
Aurélien Bompard |
dcf6f6 |
|
|
Pierre-Yves Chibon |
15e568 |
import textwrap
|
|
Pierre-Yves Chibon |
f6a6e0 |
import logging
|
|
Ryan Lerch |
9fe1c6 |
from os.path import splitext
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
15e568 |
import arrow
|
|
Pierre-Yves Chibon |
267b16 |
import flask
|
|
Jeremy Cline |
00ab23 |
import six
|
|
Ryan Lerch |
3ec425 |
import bleach
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Aurélien Bompard |
831553 |
from six.moves.urllib.parse import urlparse, parse_qsl
|
|
Michael Scherer |
773db5 |
from jinja2 import escape
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
fe5017 |
import pagure.exceptions
|
|
Pierre-Yves Chibon |
930073 |
import pagure.lib.query
|
|
Pierre-Yves Chibon |
fe5017 |
import pagure.forms
|
|
Pierre-Yves Chibon |
b130e5 |
from pagure.config import config as pagure_config
|
|
Pierre-Yves Chibon |
b130e5 |
from pagure.ui import UI_NS
|
|
Aurélien Bompard |
619e2a |
from pagure.utils import authenticated, is_repo_committer, is_true
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
f6a6e0 |
_log = logging.getLogger(__name__)
|
|
Pierre-Yves Chibon |
15e568 |
# Jinja filters
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("hasattr")
|
|
Pierre-Yves Chibon |
01d17b |
def jinja_hasattr(obj, string):
|
|
Pierre-Yves Chibon |
01d17b |
""" Template filter checking if the provided object at the provided
|
|
Pierre-Yves Chibon |
01d17b |
string as attribute
|
|
Pierre-Yves Chibon |
01d17b |
"""
|
|
Pierre-Yves Chibon |
01d17b |
return hasattr(obj, string)
|
|
Pierre-Yves Chibon |
01d17b |
|
|
Pierre-Yves Chibon |
01d17b |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("render")
|
|
Pierre-Yves Chibon |
ccc810 |
def jinja_render(tmpl, **kwargs):
|
|
Pierre-Yves Chibon |
20f04d |
""" Render the given template with the provided arguments
|
|
Pierre-Yves Chibon |
ccc810 |
"""
|
|
Pierre-Yves Chibon |
ccc810 |
return flask.render_template_string(tmpl, **kwargs)
|
|
Pierre-Yves Chibon |
ccc810 |
|
|
Pierre-Yves Chibon |
ccc810 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("humanize")
|
|
Pierre-Yves Chibon |
15e568 |
def humanize_date(date):
|
|
Pierre-Yves Chibon |
15e568 |
""" Template filter returning the last commit date of the provided repo.
|
|
Pierre-Yves Chibon |
15e568 |
"""
|
|
Pierre-Yves Chibon |
623caa |
if date:
|
|
Pierre-Yves Chibon |
623caa |
return arrow.get(date).humanize()
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("format_ts")
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("format_datetime")
|
|
Pierre-Yves Chibon |
15e568 |
def format_ts(string):
|
|
Adam Williamson |
6205ad |
""" Template filter transforming a timestamp, datetime or anything
|
|
Adam Williamson |
6205ad |
else arrow.get() can handle to a human-readable date
|
|
Pierre-Yves Chibon |
15e568 |
"""
|
|
Adam Williamson |
6205ad |
# We *could* enhance this by allowing users to specify preferred
|
|
Adam Williamson |
6205ad |
# timezone, localized time format etc. and customizing this display
|
|
Adam Williamson |
6205ad |
# to user's preferences. But we don't have that, so for now, we
|
|
Adam Williamson |
6205ad |
# always use UTC timezone, and we don't use localized forms like
|
|
Adam Williamson |
6205ad |
# %b or %d because they will be 'localized' for the *server*.
|
|
Adam Williamson |
6205ad |
# This format should be pretty 'locale-neutral'.
|
|
Adam Williamson |
6205ad |
arr = arrow.get(string)
|
|
Pierre-Yves Chibon |
9c2953 |
return arr.strftime("%Y-%m-%d %H:%M:%S %Z")
|
|
Pierre-Yves Chibon |
9c2953 |
|
|
Pierre-Yves Chibon |
9c2953 |
|
|
Ryan Lerch |
3ec425 |
@UI_NS.app_template_filter("linkify")
|
|
Ryan Lerch |
3ec425 |
def linkify_text(text):
|
|
Ryan Lerch |
3ec425 |
""" escape all html tags with bleach, then use bleach to linkify
|
|
Ryan Lerch |
3ec425 |
"""
|
|
Ryan Lerch |
3ec425 |
if text:
|
|
Ryan Lerch |
3ec425 |
cleaned = bleach.clean(text, tags=[], attributes=[])
|
|
Ryan Lerch |
3ec425 |
return bleach.linkify(cleaned)
|
|
Ryan Lerch |
3ec425 |
else:
|
|
Ryan Lerch |
3ec425 |
return ""
|
|
Ryan Lerch |
3ec425 |
|
|
Ryan Lerch |
3ec425 |
|
|
Ryan Lerch |
9fe1c6 |
@UI_NS.app_template_filter("syntax_alias")
|
|
Ryan Lerch |
9fe1c6 |
def get_syntax_alias(filename):
|
|
Ryan Lerch |
9fe1c6 |
""" return an alias based on the filename that is used to
|
|
Ryan Lerch |
9fe1c6 |
override the automatic syntax highlighting dectection
|
|
Ryan Lerch |
9fe1c6 |
by highlight.js
|
|
Ryan Lerch |
9fe1c6 |
"""
|
|
Ryan Lerch |
9fe1c6 |
|
|
Ryan Lerch |
9fe1c6 |
override_rules = pagure_config.get(
|
|
Ryan Lerch |
9fe1c6 |
"SYNTAX_ALIAS_OVERRIDES", {".spec": "specfile", ".patch": "diff"}
|
|
Ryan Lerch |
9fe1c6 |
)
|
|
Ryan Lerch |
9fe1c6 |
fn, fn_ext = splitext(filename)
|
|
Ryan Lerch |
9fe1c6 |
|
|
Ryan Lerch |
9fe1c6 |
output = ""
|
|
Ryan Lerch |
9fe1c6 |
if fn_ext == "":
|
|
Ryan Lerch |
9fe1c6 |
output = "lang-plaintext"
|
|
Ryan Lerch |
9fe1c6 |
elif fn_ext in override_rules:
|
|
Ryan Lerch |
9fe1c6 |
output = "lang-" + override_rules[fn_ext]
|
|
Ryan Lerch |
9fe1c6 |
|
|
Ryan Lerch |
9fe1c6 |
return output
|
|
Ryan Lerch |
9fe1c6 |
|
|
Ryan Lerch |
9fe1c6 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("format_loc")
|
|
Pierre-Yves Chibon |
9c2953 |
def format_loc(
|
|
Pierre-Yves Chibon |
9c2953 |
loc,
|
|
Pierre-Yves Chibon |
9c2953 |
commit=None,
|
|
Pierre-Yves Chibon |
9c2953 |
filename=None,
|
|
Pierre-Yves Chibon |
9c2953 |
tree_id=None,
|
|
Pierre-Yves Chibon |
9c2953 |
prequest=None,
|
|
Pierre-Yves Chibon |
9c2953 |
index=None,
|
|
Pierre-Yves Chibon |
9c2953 |
isprdiff=False,
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Pierre-Yves Chibon |
15e568 |
""" Template filter putting the provided lines of code into a table
|
|
Pierre-Yves Chibon |
15e568 |
"""
|
|
Pierre-Yves Chibon |
15e568 |
if loc is None:
|
|
Pierre-Yves Chibon |
15e568 |
return
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
9c2953 |
output = ['
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
f6a6e0 |
commit_hash = commit
|
|
Pierre-Yves Chibon |
f6a6e0 |
if hasattr(commit_hash, "hex"):
|
|
Pierre-Yves Chibon |
f6a6e0 |
commit_hash = commit_hash.hex
|
|
Pierre-Yves Chibon |
f6a6e0 |
|
|
Pierre-Yves Chibon |
15e568 |
comments = {}
|
|
Pierre-Yves Chibon |
15e568 |
if prequest and not isinstance(prequest, flask.wrappers.Request):
|
|
Pierre-Yves Chibon |
15e568 |
for com in prequest.comments:
|
|
Pierre-Yves Chibon |
9c2953 |
if (
|
|
Pierre-Yves Chibon |
9c2953 |
commit
|
|
Pierre-Yves Chibon |
f6a6e0 |
and com.commit_id == commit_hash
|
|
Pierre-Yves Chibon |
9c2953 |
and com.filename == filename
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Pierre-Yves Chibon |
15e568 |
if com.line in comments:
|
|
Pierre-Yves Chibon |
15e568 |
comments[com.line].append(com)
|
|
Pierre-Yves Chibon |
15e568 |
else:
|
|
Pierre-Yves Chibon |
15e568 |
comments[com.line] = [com]
|
|
Pierre-Yves Chibon |
15e568 |
for key in comments:
|
|
Pierre-Yves Chibon |
9c2953 |
comments[key] = sorted(comments[key], key=lambda obj: obj.date_created)
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
15e568 |
if not index:
|
|
Pierre-Yves Chibon |
9c2953 |
index = ""
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
15e568 |
cnt = 1
|
|
Pierre-Yves Chibon |
9c2953 |
for line in loc.split("\n"):
|
|
Pierre-Yves Chibon |
15e568 |
if filename and commit:
|
|
Aurélien Bompard |
831553 |
if isinstance(filename, str) and six.PY2:
|
|
Pierre-Yves Chibon |
9c2953 |
filename = filename.decode("UTF-8")
|
|
Pierre-Yves Chibon |
9c2953 |
|
|
Pierre-Yves Chibon |
9c2953 |
if isprdiff and (
|
|
Pierre-Yves Chibon |
9c2953 |
line.startswith("@@")
|
|
Pierre-Yves Chibon |
9c2953 |
or line.startswith("+")
|
|
Pierre-Yves Chibon |
9c2953 |
or line.startswith("-")
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Pierre-Yves Chibon |
9c2953 |
if line.startswith("@@"):
|
|
Ryan Lerch |
19dc17 |
output.append(
|
|
Ryan Lerch |
19dc17 |
'
|
|
Ryan Lerch |
19dc17 |
id="c-%(commit)s-%(cnt_lbl)s">'
|
|
Pierre-Yves Chibon |
9c2953 |
% ({"cnt_lbl": cnt, "commit": commit})
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
elif line.startswith("+"):
|
|
Ryan Lerch |
19dc17 |
output.append(
|
|
Ryan Lerch |
19dc17 |
'
|
|
Ryan Lerch |
19dc17 |
id="c-%(commit)s-%(cnt_lbl)s">'
|
|
Pierre-Yves Chibon |
9c2953 |
% ({"cnt_lbl": cnt, "commit": commit})
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
elif line.startswith("-"):
|
|
Ryan Lerch |
19dc17 |
output.append(
|
|
Ryan Lerch |
19dc17 |
'
|
|
Ryan Lerch |
19dc17 |
id="c-%(commit)s-%(cnt_lbl)s">'
|
|
Pierre-Yves Chibon |
9c2953 |
% ({"cnt_lbl": cnt, "commit": commit})
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Ryan Lerch |
19dc17 |
else:
|
|
Ryan Lerch |
19dc17 |
output.append(
|
|
Ryan Lerch |
19dc17 |
''
|
|
Pierre-Yves Chibon |
9c2953 |
% ({"cnt_lbl": cnt, "commit": commit})
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Ryan Lerch |
19dc17 |
|
|
Pierre-Yves Chibon |
15e568 |
output.append(
|
|
Ryan Lerch |
19dc17 |
''
|
|
Pierre-Yves Chibon |
11d3da |
'
|
|
Pierre-Yves Chibon |
f620a6 |
'"%(cnt_lbl)s" data-file-number='
|
|
Pierre-Yves Chibon |
f620a6 |
'"%(line)s">'
|
|
Ryan Lerch |
19dc17 |
'
|
|
Pierre-Yves Chibon |
c72242 |
' data-filename="%(filename)s" data-commit="%(commit)s"'
|
|
Pierre-Yves Chibon |
c2e1f7 |
' data-tree="%(tree_id)s">'
|
|
Pierre-Yves Chibon |
9c2953 |
""
|
|
Julen Landa Alustiza |
9b6ae7 |
'
|
|
Pierre-Yves Chibon |
11d3da |
'alt="Add comment" title="Add comment">'
|
|
Pierre-Yves Chibon |
9c2953 |
""
|
|
Pierre-Yves Chibon |
9c2953 |
""
|
|
Pierre-Yves Chibon |
9c2953 |
% (
|
|
Pierre-Yves Chibon |
15e568 |
{
|
|
Pierre-Yves Chibon |
f620a6 |
"cnt": "_%s__%s" % (index, cnt),
|
|
Pierre-Yves Chibon |
9c2953 |
"cnt_lbl": cnt,
|
|
Pierre-Yves Chibon |
f620a6 |
"line": index,
|
|
Pierre-Yves Chibon |
9c2953 |
"filename": filename,
|
|
Pierre-Yves Chibon |
9c2953 |
"commit": commit,
|
|
Pierre-Yves Chibon |
9c2953 |
"tree_id": tree_id,
|
|
Pierre-Yves Chibon |
15e568 |
}
|
|
Pierre-Yves Chibon |
15e568 |
)
|
|
Pierre-Yves Chibon |
15e568 |
)
|
|
Pierre-Yves Chibon |
15e568 |
else:
|
|
Pierre-Yves Chibon |
15e568 |
output.append(
|
|
Pierre-Yves Chibon |
15e568 |
''
|
|
Pierre-Yves Chibon |
11d3da |
'
|
|
Pierre-Yves Chibon |
11d3da |
'"%(cnt_lbl)s">'
|
|
Pierre-Yves Chibon |
9c2953 |
% ({"cnt": "%s_%s" % (index, cnt), "cnt_lbl": cnt})
|
|
Pierre-Yves Chibon |
15e568 |
)
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
15e568 |
cnt += 1
|
|
Pierre-Yves Chibon |
15e568 |
if not line:
|
|
Pierre-Yves Chibon |
15e568 |
output.append(line)
|
|
Pierre-Yves Chibon |
15e568 |
continue
|
|
Pierre-Yves Chibon |
9c2953 |
if line.startswith("@@"):
|
|
Pierre-Yves Chibon |
bb2305 |
if prequest and prequest.project_from:
|
|
Pierre-Yves Chibon |
9c2953 |
rangeline = (
|
|
Pierre-Yves Chibon |
9c2953 |
line.partition("@@ ")[2]
|
|
Pierre-Yves Chibon |
9c2953 |
if line.partition("@@ ")[1] == "@@ "
|
|
Pierre-Yves Chibon |
9c2953 |
else None
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pradeep CE (cep) |
208647 |
if rangeline:
|
|
Pierre-Yves Chibon |
9c2953 |
rangeline = rangeline.split(" @@")[0]
|
|
Pierre-Yves Chibon |
9c2953 |
linenumber = rangeline.split("+")[1].split(",")[0]
|
|
Pradeep CE (cep) |
208647 |
line = line + '
|
|
Pradeep CE (cep) |
c90835 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_file",
|
|
Pradeep CE (cep) |
208647 |
repo=prequest.project_from.name,
|
|
Pradeep CE (cep) |
208647 |
username=prequest.project_from.user.username
|
|
Pierre-Yves Chibon |
9c2953 |
if prequest.project_from.is_fork
|
|
Pierre-Yves Chibon |
9c2953 |
else None,
|
|
Pradeep CE (cep) |
208647 |
namespace=prequest.project_from.namespace,
|
|
Pradeep CE (cep) |
208647 |
identifier=prequest.branch_from,
|
|
Pierre-Yves Chibon |
9c2953 |
filename=filename,
|
|
Pierre-Yves Chibon |
9c2953 |
),
|
|
Pierre-Yves Chibon |
9c2953 |
linenumber,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
line = (
|
|
Pierre-Yves Chibon |
9c2953 |
line
|
|
Pierre-Yves Chibon |
9c2953 |
+ 'class="open_changed_file_icon_wrap">'
|
|
Pierre-Yves Chibon |
9c2953 |
+ '
|
|
Pierre-Yves Chibon |
9c2953 |
+ 'alt="Open changed file" '
|
|
Pierre-Yves Chibon |
9c2953 |
+ 'title="Open changed file">'
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
|
|
Pierre-Yves Chibon |
9c2953 |
if isprdiff and (
|
|
Pierre-Yves Chibon |
9c2953 |
line.startswith("@@")
|
|
Pierre-Yves Chibon |
9c2953 |
or line.startswith("+")
|
|
Pierre-Yves Chibon |
9c2953 |
or line.startswith("-")
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Pierre-Yves Chibon |
9c2953 |
if line.startswith("@@"):
|
|
Ryan Lerch |
19dc17 |
output.append(
|
|
Ryan Lerch |
19dc17 |
'\
|
|
Ryan Lerch |
19dc17 |
%s '
|
|
Pierre-Yves Chibon |
9c2953 |
% line
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
elif line.startswith("+"):
|
|
Ryan Lerch |
19dc17 |
output.append(
|
|
Ryan Lerch |
19dc17 |
'\
|
|
Ryan Lerch |
19dc17 |
%s '
|
|
Ryan Lerch |
1fffee |
% escape(line)
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
elif line.startswith("-"):
|
|
Ryan Lerch |
19dc17 |
output.append(
|
|
Ryan Lerch |
19dc17 |
'\
|
|
Ryan Lerch |
19dc17 |
%s '
|
|
Ryan Lerch |
1fffee |
% escape(line)
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Ryan Lerch |
19dc17 |
else:
|
|
Ryan Lerch |
19dc17 |
output.append(
|
|
Ryan Lerch |
1fffee |
'%s '
|
|
Ryan Lerch |
1fffee |
% (escape(line))
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
|
|
Pierre-Yves Chibon |
9c2953 |
output.append("")
|
|
Pierre-Yves Chibon |
9c2953 |
|
|
Pierre-Yves Chibon |
9c2953 |
tpl_edit = (
|
|
Pierre-Yves Chibon |
9c2953 |
'
|
|
Pierre-Yves Chibon |
9c2953 |
'class="btn btn-outline-primary border-0" '
|
|
Pierre-Yves Chibon |
9c2953 |
'data-comment="%(commentid)s" '
|
|
Pierre-Yves Chibon |
9c2953 |
'data-objid="%(requestid)s">'
|
|
Pierre-Yves Chibon |
9c2953 |
''
|
|
Pierre-Yves Chibon |
9c2953 |
""
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
tpl_edited = (
|
|
Pierre-Yves Chibon |
9c2953 |
'<small class="text-muted" title="%(edit_date)s"> '</small>
|
|
Pierre-Yves Chibon |
9c2953 |
"Edited %(human_edit_date)s by %(user)s "
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
|
|
Pierre-Yves Chibon |
9c2953 |
tpl_delete = (
|
|
Julen Landa Alustiza |
0e3248 |
'
|
|
Julen Landa Alustiza |
0e3248 |
'delete_comment_btn" title="Remove comment" name="drop_comment"'
|
|
Julen Landa Alustiza |
0e3248 |
'value="%(commentid)s" type="submit">'
|
|
Julen Landa Alustiza |
0e3248 |
''
|
|
Pierre-Yves Chibon |
9c2953 |
""
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
cbbc7b |
|
|
Pierre-Yves Chibon |
15e568 |
if cnt - 1 in comments:
|
|
Pierre-Yves Chibon |
15e568 |
for comment in comments[cnt - 1]:
|
|
Pierre-Yves Chibon |
cbbc7b |
|
|
Pierre-Yves Chibon |
9c2953 |
templ_delete = ""
|
|
Pierre-Yves Chibon |
9c2953 |
templ_edit = ""
|
|
Pierre-Yves Chibon |
9c2953 |
templ_edited = ""
|
|
Pierre-Yves Chibon |
b8c7ae |
if authenticated() and (
|
|
Pierre-Yves Chibon |
9c2953 |
(
|
|
Pierre-Yves Chibon |
9c2953 |
is_true(comment.parent.status, ["true", "open"])
|
|
Pierre-Yves Chibon |
9c2953 |
and comment.user.user == flask.g.fas_user.username
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
or is_repo_committer(comment.parent.project)
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Pierre-Yves Chibon |
9c2953 |
templ_delete = tpl_delete % ({"commentid": comment.id})
|
|
Pierre-Yves Chibon |
9c2953 |
templ_edit = tpl_edit % (
|
|
Pierre-Yves Chibon |
9c2953 |
{
|
|
Pierre-Yves Chibon |
9c2953 |
"edit_url": flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.pull_request_edit_comment",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=comment.parent.project.name,
|
|
Pierre-Yves Chibon |
58e90c |
namespace=comment.parent.project.namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
requestid=comment.parent.id,
|
|
Pierre-Yves Chibon |
9c2953 |
commentid=comment.id,
|
|
Pierre-Yves Chibon |
9c2953 |
username=comment.parent.user.user
|
|
Pierre-Yves Chibon |
9c2953 |
if comment.parent.project.is_fork
|
|
Pierre-Yves Chibon |
9c2953 |
else None,
|
|
Pierre-Yves Chibon |
9c2953 |
),
|
|
Pierre-Yves Chibon |
9c2953 |
"requestid": comment.parent.id,
|
|
Pierre-Yves Chibon |
9c2953 |
"commentid": comment.id,
|
|
Pierre-Yves Chibon |
9c2953 |
}
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
cbbc7b |
|
|
Pierre-Yves Chibon |
91f4c6 |
if comment.edited_on:
|
|
Pierre-Yves Chibon |
9c2953 |
templ_edited = tpl_edited % (
|
|
Pierre-Yves Chibon |
9c2953 |
{
|
|
Pierre-Yves Chibon |
9c2953 |
"edit_date": format_ts(comment.edited_on),
|
|
Pierre-Yves Chibon |
9c2953 |
"human_edit_date": humanize_date(
|
|
Pierre-Yves Chibon |
9c2953 |
comment.edited_on
|
|
Pierre-Yves Chibon |
9c2953 |
),
|
|
Pierre-Yves Chibon |
9c2953 |
"user": comment.editor.user,
|
|
Pierre-Yves Chibon |
9c2953 |
}
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
91f4c6 |
|
|
Pierre-Yves Chibon |
15e568 |
output.append(
|
|
Ryan Lerch |
1fa495 |
''
|
|
Ryan Lerch |
19dc17 |
''
|
|
Ryan Lerch |
19dc17 |
''
|
|
Ryan Lerch |
1fa495 |
'
|
|
Ryan Lerch |
1fa495 |
'align-items-center px-3 py-2">'
|
|
Pierre-Yves Chibon |
9c2953 |
""
|
|
Ryan Lerch |
1fa495 |
'
|
|
Pierre-Yves Chibon |
bc4f2b |
''
|
|
Pierre-Yves Chibon |
71f685 |
''
|
|
Pierre-Yves Chibon |
9c2953 |
"%(user)s commented "
|
|
Ryan Lerch |
79145c |
'
|
|
Pierre-Yves Chibon |
c7f2f6 |
'to this headline" href="#comment-%(commentid)s">'
|
|
Pierre-Yves Chibon |
bc4f2b |
'%(human_date)s'
|
|
Pierre-Yves Chibon |
9c2953 |
""
|
|
Pierre-Yves Chibon |
9c2953 |
""
|
|
Ryan Lerch |
19dc17 |
''
|
|
Pierre-Yves Chibon |
9c2953 |
"%(templ_edit)s"
|
|
Pierre-Yves Chibon |
9c2953 |
"%(templ_delete)s"
|
|
Pierre-Yves Chibon |
9c2953 |
""
|
|
Pierre-Yves Chibon |
9c2953 |
""
|
|
Ryan Lerch |
1fa495 |
''
|
|
Pierre-Yves Chibon |
9c2953 |
"<small></small>"
|
|
Pierre-Yves Chibon |
bc4f2b |
'<section class="issue_comment">'</section>
|
|
Pierre-Yves Chibon |
bc4f2b |
''
|
|
Pierre-Yves Chibon |
9c2953 |
"%(comment)s"
|
|
Pierre-Yves Chibon |
9c2953 |
""
|
|
Pierre-Yves Chibon |
9c2953 |
""
|
|
Pierre-Yves Chibon |
9c2953 |
""
|
|
Pierre-Yves Chibon |
9c2953 |
""
|
|
Pierre-Yves Chibon |
9c2953 |
% (
|
|
Pierre-Yves Chibon |
15e568 |
{
|
|
Pierre-Yves Chibon |
9c2953 |
"url": flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_user", username=comment.user.user
|
|
Pierre-Yves Chibon |
9c2953 |
),
|
|
Pierre-Yves Chibon |
9c2953 |
"templ_delete": templ_delete,
|
|
Pierre-Yves Chibon |
9c2953 |
"templ_edit": templ_edit,
|
|
Pierre-Yves Chibon |
9c2953 |
"templ_edited": templ_edited,
|
|
Pierre-Yves Chibon |
9c2953 |
"user": comment.user.user,
|
|
Pierre-Yves Chibon |
9c2953 |
"user_html": comment.user.html_title,
|
|
Pierre-Yves Chibon |
9c2953 |
"avatar_url": avatar_url(
|
|
Pierre-Yves Chibon |
9c2953 |
comment.user.default_email, 16
|
|
Pierre-Yves Chibon |
9c2953 |
),
|
|
Pierre-Yves Chibon |
9c2953 |
"date": format_ts(comment.date_created),
|
|
Pierre-Yves Chibon |
9c2953 |
"human_date": humanize_date(comment.date_created),
|
|
Pierre-Yves Chibon |
9c2953 |
"comment": markdown_filter(comment.comment),
|
|
Pierre-Yves Chibon |
9c2953 |
"commentid": comment.id,
|
|
Pierre-Yves Chibon |
15e568 |
}
|
|
Pierre-Yves Chibon |
15e568 |
)
|
|
Pierre-Yves Chibon |
15e568 |
)
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
9c2953 |
output.append("")
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
9c2953 |
return "\n".join(output)
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("blame_loc")
|
|
Pierre-Yves Chibon |
833d1f |
def blame_loc(loc, repo, username, blame):
|
|
Pierre-Yves Chibon |
833d1f |
""" Template filter putting the provided lines of code into a table
|
|
Pierre-Yves Chibon |
17526c |
|
|
Pierre-Yves Chibon |
17526c |
|
|
Pierre-Yves Chibon |
17526c |
This method blame lines of code (loc) takes as input a text (lines of
|
|
Pierre-Yves Chibon |
17526c |
code) concerning a given repo, with its repo and a pygit2.Blame object
|
|
Pierre-Yves Chibon |
17526c |
and convert it into a html table displayed to the user with the git
|
|
Pierre-Yves Chibon |
17526c |
blame information (user, commit, commit date).
|
|
Pierre-Yves Chibon |
17526c |
|
|
Jeremy Cline |
00ab23 |
:arg loc: a unicode object of the lines of code to display (in this case,
|
|
Pierre-Yves Chibon |
17526c |
most likely the content of a file).
|
|
Pierre-Yves Chibon |
17526c |
:arg repo: the name of the repo in which this file is.
|
|
Pierre-Yves Chibon |
17526c |
:arg username: the user name of the user whose repo this is, if the repo
|
|
Pierre-Yves Chibon |
17526c |
is not a *fork*, this value is ``None``.
|
|
Pierre-Yves Chibon |
17526c |
:arg blame: a pygit2.Blame object allowing us to link a given line of
|
|
Pierre-Yves Chibon |
17526c |
code to a commit.
|
|
Pierre-Yves Chibon |
17526c |
|
|
Pierre-Yves Chibon |
833d1f |
"""
|
|
Pierre-Yves Chibon |
833d1f |
if loc is None:
|
|
Pierre-Yves Chibon |
833d1f |
return
|
|
Pierre-Yves Chibon |
833d1f |
|
|
Jeremy Cline |
00ab23 |
if not isinstance(loc, six.text_type):
|
|
Pierre-Yves Chibon |
9c2953 |
raise ValueError('"loc" must be a unicode string, not %s' % type(loc))
|
|
Jeremy Cline |
00ab23 |
|
|
Pierre-Yves Chibon |
9c2953 |
output = ['
|
|
Pierre-Yves Chibon |
833d1f |
|
|
Pierre-Yves Chibon |
9c2953 |
for idx, line in enumerate(loc.split("\n")):
|
|
Pierre-Yves Chibon |
9c2953 |
if line == "":
|
|
Pierre-Yves Chibon |
833d1f |
break
|
|
Pierre-Yves Chibon |
a2e119 |
|
|
Pierre-Yves Chibon |
a2e119 |
try:
|
|
Pierre-Yves Chibon |
a2e119 |
diff = blame.for_line(idx + 1)
|
|
Pierre-Yves Chibon |
a2e119 |
except IndexError:
|
|
Pierre-Yves Chibon |
a2e119 |
# Happens at the end of the file, since we are using idx + 1
|
|
Pierre-Yves Chibon |
a2e119 |
continue
|
|
Pierre-Yves Chibon |
a2e119 |
|
|
Pierre-Yves Chibon |
833d1f |
output.append(
|
|
Pierre-Yves Chibon |
833d1f |
''
|
|
Pierre-Yves Chibon |
833d1f |
'
|
|
Pierre-Yves Chibon |
9c2953 |
'"%(cnt)s">' % ({"cnt": idx + 1})
|
|
Pierre-Yves Chibon |
833d1f |
)
|
|
Pierre-Yves Chibon |
833d1f |
|
|
Pierre-Yves Chibon |
71b6e5 |
committer = None
|
|
Pierre-Yves Chibon |
71b6e5 |
try:
|
|
Pierre-Yves Chibon |
71b6e5 |
committer = diff.orig_committer
|
|
Pierre-Yves Chibon |
71b6e5 |
except ValueError:
|
|
Pierre-Yves Chibon |
71b6e5 |
pass
|
|
Pierre-Yves Chibon |
833d1f |
output.append(
|
|
Pierre-Yves Chibon |
9c2953 |
'%s'
|
|
Pierre-Yves Chibon |
9c2953 |
% (
|
|
Pierre-Yves Chibon |
9c2953 |
author_to_user(committer, with_name=False)
|
|
Pierre-Yves Chibon |
9c2953 |
if committer
|
|
Pierre-Yves Chibon |
9c2953 |
else " "
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
833d1f |
)
|
|
Pierre-Yves Chibon |
a2e119 |
|
|
Pierre-Yves Chibon |
833d1f |
output.append(
|
|
Pierre-Yves Chibon |
9c2953 |
'%s'
|
|
Pierre-Yves Chibon |
9c2953 |
% (
|
|
Pierre-Yves Chibon |
0c0047 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_commit",
|
|
Pierre-Yves Chibon |
0c0047 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
0c0047 |
username=username,
|
|
Pierre-Yves Chibon |
0c0047 |
namespace=repo.namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
commitid=diff.final_commit_id,
|
|
Pierre-Yves Chibon |
833d1f |
),
|
|
Pierre-Yves Chibon |
9c2953 |
shorted_commit(diff.final_commit_id),
|
|
Pierre-Yves Chibon |
833d1f |
)
|
|
Pierre-Yves Chibon |
833d1f |
)
|
|
Pierre-Yves Chibon |
967e77 |
output.append(
|
|
Pierre-Yves Chibon |
d156c8 |
'%s ' % no_js(line)
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
output.append("")
|
|
Pierre-Yves Chibon |
833d1f |
|
|
Pierre-Yves Chibon |
9c2953 |
output.append("")
|
|
Pierre-Yves Chibon |
833d1f |
|
|
Pierre-Yves Chibon |
9c2953 |
return "\n".join(output)
|
|
Pierre-Yves Chibon |
833d1f |
|
|
Pierre-Yves Chibon |
833d1f |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("wraps")
|
|
Pierre-Yves Chibon |
15e568 |
def text_wraps(text, size=10):
|
|
Pierre-Yves Chibon |
15e568 |
""" Template filter to wrap text at a specified size
|
|
Pierre-Yves Chibon |
15e568 |
"""
|
|
Pierre-Yves Chibon |
15e568 |
if text:
|
|
Pierre-Yves Chibon |
15e568 |
parts = textwrap.wrap(text, size)
|
|
Pierre-Yves Chibon |
15e568 |
if len(parts) > 1:
|
|
Pierre-Yves Chibon |
9c2953 |
parts = "%s..." % parts[0]
|
|
Pierre-Yves Chibon |
15e568 |
else:
|
|
Pierre-Yves Chibon |
15e568 |
parts = parts[0]
|
|
Pierre-Yves Chibon |
15e568 |
return parts
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("avatar")
|
|
Ryan Lerch |
6d2e06 |
def avatar(packager, size=64, css_class=None):
|
|
chocos10 |
6e4a4f |
""" Template filter that returns html for avatar of any given Username.
|
|
Pierre-Yves Chibon |
15e568 |
"""
|
|
Aurélien Bompard |
619e2a |
if not isinstance(packager, six.text_type):
|
|
Pierre-Yves Chibon |
9c2953 |
packager = packager.decode("utf-8")
|
|
Aurélien Bompard |
831553 |
|
|
Pierre-Yves Chibon |
9c2953 |
if "@" not in packager:
|
|
Pierre-Yves Chibon |
930073 |
user = pagure.lib.query.search_user(flask.g.session, username=packager)
|
|
Pierre-Yves Chibon |
f6cf03 |
if user:
|
|
Pierre-Yves Chibon |
f6cf03 |
packager = user.default_email
|
|
Pierre-Yves Chibon |
f6cf03 |
|
|
Ryan Lerch |
6d2e06 |
class_string = "avatar circle"
|
|
Ryan Lerch |
6d2e06 |
if css_class:
|
|
Pierre-Yves Chibon |
77bdcd |
class_string = class_string + " " + css_class
|
|
Ryan Lerch |
6d2e06 |
|
|
Ryan Lerch |
6d2e06 |
output = '' % (
|
|
Ryan Lerch |
6d2e06 |
class_string,
|
|
Pierre-Yves Chibon |
9c2953 |
avatar_url(packager, size),
|
|
Pierre-Yves Chibon |
15e568 |
)
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
15e568 |
return output
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("avatar_url")
|
|
Pierre-Yves Chibon |
13de4a |
def avatar_url(email, size=64):
|
|
chocos10 |
6e4a4f |
""" Template filter that returns html for avatar of any given Email.
|
|
Pierre-Yves Chibon |
13de4a |
"""
|
|
Pierre-Yves Chibon |
930073 |
return pagure.lib.query.avatar_url_from_email(email, size)
|
|
Pierre-Yves Chibon |
13de4a |
|
|
Pierre-Yves Chibon |
13de4a |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("short")
|
|
Pierre-Yves Chibon |
15e568 |
def shorted_commit(cid):
|
|
Pierre-Yves Chibon |
15e568 |
"""Gets short version of the commit id"""
|
|
Pierre-Yves Chibon |
9c2953 |
return ("%s" % cid)[: pagure_config["SHORT_LENGTH"]]
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("markdown")
|
|
Pierre-Yves Chibon |
15e568 |
def markdown_filter(text):
|
|
Pierre-Yves Chibon |
15e568 |
""" Template filter converting a string into html content using the
|
|
Pierre-Yves Chibon |
15e568 |
markdown library.
|
|
Pierre-Yves Chibon |
15e568 |
"""
|
|
Pierre-Yves Chibon |
930073 |
return pagure.lib.query.text2markdown(text)
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
15e568 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("patch_to_diff")
|
|
Pierre-Yves Chibon |
15e568 |
def patch_to_diff(patch):
|
|
Pierre-Yves Chibon |
15e568 |
"""Render a hunk as a diff"""
|
|
Patrick Uiterwijk |
b68dfe |
content = []
|
|
Pierre-Yves Chibon |
15e568 |
for hunk in patch.hunks:
|
|
Pierre-Yves Chibon |
9c2953 |
content.append(
|
|
Pierre-Yves Chibon |
9c2953 |
"@@ -%i,%i +%i,%i @@\n"
|
|
Pierre-Yves Chibon |
9c2953 |
% (hunk.old_start, hunk.old_lines, hunk.new_start, hunk.new_lines)
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Patrick Uiterwijk |
b68dfe |
|
|
Pierre-Yves Chibon |
15e568 |
for line in hunk.lines:
|
|
Pierre-Yves Chibon |
9c2953 |
if hasattr(line, "content"):
|
|
Pierre-Yves Chibon |
2767e0 |
origin = line.origin
|
|
Pierre-Yves Chibon |
9c2953 |
if line.origin in ["<", ">", "="]:
|
|
Pierre-Yves Chibon |
9c2953 |
origin = ""
|
|
Pierre-Yves Chibon |
9c2953 |
content.append(origin + " " + line.content)
|
|
Pierre-Yves Chibon |
a55741 |
else:
|
|
Pierre-Yves Chibon |
44cd3f |
# Avoid situation where at the end of a file we get:
|
|
Pierre-Yves Chibon |
44cd3f |
# + foo<
|
|
Pierre-Yves Chibon |
44cd3f |
# \ No newline at end of file
|
|
Pierre-Yves Chibon |
9c2953 |
if line[0] in ["<", ">", "="]:
|
|
Pierre-Yves Chibon |
9c2953 |
line = ("", line[1])
|
|
Pierre-Yves Chibon |
9c2953 |
content.append(" ".join(line))
|
|
Pierre-Yves Chibon |
44cd3f |
|
|
Pierre-Yves Chibon |
9c2953 |
return "".join(content)
|
|
Pierre-Yves Chibon |
10a437 |
|
|
Pierre-Yves Chibon |
10a437 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("author2user")
|
|
Pierre-Yves Chibon |
833d1f |
def author_to_user(author, size=16, cssclass=None, with_name=True):
|
|
Pierre-Yves Chibon |
10a437 |
""" Template filter transforming a pygit2 Author object into a text
|
|
Pierre-Yves Chibon |
10a437 |
either with just the username or linking to the user in pagure.
|
|
Pierre-Yves Chibon |
10a437 |
"""
|
|
Michael Scherer |
773db5 |
output = escape(author.name)
|
|
Pierre-Yves Chibon |
86c3f2 |
if not author.email:
|
|
Pierre-Yves Chibon |
86c3f2 |
return output
|
|
Pierre-Yves Chibon |
930073 |
user = pagure.lib.query.search_user(flask.g.session, email=author.email)
|
|
Pierre-Yves Chibon |
10a437 |
if user:
|
|
Pierre-Yves Chibon |
9c2953 |
output = (
|
|
Pierre-Yves Chibon |
9c2953 |
"%(avatar)s
|
|
Pierre-Yves Chibon |
833d1f |
"%(cssclass)s>%(username)s"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
833d1f |
if not with_name:
|
|
Pierre-Yves Chibon |
9c2953 |
output = (
|
|
Pierre-Yves Chibon |
9c2953 |
"
|
|
Pierre-Yves Chibon |
833d1f |
"%(cssclass)s>%(avatar)s"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
833d1f |
|
|
Pierre-Yves Chibon |
833d1f |
output = output % (
|
|
Pierre-Yves Chibon |
833d1f |
{
|
|
Pierre-Yves Chibon |
9c2953 |
"avatar": avatar(user.default_email, size),
|
|
Pierre-Yves Chibon |
9c2953 |
"url": flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_user", username=user.username
|
|
Pierre-Yves Chibon |
9c2953 |
),
|
|
Pierre-Yves Chibon |
9c2953 |
"cssclass": ('class="%s"' % cssclass) if cssclass else "",
|
|
Pierre-Yves Chibon |
9c2953 |
"username": user.username,
|
|
Pierre-Yves Chibon |
9c2953 |
"name": escape(author.name),
|
|
Pierre-Yves Chibon |
833d1f |
}
|
|
Pierre-Yves Chibon |
c1b151 |
)
|
|
Pierre-Yves Chibon |
c1b151 |
|
|
Pierre-Yves Chibon |
10a437 |
return output
|
|
Pierre-Yves Chibon |
bcc50f |
|
|
Pierre-Yves Chibon |
bcc50f |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("author2avatar")
|
|
Pierre-Yves Chibon |
b8c7ae |
def author_to_avatar(author, size=32):
|
|
Pierre-Yves Chibon |
b8c7ae |
""" Template filter transforming a pygit2 Author object into an avatar.
|
|
Pierre-Yves Chibon |
bcc50f |
"""
|
|
Pierre-Yves Chibon |
b7c63b |
if not author.email:
|
|
Pierre-Yves Chibon |
9c2953 |
return ""
|
|
Pierre-Yves Chibon |
930073 |
user = pagure.lib.query.search_user(flask.g.session, email=author.email)
|
|
Pierre-Yves Chibon |
570175 |
output = user.default_email if user else author.email
|
|
Pierre-Yves Chibon |
9c2953 |
return avatar(output.encode("utf-8"), size)
|
|
Pierre-Yves Chibon |
3578fd |
|
|
Pierre-Yves Chibon |
3578fd |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("author2user_commits")
|
|
Pierre-Yves Chibon |
bea195 |
def author_to_user_commits(author, link, size=16, cssclass=None):
|
|
Pierre-Yves Chibon |
bea195 |
""" Template filter transforming a pygit2 Author object into a text
|
|
Pierre-Yves Chibon |
bea195 |
either with just the username or linking to the user in pagure.
|
|
Pierre-Yves Chibon |
bea195 |
"""
|
|
Pierre-Yves Chibon |
bea195 |
output = author.name
|
|
Pierre-Yves Chibon |
bea195 |
if not author.email:
|
|
Pierre-Yves Chibon |
bea195 |
return output
|
|
Pierre-Yves Chibon |
930073 |
user = pagure.lib.query.search_user(flask.g.session, email=author.email)
|
|
Pierre-Yves Chibon |
bea195 |
if user:
|
|
Pierre-Yves Chibon |
bea195 |
output = "%s %s" % (
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for("ui_ns.view_user", username=user.username),
|
|
Pierre-Yves Chibon |
bea195 |
avatar(user.default_email, size),
|
|
Pierre-Yves Chibon |
bea195 |
link,
|
|
Pierre-Yves Chibon |
9c2953 |
('class="%s"' % cssclass) if cssclass else "",
|
|
Pierre-Yves Chibon |
bea195 |
author.name,
|
|
Pierre-Yves Chibon |
bea195 |
)
|
|
Pierre-Yves Chibon |
bea195 |
|
|
Pierre-Yves Chibon |
bea195 |
return output
|
|
Pierre-Yves Chibon |
bea195 |
|
|
Pierre-Yves Chibon |
833d1f |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("InsertDiv")
|
|
Pierre-Yves Chibon |
3578fd |
def insert_div(content):
|
|
Pierre-Yves Chibon |
3578fd |
""" Template filter inserting an opening and closing
|
|
Pierre-Yves Chibon |
3578fd |
after the first title and then at the end of the content.
|
|
Pierre-Yves Chibon |
3578fd |
"""
|
|
Pierre-Yves Chibon |
3578fd |
# This is quite a hack but simpler solution using .replace() didn't work
|
|
Pierre-Yves Chibon |
3578fd |
# for some reasons...
|
|
Pierre-Yves Chibon |
9c2953 |
content = content.split("\n")
|
|
Pierre-Yves Chibon |
3578fd |
output = []
|
|
Pierre-Yves Chibon |
3578fd |
for row in content:
|
|
Pierre-Yves Chibon |
3578fd |
if row.startswith('
|
|
Pierre-Yves Chibon |
3578fd |
continue
|
|
Pierre-Yves Chibon |
562e03 |
if '' in row:
|
|
Aurélien Bompard |
619e2a |
row = ("%s" % row).replace(
|
|
Pierre-Yves Chibon |
562e03 |
'',
|
|
Pierre-Yves Chibon |
562e03 |
''
|
|
Pierre-Yves Chibon |
9c2953 |
' ',
|
|
Pierre-Yves Chibon |
562e03 |
)
|
|
Pierre-Yves Chibon |
3578fd |
output.append(row)
|
|
Pierre-Yves Chibon |
3578fd |
output = "\n".join(output)
|
|
Pierre-Yves Chibon |
9c2953 |
output = output.replace("", "\n", 1)
|
|
Pierre-Yves Chibon |
9c2953 |
output = output.replace("h1", "h3")
|
|
Pierre-Yves Chibon |
3578fd |
|
|
Pierre-Yves Chibon |
3578fd |
return output
|
|
Pierre-Yves Chibon |
bc85d8 |
|
|
Pierre-Yves Chibon |
bc85d8 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("noJS")
|
|
Pierre-Yves Chibon |
2f90ea |
def no_js(content, ignore=None):
|
|
Pierre-Yves Chibon |
bc85d8 |
""" Template filter replacing <script <script="" <="" and="" by="" script=""> by</script>
|
|
Pierre-Yves Chibon |
bc85d8 |
</script>
|
|
Pierre-Yves Chibon |
bc85d8 |
"""
|
|
Pierre-Yves Chibon |
930073 |
return pagure.lib.query.clean_input(content, ignore=ignore)
|
|
Pierre-Yves Chibon |
0c1b4c |
|
|
Pierre-Yves Chibon |
0c1b4c |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("toRGB")
|
|
Pierre-Yves Chibon |
0c1b4c |
def int_to_rgb(percent):
|
|
Pierre-Yves Chibon |
0c1b4c |
""" Template filter converting a given percentage to a css RGB value.
|
|
Pierre-Yves Chibon |
0c1b4c |
"""
|
|
Pierre-Yves Chibon |
0c1b4c |
output = "rgb(255, 0, 0);"
|
|
Pierre-Yves Chibon |
0c1b4c |
try:
|
|
Pierre-Yves Chibon |
0c1b4c |
percent = int(percent)
|
|
Pierre-Yves Chibon |
0c1b4c |
if percent < 50:
|
|
Pierre-Yves Chibon |
0c1b4c |
red = 255
|
|
Pierre-Yves Chibon |
0c0047 |
green = (255.0 / 50) * percent
|
|
Pierre-Yves Chibon |
0c1b4c |
else:
|
|
Pierre-Yves Chibon |
0c1b4c |
green = 255
|
|
Pierre-Yves Chibon |
0c0047 |
red = (255.0 / 50) * (100 - percent)
|
|
Pierre-Yves Chibon |
0c1b4c |
output = "rgb(%s, %s, 0);" % (int(red), int(green))
|
|
Pierre-Yves Chibon |
0c1b4c |
except ValueError:
|
|
Pierre-Yves Chibon |
0c1b4c |
pass
|
|
Pierre-Yves Chibon |
0c1b4c |
return output
|
|
Ryan Lerch |
e914ef |
|
|
Pierre-Yves Chibon |
f6cf03 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("increment_largest_priority")
|
|
Pierre-Yves Chibon |
11d3da |
def largest_priority(dictionary):
|
|
Ryan Lerch |
bf08ec |
""" Template filter to return the largest priority +1
|
|
Ryan Lerch |
bf08ec |
"""
|
|
Pierre-Yves Chibon |
fb7a0a |
if dictionary:
|
|
Pierre-Yves Chibon |
7b3aee |
keys = [int(k) for k in dictionary if k]
|
|
Pierre-Yves Chibon |
7b3aee |
if keys:
|
|
Pierre-Yves Chibon |
7b3aee |
return max(keys) + 1
|
|
Pierre-Yves Chibon |
7b3aee |
return 1
|
|
Ryan Lerch |
9dad14 |
|
|
Pierre-Yves Chibon |
f5f5d6 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("unicode")
|
|
Ryan Lerch |
9dad14 |
def convert_unicode(text):
|
|
Pierre-Yves Chibon |
9c2953 |
""" If the provided string is a binary string, this filter converts it
|
|
Pierre-Yves Chibon |
11d3da |
to UTF-8 (unicode).
|
|
Pierre-Yves Chibon |
9c2953 |
"""
|
|
Aurélien Bompard |
831553 |
if isinstance(text, str) and six.PY2:
|
|
Pierre-Yves Chibon |
f5f5d6 |
return text.decode("utf8")
|
|
Pierre-Yves Chibon |
f5f5d6 |
else:
|
|
Pierre-Yves Chibon |
f5f5d6 |
return text
|
|
Pierre-Yves Chibon |
a5aa6b |
|
|
Pierre-Yves Chibon |
a5aa6b |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("combine_url")
|
|
Pierre-Yves Chibon |
a5aa6b |
def combine_url(url, page, pagetitle, **kwargs):
|
|
Pierre-Yves Chibon |
a5aa6b |
""" Add the specified arguments in the provided kwargs dictionary to
|
|
Pierre-Yves Chibon |
a5aa6b |
the given URL.
|
|
Pierre-Yves Chibon |
a5aa6b |
"""
|
|
Aurélien Bompard |
831553 |
url_obj = urlparse(url)
|
|
Pierre-Yves Chibon |
9c2953 |
url = url_obj.geturl().replace(url_obj.query, "").rstrip("?")
|
|
Pierre-Yves Chibon |
bc789a |
query = {}
|
|
Aurélien Bompard |
831553 |
for k, v in parse_qsl(url_obj.query):
|
|
Pierre-Yves Chibon |
bc789a |
if k in query:
|
|
Pierre-Yves Chibon |
bc789a |
if isinstance(query[k], list):
|
|
Pierre-Yves Chibon |
bc789a |
query[k].append(v)
|
|
Pierre-Yves Chibon |
bc789a |
else:
|
|
Pierre-Yves Chibon |
bc789a |
query[k] = [query[k], v]
|
|
Pierre-Yves Chibon |
bc789a |
else:
|
|
Pierre-Yves Chibon |
bc789a |
query[k] = v
|
|
Pierre-Yves Chibon |
a5aa6b |
query[pagetitle] = page
|
|
Pierre-Yves Chibon |
a5aa6b |
query.update(kwargs)
|
|
Pierre-Yves Chibon |
9c2953 |
args = ""
|
|
Pierre-Yves Chibon |
bc789a |
for key in query:
|
|
Pierre-Yves Chibon |
bc789a |
if isinstance(query[key], list):
|
|
Pierre-Yves Chibon |
bc789a |
for val in query[key]:
|
|
Pierre-Yves Chibon |
9c2953 |
args += "&%s=%s" % (key, val)
|
|
Pierre-Yves Chibon |
bc789a |
else:
|
|
Pierre-Yves Chibon |
9c2953 |
args += "&%s=%s" % (key, query[key])
|
|
Pierre-Yves Chibon |
9c2953 |
return url + "?" + args[1:]
|
|
Pierre-Yves Chibon |
366fac |
|
|
Pierre-Yves Chibon |
366fac |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("add_or_remove")
|
|
Pierre-Yves Chibon |
366fac |
def add_or_remove(item, items):
|
|
Pierre-Yves Chibon |
366fac |
""" Adds the item to the list if it is not in there and remove it
|
|
Pierre-Yves Chibon |
366fac |
otherwise.
|
|
Pierre-Yves Chibon |
366fac |
"""
|
|
Pierre-Yves Chibon |
366fac |
if item in items:
|
|
Pierre-Yves Chibon |
366fac |
items.remove(item)
|
|
Pierre-Yves Chibon |
366fac |
else:
|
|
Pierre-Yves Chibon |
366fac |
items.append(item)
|
|
Pierre-Yves Chibon |
366fac |
return items
|
|
mprahl |
a6fb93 |
|
|
mprahl |
a6fb93 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("table_sort_arrow")
|
|
mprahl |
a6fb93 |
def table_sort_arrow(column, order_key, order):
|
|
mprahl |
a6fb93 |
""" Outputs an arrow icon if the column is currently being sorted on
|
|
mprahl |
a6fb93 |
"""
|
|
Pierre-Yves Chibon |
9c2953 |
arrow_html = ''
|
|
mprahl |
a6fb93 |
if column == order_key:
|
|
Pierre-Yves Chibon |
9c2953 |
if order == "desc":
|
|
Pierre-Yves Chibon |
9c2953 |
return arrow_html.format("bottom")
|
|
mprahl |
a6fb93 |
else:
|
|
Pierre-Yves Chibon |
9c2953 |
return arrow_html.format("top")
|
|
Pierre-Yves Chibon |
9c2953 |
return ""
|
|
mprahl |
a6fb93 |
|
|
mprahl |
a6fb93 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("table_get_link_order")
|
|
mprahl |
a6fb93 |
def table_get_link_order(column, order_key, order):
|
|
mprahl |
a6fb93 |
""" Get the correct order parameter value for the table heading link
|
|
mprahl |
a6fb93 |
"""
|
|
mprahl |
a6fb93 |
if column == order_key:
|
|
mprahl |
a6fb93 |
# If the user is clicking on the column again, they want the
|
|
mprahl |
a6fb93 |
# oposite order
|
|
Pierre-Yves Chibon |
9c2953 |
if order == "desc":
|
|
Pierre-Yves Chibon |
9c2953 |
return "asc"
|
|
mprahl |
a6fb93 |
else:
|
|
Pierre-Yves Chibon |
9c2953 |
return "desc"
|
|
mprahl |
a6fb93 |
else:
|
|
mprahl |
a6fb93 |
# Default to descending
|
|
Pierre-Yves Chibon |
9c2953 |
return "desc"
|
|
Pierre-Yves Chibon |
b15d96 |
|
|
Pierre-Yves Chibon |
b15d96 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("flag2label")
|
|
Pierre-Yves Chibon |
b15d96 |
def flag_to_label(flag):
|
|
Pierre-Yves Chibon |
b15d96 |
""" For a given flag return the bootstrap label to use
|
|
Pierre-Yves Chibon |
b15d96 |
"""
|
|
Pierre-Yves Chibon |
9c2953 |
return pagure_config["FLAG_STATUSES_LABELS"][flag.status.lower()]
|
|
Lubomír Sedlář |
59889e |
|
|
Lubomír Sedlář |
59889e |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("join_prefix")
|
|
Lubomír Sedlář |
59889e |
def join_prefix(values, num):
|
|
Lubomír Sedlář |
59889e |
"""Produce a string joining first `num` items in the list and indicate
|
|
Lubomír Sedlář |
59889e |
total number total number of items.
|
|
Lubomír Sedlář |
59889e |
"""
|
|
Lubomír Sedlář |
59889e |
if len(values) <= 1:
|
|
Lubomír Sedlář |
59889e |
return "".join(values)
|
|
Lubomír Sedlář |
59889e |
if len(values) <= num:
|
|
Lubomír Sedlář |
59889e |
return ", ".join(values[:-1]) + " and " + values[-1]
|
|
Lubomír Sedlář |
59889e |
return "%s and %d others" % (", ".join(values[:num]), len(values) - num)
|
|
Pierre-Yves Chibon |
9aba91 |
|
|
Pierre-Yves Chibon |
9aba91 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("user_can_clone_ssh")
|
|
Pierre-Yves Chibon |
9aba91 |
def user_can_clone_ssh(username):
|
|
Patrick Uiterwijk |
9b237b |
has_ssh_keys = False
|
|
Pierre-Yves Chibon |
9aba91 |
if flask.g.authenticated:
|
|
Patrick Uiterwijk |
9b237b |
has_ssh_keys = (
|
|
Patrick Uiterwijk |
9b237b |
len(
|
|
Pierre-Yves Chibon |
930073 |
pagure.lib.query.search_user(
|
|
Patrick Uiterwijk |
9b237b |
flask.g.session, username=flask.g.fas_user.username
|
|
Patrick Uiterwijk |
9b237b |
).sshkeys
|
|
Patrick Uiterwijk |
9b237b |
)
|
|
Patrick Uiterwijk |
9b237b |
!= 0
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Patrick Uiterwijk |
9b237b |
always_render = pagure_config.get("ALWAYS_RENDER_SSH_CLONE_URL")
|
|
Patrick Uiterwijk |
9b237b |
return always_render or has_ssh_keys
|
|
Pierre-Yves Chibon |
9aba91 |
|
|
Pierre-Yves Chibon |
9aba91 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.app_template_filter("git_url_ssh")
|
|
Pierre-Yves Chibon |
9c2953 |
def get_git_url_ssh(complement=""):
|
|
Pierre-Yves Chibon |
9aba91 |
""" Return the GIT SSH URL to be displayed in the UI based on the
|
|
Pierre-Yves Chibon |
9aba91 |
content of the configuration file.
|
|
Pierre-Yves Chibon |
9aba91 |
"""
|
|
Pierre-Yves Chibon |
9c2953 |
git_url_ssh = pagure_config.get("GIT_URL_SSH")
|
|
Pierre-Yves Chibon |
9aba91 |
if flask.g.authenticated and git_url_ssh:
|
|
Pierre-Yves Chibon |
9aba91 |
try:
|
|
Pierre-Yves Chibon |
9aba91 |
git_url_ssh = git_url_ssh.format(
|
|
Pierre-Yves Chibon |
9c2953 |
username=flask.g.fas_user.username
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9aba91 |
except (KeyError, IndexError):
|
|
Pierre-Yves Chibon |
9aba91 |
pass
|
|
Pierre-Yves Chibon |
9aba91 |
return git_url_ssh + complement
|
|
Pierre-Yves Chibon |
f6a6e0 |
|
|
Pierre-Yves Chibon |
f6a6e0 |
|
|
Pierre-Yves Chibon |
f6a6e0 |
@UI_NS.app_template_filter("patch_stats")
|
|
Pierre-Yves Chibon |
f6a6e0 |
def get_patch_stats(patch):
|
|
Pierre-Yves Chibon |
f6a6e0 |
""" Return a dict of stats about the provided patch."""
|
|
Pierre-Yves Chibon |
f6a6e0 |
try:
|
|
Pierre-Yves Chibon |
f6a6e0 |
output = pagure.lib.git.get_stats_patch(patch)
|
|
Pierre-Yves Chibon |
f6a6e0 |
except pagure.exceptions.PagureException:
|
|
Pierre-Yves Chibon |
f6a6e0 |
_log.exception("Failed to get stats on a patch")
|
|
Pierre-Yves Chibon |
f6a6e0 |
output = {}
|
|
Pierre-Yves Chibon |
f6a6e0 |
return output
|