|
Pierre-Yves Chibon |
33b534 |
# -*- coding: utf-8 -*-
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
"""
|
|
Pierre-Yves Chibon |
a04944 |
(c) 2014-2018 - Copyright Red Hat Inc
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
Authors:
|
|
Pierre-Yves Chibon |
47950c |
Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
|
|
farhaanbukhsh |
141da6 |
Farhaan Bukhsh <farhaan.bukhsh@gmail.com></farhaan.bukhsh@gmail.com>
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
"""
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
22a554 |
# pylint: disable=too-many-lines
|
|
Pierre-Yves Chibon |
22a554 |
# pylint: disable=too-many-branches
|
|
Pierre-Yves Chibon |
22a554 |
# pylint: disable=too-many-locals
|
|
Pierre-Yves Chibon |
22a554 |
# pylint: disable=too-many-statements
|
|
Pierre-Yves Chibon |
22a554 |
# pylint: disable=bare-except
|
|
Pierre-Yves Chibon |
22a554 |
# pylint: disable=broad-except
|
|
Pierre-Yves Chibon |
53e4c2 |
|
|
Pierre-Yves Chibon |
53e4c2 |
|
|
Pierre-Yves Chibon |
67d1cc |
from __future__ import unicode_literals, absolute_import
|
|
Aurélien Bompard |
dcf6f6 |
|
|
Pierre-Yves Chibon |
e649cf |
import datetime
|
|
Pierre-Yves Chibon |
8c8487 |
import json
|
|
Pierre-Yves Chibon |
4635b5 |
import logging
|
|
Pierre-Yves Chibon |
47950c |
import os
|
|
Pierre-Yves Chibon |
7b3c51 |
import re
|
|
Pierre-Yves Chibon |
47950c |
from math import ceil
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
e649cf |
import flask
|
|
Pierre-Yves Chibon |
47950c |
import pygit2
|
|
Pierre-Yves Chibon |
5b7bfc |
import kitchen.text.converters as ktc
|
|
Aurélien Bompard |
831553 |
import six
|
|
Pierre-Yves Chibon |
cda607 |
import werkzeug
|
|
Pierre-Yves Chibon |
5b7bfc |
|
|
Aurélien Bompard |
831553 |
from six import BytesIO
|
|
Pierre-Yves Chibon |
a1aa0b |
from PIL import Image
|
|
Pierre-Yves Chibon |
5b7bfc |
from sqlalchemy.exc import SQLAlchemyError
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
801c6f |
from binaryornot.helpers import is_binary_string
|
|
Pierre-Yves Chibon |
801c6f |
|
|
Pierre-Yves Chibon |
fe5017 |
import pagure.exceptions
|
|
Pierre-Yves Chibon |
fe5017 |
import pagure.lib.git
|
|
Shengjing Zhu |
c28196 |
import pagure.lib.mimetype
|
|
Pierre-Yves Chibon |
295cfb |
import pagure.lib.plugins
|
|
Pierre-Yves Chibon |
930073 |
import pagure.lib.query
|
|
Pierre-Yves Chibon |
5b06f7 |
import pagure.lib.tasks
|
|
Pierre-Yves Chibon |
fe5017 |
import pagure.forms
|
|
Pierre-Yves Chibon |
fe5017 |
import pagure.ui.plugins
|
|
Pierre-Yves Chibon |
b130e5 |
from pagure.config import config as pagure_config
|
|
Pierre-Yves Chibon |
9efbd5 |
from pagure.flask_app import _get_user
|
|
farhaanbukhsh |
b24eb0 |
from pagure.lib import encoding_utils
|
|
Pierre-Yves Chibon |
b130e5 |
from pagure.ui import UI_NS
|
|
Pierre-Yves Chibon |
b130e5 |
from pagure.utils import (
|
|
Pierre-Yves Chibon |
b130e5 |
__get_file_in_tree,
|
|
Pierre-Yves Chibon |
b130e5 |
login_required,
|
|
Aurélien Bompard |
619e2a |
is_true,
|
|
Patrick Uiterwijk |
71124e |
stream_template,
|
|
Pierre-Yves Chibon |
b130e5 |
)
|
|
Clement Verna |
afe475 |
from pagure.decorators import (
|
|
Clement Verna |
afe475 |
is_repo_admin,
|
|
Clement Verna |
afe475 |
is_admin_sess_timedout,
|
|
Pierre-Yves Chibon |
9c2953 |
has_issue_tracker,
|
|
Pierre-Yves Chibon |
d86b5c |
has_issue_or_pr_enabled,
|
|
Clement Verna |
36168f |
has_pr_enabled,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b8c7ae |
|
|
Pierre-Yves Chibon |
4635b5 |
_log = logging.getLogger(__name__)
|
|
Pierre-Yves Chibon |
4635b5 |
|
|
Pierre-Yves Chibon |
4635b5 |
|
|
Karsten Hopp |
dd024f |
def get_preferred_readme(tree):
|
|
Karsten Hopp |
dd024f |
""" Establish some order about which README gets displayed
|
|
Karsten Hopp |
dd024f |
if there are several in the repository. If none of the listed
|
|
Karsten Hopp |
018f64 |
README files is availabe, display either the next file that
|
|
Karsten Hopp |
dd024f |
starts with 'README' or nothing at all.
|
|
Karsten Hopp |
dd024f |
"""
|
|
Pierre-Yves Chibon |
9c2953 |
order = ["README.md", "README.rst", "README", "README.txt"]
|
|
Karsten Hopp |
dd024f |
readmes = [x for x in tree if x.name.startswith("README")]
|
|
Karsten Hopp |
0f3f40 |
if len(readmes) > 1:
|
|
Karsten Hopp |
dd024f |
for i in order:
|
|
Karsten Hopp |
dd024f |
for j in readmes:
|
|
Karsten Hopp |
dd024f |
if i == j.name:
|
|
Karsten Hopp |
dd024f |
return j
|
|
Karsten Hopp |
0f3f40 |
elif len(readmes) == 1:
|
|
Karsten Hopp |
dd024f |
return readmes[0]
|
|
Karsten Hopp |
dd024f |
return None
|
|
Karsten Hopp |
dd024f |
|
|
Pierre-Yves Chibon |
4ea41a |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>.git")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>.git")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>.git")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>.git")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
4501da |
def view_repo_git(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
9c2953 |
""" Redirect to the project index page when user wants to view
|
|
Vivek Anand |
59997f |
the git repo of the project
|
|
Pierre-Yves Chibon |
9c2953 |
"""
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_repo",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
|
|
Pierre-Yves Chibon |
9c2953 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
4501da |
def view_repo(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
47950c |
""" Front page of a specific repo.
|
|
Pierre-Yves Chibon |
47950c |
"""
|
|
Pierre-Yves Chibon |
4501da |
repo_db = flask.g.repo
|
|
Pierre-Yves Chibon |
16572e |
repo_obj = flask.g.repo_obj
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
1e2612 |
if not repo_obj.is_empty and not repo_obj.head_is_unborn:
|
|
Pierre-Yves Chibon |
1e2612 |
head = repo_obj.head.shorthand
|
|
Pierre-Yves Chibon |
1e2612 |
else:
|
|
Pierre-Yves Chibon |
1e2612 |
head = None
|
|
Pierre-Yves Chibon |
1e2612 |
|
|
Pierre-Yves Chibon |
47950c |
cnt = 0
|
|
Pierre-Yves Chibon |
47950c |
last_commits = []
|
|
Pierre-Yves Chibon |
47950c |
tree = []
|
|
Pierre-Yves Chibon |
47950c |
if not repo_obj.is_empty:
|
|
Pierre-Yves Chibon |
e63173 |
try:
|
|
Pierre-Yves Chibon |
e63173 |
for commit in repo_obj.walk(
|
|
Slavek Kabrda |
0dd0cd |
repo_obj.head.target, pygit2.GIT_SORT_NONE
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Pierre-Yves Chibon |
e63173 |
last_commits.append(commit)
|
|
Pierre-Yves Chibon |
e63173 |
cnt += 1
|
|
Pierre-Yves Chibon |
e63173 |
if cnt == 3:
|
|
Pierre-Yves Chibon |
e63173 |
break
|
|
Pierre-Yves Chibon |
e63173 |
tree = sorted(last_commits[0].tree, key=lambda x: x.filemode)
|
|
Pierre-Yves Chibon |
e63173 |
except pygit2.GitError:
|
|
Pierre-Yves Chibon |
e63173 |
pass
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
readme = None
|
|
Pierre-Yves Chibon |
f77c9a |
safe = False
|
|
Ghost-script |
d50d9e |
|
|
Ghost-script |
d50d9e |
if not repo_obj.is_empty and not repo_obj.head_is_unborn:
|
|
Ghost-script |
d50d9e |
branchname = repo_obj.head.shorthand
|
|
Ghost-script |
d50d9e |
else:
|
|
Ghost-script |
d50d9e |
branchname = None
|
|
Pierre-Yves Chibon |
930073 |
project = pagure.lib.query.get_authorized_project(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session, repo, user=username, namespace=namespace
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Karsten Hopp |
028a86 |
watch_users = set()
|
|
Karsten Hopp |
028a86 |
watch_users.add(project.user.username)
|
|
Karsten Hopp |
277ab2 |
for access_type in project.access_users.keys():
|
|
Karsten Hopp |
277ab2 |
for user in project.access_users[access_type]:
|
|
Karsten Hopp |
028a86 |
watch_users.add(user.username)
|
|
Karsten Hopp |
277ab2 |
for watcher in project.watchers:
|
|
Karsten Hopp |
028a86 |
if watcher.watch_issues or watcher.watch_commits:
|
|
Karsten Hopp |
028a86 |
watch_users.add(watcher.user.username)
|
|
Karsten Hopp |
dd024f |
readmefile = get_preferred_readme(tree)
|
|
Karsten Hopp |
dd024f |
if readmefile:
|
|
Karsten Hopp |
dd024f |
name, ext = os.path.splitext(readmefile.name)
|
|
Karsten Hopp |
dd024f |
content = __get_file_in_tree(
|
|
Pierre-Yves Chibon |
9c2953 |
repo_obj, last_commits[0].tree, [readmefile.name]
|
|
Pierre-Yves Chibon |
9c2953 |
).data
|
|
Karsten Hopp |
dd024f |
readme, safe = pagure.doc_utils.convert_readme(
|
|
Pierre-Yves Chibon |
9c2953 |
content,
|
|
Pierre-Yves Chibon |
9c2953 |
ext,
|
|
Karsten Hopp |
dd024f |
view_file_url=flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_raw_file",
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo_db.name,
|
|
Pierre-Yves Chibon |
9c2953 |
identifier=branchname,
|
|
Pierre-Yves Chibon |
9c2953 |
filename="",
|
|
Pierre-Yves Chibon |
9c2953 |
),
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
47950c |
return flask.render_template(
|
|
Pierre-Yves Chibon |
9c2953 |
"repo_info.html",
|
|
Pierre-Yves Chibon |
9c2953 |
select="overview",
|
|
Pierre-Yves Chibon |
4501da |
repo=repo_db,
|
|
Pierre-Yves Chibon |
47950c |
username=username,
|
|
Pierre-Yves Chibon |
1e2612 |
head=head,
|
|
Pierre-Yves Chibon |
47950c |
readme=readme,
|
|
Pierre-Yves Chibon |
f77c9a |
safe=safe,
|
|
Pierre-Yves Chibon |
9c2953 |
origin="view_repo",
|
|
Ghost-script |
966a39 |
branchname=branchname,
|
|
Pierre-Yves Chibon |
47950c |
last_commits=last_commits,
|
|
Pierre-Yves Chibon |
47950c |
tree=tree,
|
|
Karsten Hopp |
277ab2 |
num_watchers=len(watch_users),
|
|
Pierre-Yves Chibon |
47950c |
)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
77bdcd |
|
|
Ryan Lerch |
6d2e06 |
"""
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route('/<repo>/branch/<path:branchname>')</path:branchname></repo>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route('/<namespace>/<repo>/branch/<path:branchname>')</path:branchname></repo></namespace>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route('/fork/<username>/<repo>/branch/<path:branchname>')</path:branchname></repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route('/fork/<username>/<namespace>/<repo>/branch/<path:branchname>')</path:branchname></repo></namespace></username>
|
|
Pierre-Yves Chibon |
4501da |
def view_repo_branch(repo, branchname, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
b8c7ae |
''' Returns the list of branches in the repo. '''
|
|
Pierre-Yves Chibon |
b8c7ae |
|
|
Pierre-Yves Chibon |
16572e |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
16572e |
repo_obj = flask.g.repo_obj
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
05748c |
if branchname not in repo_obj.listall_branches():
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description='Branch not found')
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
branch = repo_obj.lookup_branch(branchname)
|
|
Ghost-script |
fdcd15 |
if not repo_obj.is_empty and not repo_obj.head_is_unborn:
|
|
Ghost-script |
fdcd15 |
head = repo_obj.head.shorthand
|
|
Ghost-script |
fdcd15 |
else:
|
|
Ghost-script |
fdcd15 |
head = None
|
|
Pierre-Yves Chibon |
47950c |
cnt = 0
|
|
Pierre-Yves Chibon |
47950c |
last_commits = []
|
|
Pierre-Yves Chibon |
29ff0a |
for commit in repo_obj.walk(branch.peel().hex, pygit2.GIT_SORT_NONE):
|
|
Pierre-Yves Chibon |
47950c |
last_commits.append(commit)
|
|
Pierre-Yves Chibon |
47950c |
cnt += 1
|
|
Pierre-Yves Chibon |
ce2f5b |
if cnt == 3:
|
|
Pierre-Yves Chibon |
47950c |
break
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
diff_commits = []
|
|
Pierre-Yves Chibon |
4fcac8 |
|
|
farhaanbukhsh |
778e69 |
if repo.is_fork and repo.parent:
|
|
Patrick Uiterwijk |
3f97f6 |
parentname = repo.parent.repopath('main')
|
|
Pierre-Yves Chibon |
2c9e9f |
else:
|
|
Patrick Uiterwijk |
3f97f6 |
parentname = repo.repopath('main')
|
|
Pierre-Yves Chibon |
2c9e9f |
|
|
Pierre-Yves Chibon |
2c9e9f |
orig_repo = pygit2.Repository(parentname)
|
|
Pierre-Yves Chibon |
26dbc9 |
|
|
Pierre-Yves Chibon |
277040 |
tree = None
|
|
Pierre-Yves Chibon |
53e4c2 |
safe = False
|
|
Pierre-Yves Chibon |
277040 |
readme = None
|
|
Pierre-Yves Chibon |
2c9e9f |
if not repo_obj.is_empty and not orig_repo.is_empty:
|
|
Pierre-Yves Chibon |
47950c |
|
|
Ghost-script |
fdcd15 |
if not orig_repo.head_is_unborn:
|
|
Ghost-script |
fdcd15 |
compare_branch = orig_repo.lookup_branch(orig_repo.head.shorthand)
|
|
Ghost-script |
fdcd15 |
else:
|
|
Ghost-script |
fdcd15 |
compare_branch = None
|
|
Pierre-Yves Chibon |
5c7892 |
|
|
Pierre-Yves Chibon |
53e4c2 |
commit_list = []
|
|
Ghost-script |
fdcd15 |
|
|
Ghost-script |
fdcd15 |
if compare_branch:
|
|
Pierre-Yves Chibon |
53e4c2 |
commit_list = [
|
|
Pierre-Yves Chibon |
5c7892 |
commit.oid.hex
|
|
Pierre-Yves Chibon |
5c7892 |
for commit in orig_repo.walk(
|
|
Pierre-Yves Chibon |
29ff0a |
compare_branch.peel().hex,
|
|
Slavek Kabrda |
0dd0cd |
pygit2.GIT_SORT_NONE)
|
|
Pierre-Yves Chibon |
5c7892 |
]
|
|
Pierre-Yves Chibon |
acb942 |
|
|
Pierre-Yves Chibon |
29ff0a |
repo_commit = repo_obj[branch.peel().hex]
|
|
Pierre-Yves Chibon |
2c9e9f |
|
|
Pierre-Yves Chibon |
2c9e9f |
for commit in repo_obj.walk(
|
|
Slavek Kabrda |
0dd0cd |
repo_commit.oid.hex, pygit2.GIT_SORT_NONE):
|
|
Pierre-Yves Chibon |
53e4c2 |
if commit.oid.hex in commit_list:
|
|
Pierre-Yves Chibon |
2c9e9f |
break
|
|
Pierre-Yves Chibon |
2c9e9f |
diff_commits.append(commit.oid.hex)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
53e4c2 |
tree = sorted(last_commits[0].tree, key=lambda x: x.filemode)
|
|
Ryan Lerch |
0db4c7 |
for i in tree:
|
|
Ryan Lerch |
0db4c7 |
name, ext = os.path.splitext(i.name)
|
|
Ryan Lerch |
0db4c7 |
if name == 'README':
|
|
Ryan Lerch |
0db4c7 |
content = __get_file_in_tree(
|
|
Ryan Lerch |
0db4c7 |
repo_obj, last_commits[0].tree, [i.name]).data
|
|
Ryan Lerch |
0db4c7 |
|
|
Ryan Lerch |
0db4c7 |
readme, safe = pagure.doc_utils.convert_readme(
|
|
Ryan Lerch |
0db4c7 |
content, ext,
|
|
Ryan Lerch |
0db4c7 |
view_file_url=flask.url_for(
|
|
Pierre-Yves Chibon |
b130e5 |
'ui_ns.view_raw_file', username=username,
|
|
Pierre-Yves Chibon |
45aebf |
namespace=repo.namespace,
|
|
Ryan Lerch |
0db4c7 |
repo=repo.name, identifier=branchname, filename=''))
|
|
Ryan Lerch |
0db4c7 |
|
|
Pierre-Yves Chibon |
47950c |
return flask.render_template(
|
|
Pierre-Yves Chibon |
47950c |
'repo_info.html',
|
|
Pierre-Yves Chibon |
47950c |
select='overview',
|
|
Pierre-Yves Chibon |
47950c |
repo=repo,
|
|
Ghost-script |
fdcd15 |
head=head,
|
|
Pierre-Yves Chibon |
47950c |
username=username,
|
|
Pierre-Yves Chibon |
47950c |
branchname=branchname,
|
|
Ryan Lerch |
3d532e |
origin='view_repo_branch',
|
|
Pierre-Yves Chibon |
47950c |
last_commits=last_commits,
|
|
Ryan Lerch |
0db4c7 |
tree=tree,
|
|
Ryan Lerch |
0db4c7 |
safe=safe,
|
|
Ryan Lerch |
0db4c7 |
readme=readme,
|
|
Pierre-Yves Chibon |
47950c |
diff_commits=diff_commits,
|
|
Pierre-Yves Chibon |
47950c |
)
|
|
Ryan Lerch |
6d2e06 |
"""
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
77bdcd |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/commits/")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/commits")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/commits/<path:branchname>")</path:branchname></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/commits/")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/commits")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/commits/<path:branchname>")</path:branchname></repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/commits/")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/commits")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/commits/<path:branchname>")</path:branchname></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/commits/")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/commits")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/commits/<path:branchname>")</path:branchname></repo></namespace></username>
|
|
Pierre-Yves Chibon |
4501da |
def view_commits(repo, branchname=None, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
c5e646 |
""" Displays the commits of the specified repo.
|
|
Pierre-Yves Chibon |
47950c |
"""
|
|
Pierre-Yves Chibon |
16572e |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
16572e |
repo_obj = flask.g.repo_obj
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
d4bfa3 |
commit = None
|
|
Pierre-Yves Chibon |
d4bfa3 |
branch = None
|
|
Pierre-Yves Chibon |
d4bfa3 |
if branchname and branchname in repo_obj.listall_branches():
|
|
Pierre-Yves Chibon |
47950c |
branch = repo_obj.lookup_branch(branchname)
|
|
Pierre-Yves Chibon |
91cec1 |
commit = branch.peel(pygit2.Commit)
|
|
Pierre-Yves Chibon |
d4bfa3 |
elif branchname:
|
|
Pierre-Yves Chibon |
d4bfa3 |
try:
|
|
Pierre-Yves Chibon |
d4bfa3 |
commit = repo_obj.get(branchname)
|
|
Pierre-Yves Chibon |
d4bfa3 |
except (ValueError, TypeError):
|
|
Pierre-Yves Chibon |
d4bfa3 |
pass
|
|
Pierre-Yves Chibon |
d4bfa3 |
|
|
Pierre-Yves Chibon |
9c2953 |
if "refs/tags/%s" % branchname in list(repo_obj.references):
|
|
Pierre-Yves Chibon |
9c2953 |
ref = repo_obj.lookup_reference("refs/tags/%s" % branchname)
|
|
Pierre-Yves Chibon |
91cec1 |
commit = ref.peel(pygit2.Commit)
|
|
Pierre-Yves Chibon |
6868c1 |
|
|
Pierre-Yves Chibon |
d4bfa3 |
# If we're arriving here from the release page, we may have a Tag
|
|
Pierre-Yves Chibon |
d4bfa3 |
# where we expected a commit, in this case, get the actual commit
|
|
Pierre-Yves Chibon |
d4bfa3 |
if isinstance(commit, pygit2.Tag):
|
|
Pierre-Yves Chibon |
91cec1 |
commit = commit.peel(pygit2.Commit)
|
|
Pierre-Yves Chibon |
d4bfa3 |
branchname = commit.oid.hex
|
|
Ghost-script |
fdcd15 |
elif not repo_obj.is_empty and not repo_obj.head_is_unborn:
|
|
Ghost-script |
fdcd15 |
branch = repo_obj.lookup_branch(repo_obj.head.shorthand)
|
|
Pierre-Yves Chibon |
91cec1 |
commit = branch.peel(pygit2.Commit)
|
|
Pierre-Yves Chibon |
db30ef |
branchname = branch.branch_name
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
34f46f |
if not repo_obj.is_empty and not repo_obj.head_is_unborn:
|
|
Pierre-Yves Chibon |
34f46f |
head = repo_obj.head.shorthand
|
|
Pierre-Yves Chibon |
34f46f |
else:
|
|
Pierre-Yves Chibon |
34f46f |
head = None
|
|
Pierre-Yves Chibon |
34f46f |
|
|
Pierre-Yves Chibon |
47950c |
try:
|
|
Pierre-Yves Chibon |
9c2953 |
page = int(flask.request.args.get("page", 1))
|
|
Abhijeet Kasurde |
f4bf50 |
except (ValueError, TypeError):
|
|
Pierre-Yves Chibon |
47950c |
page = 1
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
9c2953 |
author = flask.request.args.get("author", None)
|
|
Pierre-Yves Chibon |
2df018 |
author_obj = None
|
|
Pierre-Yves Chibon |
2df018 |
if author:
|
|
Pierre-Yves Chibon |
2df018 |
try:
|
|
Pierre-Yves Chibon |
930073 |
author_obj = pagure.lib.query.get_user(flask.g.session, author)
|
|
Abhijeet Kasurde |
f4bf50 |
except pagure.exceptions.PagureException:
|
|
Pierre-Yves Chibon |
2df018 |
pass
|
|
Pierre-Yves Chibon |
2df018 |
if not author_obj:
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("No user found for the author: %s" % author, "error")
|
|
Pierre-Yves Chibon |
2df018 |
|
|
Pierre-Yves Chibon |
9c2953 |
limit = pagure_config["ITEM_PER_PAGE"]
|
|
Pierre-Yves Chibon |
47950c |
start = limit * (page - 1)
|
|
Pierre-Yves Chibon |
47950c |
end = limit * page
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
n_commits = 0
|
|
Pierre-Yves Chibon |
47950c |
last_commits = []
|
|
Pierre-Yves Chibon |
d4bfa3 |
if commit:
|
|
Slavek Kabrda |
0dd0cd |
for commit in repo_obj.walk(commit.hex, pygit2.GIT_SORT_NONE):
|
|
Pierre-Yves Chibon |
2df018 |
|
|
chocos10 |
6e4a4f |
# Filters the commits for a user
|
|
Pierre-Yves Chibon |
2df018 |
if author_obj:
|
|
Pierre-Yves Chibon |
2df018 |
tmp = False
|
|
Pierre-Yves Chibon |
2df018 |
for email in author_obj.emails:
|
|
Pierre-Yves Chibon |
2df018 |
if email.email == commit.author.email:
|
|
Pierre-Yves Chibon |
2df018 |
tmp = True
|
|
Pierre-Yves Chibon |
2df018 |
break
|
|
Pierre-Yves Chibon |
2df018 |
if not tmp:
|
|
Pierre-Yves Chibon |
2df018 |
continue
|
|
Pierre-Yves Chibon |
2df018 |
|
|
Pierre-Yves Chibon |
c184e7 |
if n_commits >= start and n_commits <= end:
|
|
Pierre-Yves Chibon |
c184e7 |
last_commits.append(commit)
|
|
Pierre-Yves Chibon |
c184e7 |
n_commits += 1
|
|
Pierre-Yves Chibon |
47950c |
|
|
vibhcool |
eb6723 |
total_page = int(ceil(n_commits / float(limit)) if n_commits > 0 else 1)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
diff_commits = []
|
|
Ryan Lerch |
3fb285 |
diff_commits_full = []
|
|
Farhaan Bukhsh |
72ffb0 |
if repo.is_fork and repo.parent:
|
|
Patrick Uiterwijk |
3f97f6 |
parentname = repo.parent.repopath("main")
|
|
Pierre-Yves Chibon |
2c9e9f |
else:
|
|
Patrick Uiterwijk |
3f97f6 |
parentname = repo.repopath("main")
|
|
Pierre-Yves Chibon |
26dbc9 |
|
|
Pierre-Yves Chibon |
2c9e9f |
orig_repo = pygit2.Repository(parentname)
|
|
Pierre-Yves Chibon |
acb942 |
|
|
Pierre-Yves Chibon |
9c2953 |
if (
|
|
Pierre-Yves Chibon |
9c2953 |
not repo_obj.is_empty
|
|
Pierre-Yves Chibon |
9c2953 |
and not orig_repo.is_empty
|
|
Pierre-Yves Chibon |
9c2953 |
and len(repo_obj.listall_branches()) > 1
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Pierre-Yves Chibon |
2c9e9f |
|
|
Ghost-script |
fdcd15 |
if not orig_repo.head_is_unborn:
|
|
Pierre-Yves Chibon |
9c2953 |
compare_branch = orig_repo.lookup_branch(orig_repo.head.shorthand)
|
|
Ghost-script |
fdcd15 |
else:
|
|
Ghost-script |
fdcd15 |
compare_branch = None
|
|
Pierre-Yves Chibon |
0b2adf |
|
|
clime |
703035 |
if compare_branch and branch:
|
|
Pierre-Yves Chibon |
9c2953 |
(
|
|
Pierre-Yves Chibon |
9c2953 |
diff,
|
|
Pierre-Yves Chibon |
9c2953 |
diff_commits_full,
|
|
Pierre-Yves Chibon |
9c2953 |
orig_commit,
|
|
Pierre-Yves Chibon |
9c2953 |
) = pagure.lib.git.get_diff_info(
|
|
Pierre-Yves Chibon |
9c2953 |
repo_obj,
|
|
Pierre-Yves Chibon |
9c2953 |
orig_repo,
|
|
Pierre-Yves Chibon |
9c2953 |
branch.branch_name,
|
|
Pierre-Yves Chibon |
9c2953 |
compare_branch.branch_name,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
clime |
703035 |
|
|
clime |
703035 |
for commit in diff_commits_full:
|
|
Pierre-Yves Chibon |
1f8aee |
diff_commits.append(commit.oid.hex)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
return flask.render_template(
|
|
Pierre-Yves Chibon |
9c2953 |
"commits.html",
|
|
Pierre-Yves Chibon |
9c2953 |
select="commits",
|
|
Pierre-Yves Chibon |
9c2953 |
origin="view_commits",
|
|
Pierre-Yves Chibon |
47950c |
repo=repo,
|
|
Pierre-Yves Chibon |
47950c |
username=username,
|
|
Pierre-Yves Chibon |
34f46f |
head=head,
|
|
Pierre-Yves Chibon |
47950c |
branchname=branchname,
|
|
Pierre-Yves Chibon |
47950c |
last_commits=last_commits,
|
|
Pierre-Yves Chibon |
47950c |
diff_commits=diff_commits,
|
|
Ryan Lerch |
3fb285 |
diff_commits_full=diff_commits_full,
|
|
Ryan Lerch |
3fb285 |
number_of_commits=n_commits,
|
|
Pierre-Yves Chibon |
47950c |
page=page,
|
|
Pierre-Yves Chibon |
47950c |
total_page=total_page,
|
|
Pierre-Yves Chibon |
9c2953 |
flag_statuses_labels=json.dumps(pagure_config["FLAG_STATUSES_LABELS"]),
|
|
Pierre-Yves Chibon |
47950c |
)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/c/<commit1>..<commit2>/")</commit2></commit1></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/c/<commit1>..<commit2>")</commit2></commit1></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/c/<commit1>..<commit2>/")</commit2></commit1></repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/c/<commit1>..<commit2>")</commit2></commit1></repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/c/<commit1>..<commit2>/")</commit2></commit1></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/c/<commit1>..<commit2>")</commit2></commit1></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/c/<commit1>..<commit2>/")</commit2></commit1></repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/c/<commit1>..<commit2>")</commit2></commit1></repo></namespace></username>
|
|
Pierre-Yves Chibon |
4501da |
def compare_commits(repo, commit1, commit2, username=None, namespace=None):
|
|
Oliver Gutierrez |
38f510 |
""" Compares two commits for specified repo
|
|
Oliver Gutierrez |
38f510 |
"""
|
|
Pierre-Yves Chibon |
16572e |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
16572e |
repo_obj = flask.g.repo_obj
|
|
Oliver Gutierrez |
38f510 |
|
|
Oliver Gutierrez |
38f510 |
if not repo_obj.is_empty and not repo_obj.head_is_unborn:
|
|
Oliver Gutierrez |
38f510 |
head = repo_obj.head.shorthand
|
|
Oliver Gutierrez |
38f510 |
else:
|
|
Oliver Gutierrez |
38f510 |
head = None
|
|
Oliver Gutierrez |
38f510 |
|
|
Oliver Gutierrez |
38f510 |
# Check commit1 and commit2 existence
|
|
Oliver Gutierrez |
38f510 |
commit1_obj = repo_obj.get(commit1)
|
|
Oliver Gutierrez |
38f510 |
commit2_obj = repo_obj.get(commit2)
|
|
Oliver Gutierrez |
38f510 |
if commit1_obj is None:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="First commit does not exist")
|
|
Oliver Gutierrez |
38f510 |
if commit2_obj is None:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Last commit does not exist")
|
|
Oliver Gutierrez |
38f510 |
|
|
Oliver Gutierrez |
9e99d9 |
# Get commits diff data
|
|
Oliver Gutierrez |
38f510 |
diff = repo_obj.diff(commit1, commit2)
|
|
Oliver Gutierrez |
38f510 |
|
|
Oliver Gutierrez |
9e99d9 |
# Get commits list
|
|
Oliver Gutierrez |
9e99d9 |
diff_commits = []
|
|
Slavek Kabrda |
0dd0cd |
order = pygit2.GIT_SORT_NONE
|
|
Oliver Gutierrez |
9e99d9 |
first_commit = commit1
|
|
Oliver Gutierrez |
9e99d9 |
last_commit = commit2
|
|
Oliver Gutierrez |
9e99d9 |
|
|
Pierre-Yves Chibon |
53e4c2 |
commits = [
|
|
Pierre-Yves Chibon |
9c2953 |
commit.oid.hex[: len(first_commit)]
|
|
Slavek Kabrda |
0dd0cd |
for commit in repo_obj.walk(last_commit, pygit2.GIT_SORT_NONE)
|
|
Pierre-Yves Chibon |
53e4c2 |
]
|
|
Oliver Gutierrez |
9e99d9 |
|
|
Oliver Gutierrez |
9e99d9 |
if first_commit not in commits:
|
|
Oliver Gutierrez |
9e99d9 |
first_commit = commit2
|
|
Oliver Gutierrez |
9e99d9 |
last_commit = commit1
|
|
Oliver Gutierrez |
9e99d9 |
|
|
Oliver Gutierrez |
9e99d9 |
for commit in repo_obj.walk(last_commit, order):
|
|
Oliver Gutierrez |
9e99d9 |
diff_commits.append(commit)
|
|
Oliver Gutierrez |
9e99d9 |
|
|
Pierre-Yves Chibon |
9c2953 |
if commit.oid.hex == first_commit or commit.oid.hex.startswith(
|
|
Pierre-Yves Chibon |
9c2953 |
first_commit
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Oliver Gutierrez |
9e99d9 |
break
|
|
Oliver Gutierrez |
9e99d9 |
|
|
Oliver Gutierrez |
9e99d9 |
if first_commit == commit2:
|
|
Oliver Gutierrez |
9e99d9 |
diff_commits.reverse()
|
|
Oliver Gutierrez |
9e99d9 |
|
|
Oliver Gutierrez |
38f510 |
return flask.render_template(
|
|
Pierre-Yves Chibon |
9c2953 |
"repo_comparecommits.html",
|
|
Pierre-Yves Chibon |
9c2953 |
select="commits",
|
|
Pierre-Yves Chibon |
9c2953 |
origin="compare_commits",
|
|
Oliver Gutierrez |
38f510 |
repo=repo,
|
|
Oliver Gutierrez |
38f510 |
username=username,
|
|
Oliver Gutierrez |
38f510 |
head=head,
|
|
Oliver Gutierrez |
38f510 |
commit1=commit1,
|
|
Oliver Gutierrez |
38f510 |
commit2=commit2,
|
|
Oliver Gutierrez |
38f510 |
diff=diff,
|
|
Oliver Gutierrez |
38f510 |
diff_commits=diff_commits,
|
|
Oliver Gutierrez |
38f510 |
)
|
|
Oliver Gutierrez |
38f510 |
|
|
Oliver Gutierrez |
38f510 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/blob/<path:identifier>/f/<path:filename>")</path:filename></path:identifier></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/blob/<path:identifier>/f/<path:filename>")</path:filename></path:identifier></repo></namespace>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<repo>/blob/<path:identifier>/f/<path:filename>"</path:filename></path:identifier></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/blob/<path:identifier>/f/"</path:identifier></repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
"<path:filename>"</path:filename>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
4501da |
def view_file(repo, identifier, filename, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
47950c |
""" Displays the content of a file or a tree for the specified repo.
|
|
Pierre-Yves Chibon |
47950c |
"""
|
|
Pierre-Yves Chibon |
16572e |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
16572e |
repo_obj = flask.g.repo_obj
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
bc6cc4 |
if repo_obj.is_empty:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Empty repo cannot have a file")
|
|
Pierre-Yves Chibon |
bc6cc4 |
|
|
Pierre-Yves Chibon |
47950c |
if identifier in repo_obj.listall_branches():
|
|
Pierre-Yves Chibon |
47950c |
branchname = identifier
|
|
Pierre-Yves Chibon |
47950c |
branch = repo_obj.lookup_branch(identifier)
|
|
Pierre-Yves Chibon |
91cec1 |
commit = branch.peel(pygit2.Commit)
|
|
Pierre-Yves Chibon |
47950c |
else:
|
|
Pierre-Yves Chibon |
47950c |
try:
|
|
Pierre-Yves Chibon |
47950c |
commit = repo_obj.get(identifier)
|
|
Pierre-Yves Chibon |
47950c |
branchname = identifier
|
|
Pierre-Yves Chibon |
47950c |
except ValueError:
|
|
Pierre-Yves Chibon |
9c2953 |
if "master" not in repo_obj.listall_branches():
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Branch not found")
|
|
Pierre-Yves Chibon |
47950c |
# If it's not a commit id then it's part of the filename
|
|
Pierre-Yves Chibon |
47950c |
commit = repo_obj[repo_obj.head.target]
|
|
Pierre-Yves Chibon |
9c2953 |
branchname = "master"
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
5bb964 |
if isinstance(commit, pygit2.Tag):
|
|
Pierre-Yves Chibon |
91cec1 |
commit = commit.peel(pygit2.Commit)
|
|
Pierre-Yves Chibon |
5bb964 |
|
|
Pierre-Yves Chibon |
fec0c5 |
tree = None
|
|
Pierre-Yves Chibon |
fec0c5 |
if isinstance(commit, pygit2.Tree):
|
|
Pierre-Yves Chibon |
fec0c5 |
tree = commit
|
|
Pierre-Yves Chibon |
fec0c5 |
elif isinstance(commit, pygit2.Commit):
|
|
Pierre-Yves Chibon |
fec0c5 |
tree = commit.tree
|
|
Pierre-Yves Chibon |
fec0c5 |
|
|
Pierre-Yves Chibon |
fec0c5 |
if tree and commit and not isinstance(commit, pygit2.Blob):
|
|
Pierre-Yves Chibon |
f74707 |
content = __get_file_in_tree(
|
|
Pierre-Yves Chibon |
9c2953 |
repo_obj, tree, filename.split("/"), bail_on_tree=True
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
f74707 |
if not content:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="File not found")
|
|
Pierre-Yves Chibon |
f74707 |
content = repo_obj[content.oid]
|
|
Pierre-Yves Chibon |
f74707 |
else:
|
|
Pierre-Yves Chibon |
f74707 |
content = commit
|
|
Pierre-Yves Chibon |
f74707 |
|
|
Pierre-Yves Chibon |
7c128e |
if not content:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="File not found")
|
|
Pierre-Yves Chibon |
7c128e |
|
|
Ryan Lerch |
4c1bc5 |
readme = None
|
|
Ryan Lerch |
4c1bc5 |
safe = False
|
|
Ryan Lerch |
4c1bc5 |
readme_ext = None
|
|
Pierre-Yves Chibon |
a443ef |
headers = {}
|
|
Patrick Uiterwijk |
71124e |
huge = False
|
|
Patrick Uiterwijk |
71124e |
|
|
Patrick Uiterwijk |
71124e |
isbinary = False
|
|
Pierre-Yves Chibon |
9c2953 |
if "data" in dir(content):
|
|
Patrick Uiterwijk |
71124e |
isbinary = is_binary_string(content.data)
|
|
Ryan Lerch |
4c1bc5 |
|
|
Pierre-Yves Chibon |
47950c |
if isinstance(content, pygit2.Blob):
|
|
Pierre-Yves Chibon |
9c2953 |
rawtext = is_true(flask.request.args.get("text"))
|
|
Pierre-Yves Chibon |
9c2953 |
ext = filename[filename.rfind(".") :]
|
|
Pierre-Yves Chibon |
c9a40f |
if ext in (
|
|
Pierre-Yves Chibon |
9c2953 |
".gif",
|
|
Pierre-Yves Chibon |
9c2953 |
".png",
|
|
Pierre-Yves Chibon |
9c2953 |
".bmp",
|
|
Pierre-Yves Chibon |
9c2953 |
".tif",
|
|
Pierre-Yves Chibon |
9c2953 |
".tiff",
|
|
Pierre-Yves Chibon |
9c2953 |
".jpg",
|
|
Pierre-Yves Chibon |
9c2953 |
".jpeg",
|
|
Pierre-Yves Chibon |
9c2953 |
".ppm",
|
|
Pierre-Yves Chibon |
9c2953 |
".pnm",
|
|
Pierre-Yves Chibon |
9c2953 |
".pbm",
|
|
Pierre-Yves Chibon |
9c2953 |
".pgm",
|
|
Pierre-Yves Chibon |
9c2953 |
".webp",
|
|
Pierre-Yves Chibon |
9c2953 |
".ico",
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Pierre-Yves Chibon |
c9a40f |
try:
|
|
Aurélien Bompard |
831553 |
Image.open(BytesIO(content.data))
|
|
Pierre-Yves Chibon |
9c2953 |
output_type = "image"
|
|
Pierre-Yves Chibon |
c9a40f |
except IOError as err:
|
|
Pierre-Yves Chibon |
9c2953 |
_log.debug("Failed to load image %s, error: %s", filename, err)
|
|
Pierre-Yves Chibon |
9c2953 |
output_type = "binary"
|
|
Pierre-Yves Chibon |
9c2953 |
elif ext in (".rst", ".mk", ".md", ".markdown") and not rawtext:
|
|
Yves Martin |
358b76 |
content, safe = pagure.doc_utils.convert_readme(content.data, ext)
|
|
Pierre-Yves Chibon |
9c2953 |
output_type = "markup"
|
|
Pierre-Yves Chibon |
9c2953 |
elif "data" in dir(content) and not isbinary:
|
|
Pierre-Yves Chibon |
e81494 |
file_content = None
|
|
Pierre-Yves Chibon |
65d40a |
try:
|
|
Pierre-Yves Chibon |
0c0047 |
file_content = encoding_utils.decode(
|
|
Pierre-Yves Chibon |
9c2953 |
ktc.to_bytes(content.data)
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
65d40a |
except pagure.exceptions.PagureException:
|
|
Pierre-Yves Chibon |
65d40a |
# We cannot decode the file, so let's pretend it's a binary
|
|
Pierre-Yves Chibon |
65d40a |
# file and let the user download it instead of displaying
|
|
Pierre-Yves Chibon |
65d40a |
# it.
|
|
Pierre-Yves Chibon |
9c2953 |
output_type = "binary"
|
|
Pierre-Yves Chibon |
100456 |
if file_content is not None:
|
|
Pierre-Yves Chibon |
9c2953 |
output_type = "file"
|
|
Pierre-Yves Chibon |
9c2953 |
content = content.data.decode("utf-8")
|
|
Farhaan Bukhsh |
9687ce |
else:
|
|
Pierre-Yves Chibon |
9c2953 |
output_type = "binary"
|
|
Patrick Uiterwijk |
71124e |
elif not isbinary:
|
|
Pierre-Yves Chibon |
9c2953 |
output_type = "file"
|
|
Patrick Uiterwijk |
71124e |
huge = True
|
|
Patrick Uiterwijk |
71124e |
safe = False
|
|
Pierre-Yves Chibon |
9c2953 |
content = content.data.decode("utf-8")
|
|
Pierre-Yves Chibon |
c9a40f |
else:
|
|
Pierre-Yves Chibon |
9c2953 |
output_type = "binary"
|
|
Pierre-Yves Chibon |
c10f7e |
elif isinstance(content, pygit2.Commit):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="File not found")
|
|
Pierre-Yves Chibon |
47950c |
else:
|
|
Pierre-Yves Chibon |
47950c |
content = sorted(content, key=lambda x: x.filemode)
|
|
Ryan Lerch |
4c1bc5 |
for i in content:
|
|
Ryan Lerch |
4c1bc5 |
name, ext = os.path.splitext(i.name)
|
|
Aurélien Bompard |
619e2a |
if not isinstance(name, six.text_type):
|
|
Aurélien Bompard |
619e2a |
name = name.decode("utf-8")
|
|
Pierre-Yves Chibon |
9c2953 |
if name == "README":
|
|
Ryan Lerch |
4c1bc5 |
readme_file = __get_file_in_tree(
|
|
Pierre-Yves Chibon |
9c2953 |
repo_obj, content, [i.name]
|
|
Pierre-Yves Chibon |
9c2953 |
).data
|
|
Ryan Lerch |
4c1bc5 |
|
|
Ryan Lerch |
4c1bc5 |
readme, safe = pagure.doc_utils.convert_readme(
|
|
Pierre-Yves Chibon |
9c2953 |
readme_file, ext
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Ryan Lerch |
4c1bc5 |
|
|
Ryan Lerch |
4c1bc5 |
readme_ext = ext
|
|
Pierre-Yves Chibon |
9c2953 |
output_type = "tree"
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
9c2953 |
if output_type == "binary":
|
|
Pierre-Yves Chibon |
9c2953 |
headers[str("Content-Disposition")] = "attachment"
|
|
Pierre-Yves Chibon |
bbcc6a |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.Response(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.stream_with_context(
|
|
Pierre-Yves Chibon |
9c2953 |
stream_template(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.current_app,
|
|
Pierre-Yves Chibon |
9c2953 |
"file.html",
|
|
Pierre-Yves Chibon |
9c2953 |
select="tree",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo,
|
|
Pierre-Yves Chibon |
9c2953 |
origin="view_file",
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
branchname=branchname,
|
|
Pierre-Yves Chibon |
9c2953 |
filename=filename,
|
|
Pierre-Yves Chibon |
9c2953 |
content=content,
|
|
Pierre-Yves Chibon |
9c2953 |
output_type=output_type,
|
|
Pierre-Yves Chibon |
9c2953 |
readme=readme,
|
|
Pierre-Yves Chibon |
9c2953 |
readme_ext=readme_ext,
|
|
Pierre-Yves Chibon |
9c2953 |
safe=safe,
|
|
Pierre-Yves Chibon |
9c2953 |
huge=huge,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
),
|
|
Pierre-Yves Chibon |
bbcc6a |
200,
|
|
Pierre-Yves Chibon |
9c2953 |
headers,
|
|
Pierre-Yves Chibon |
47950c |
)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/raw/<path:identifier>")</path:identifier></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/raw/<path:identifier>")</path:identifier></repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/raw/<path:identifier>/f/<path:filename>")</path:filename></path:identifier></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/raw/<path:identifier>/f/<path:filename>")</path:filename></path:identifier></repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/raw/<path:identifier>")</path:identifier></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/raw/<path:identifier>")</path:identifier></repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/raw/<path:identifier>/f/<path:filename>")</path:filename></path:identifier></repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/raw/<path:identifier>/f/"</path:identifier></repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
"<path:filename>"</path:filename>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
4501da |
def view_raw_file(
|
|
Pierre-Yves Chibon |
9c2953 |
repo, identifier, filename=None, username=None, namespace=None
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Johan Cwiklinski |
002118 |
""" Displays the raw content of a file of a commit for the specified repo.
|
|
Johan Cwiklinski |
740adc |
"""
|
|
Pierre-Yves Chibon |
16572e |
repo_obj = flask.g.repo_obj
|
|
Johan Cwiklinski |
740adc |
|
|
Pierre-Yves Chibon |
346039 |
if repo_obj.is_empty:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Empty repo cannot have a file")
|
|
Pierre-Yves Chibon |
346039 |
|
|
Johan Cwiklinski |
740adc |
if identifier in repo_obj.listall_branches():
|
|
Johan Cwiklinski |
740adc |
branch = repo_obj.lookup_branch(identifier)
|
|
Pierre-Yves Chibon |
91cec1 |
commit = branch.peel(pygit2.Commit)
|
|
Johan Cwiklinski |
740adc |
else:
|
|
Johan Cwiklinski |
740adc |
try:
|
|
Johan Cwiklinski |
740adc |
commit = repo_obj.get(identifier)
|
|
Johan Cwiklinski |
740adc |
except ValueError:
|
|
Pierre-Yves Chibon |
9c2953 |
if "master" not in repo_obj.listall_branches():
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Branch not found")
|
|
Johan Cwiklinski |
740adc |
# If it's not a commit id then it's part of the filename
|
|
Johan Cwiklinski |
740adc |
commit = repo_obj[repo_obj.head.target]
|
|
Johan Cwiklinski |
740adc |
|
|
Pierre-Yves Chibon |
8da4af |
if not commit:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Commit %s not found" % (identifier))
|
|
Pierre-Yves Chibon |
8da4af |
|
|
Pierre-Yves Chibon |
5bb964 |
if isinstance(commit, pygit2.Tag):
|
|
Pierre-Yves Chibon |
91cec1 |
commit = commit.peel(pygit2.Commit)
|
|
Pierre-Yves Chibon |
5bb964 |
|
|
Johan Cwiklinski |
002118 |
if filename:
|
|
Pierre-Yves Chibon |
5500b2 |
if isinstance(commit, pygit2.Blob):
|
|
Pierre-Yves Chibon |
5500b2 |
content = commit
|
|
Pierre-Yves Chibon |
5500b2 |
else:
|
|
Pierre-Yves Chibon |
5500b2 |
content = __get_file_in_tree(
|
|
Pierre-Yves Chibon |
9c2953 |
repo_obj, commit.tree, filename.split("/"), bail_on_tree=True
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
274dbb |
if not content or isinstance(content, pygit2.Tree):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="File not found")
|
|
Johan Cwiklinski |
002118 |
|
|
Johan Cwiklinski |
002118 |
data = repo_obj[content.oid].data
|
|
Johan Cwiklinski |
002118 |
else:
|
|
Johan Cwiklinski |
002118 |
if commit.parents:
|
|
Carlos Mogas da Silva |
dbd6dd |
# We need to take this not so nice road to ensure that the
|
|
Carlos Mogas da Silva |
dbd6dd |
# identifier retrieved from the URL is actually valid
|
|
Pierre-Yves Chibon |
4ea07d |
try:
|
|
Pierre-Yves Chibon |
9c2953 |
parent = repo_obj.revparse_single("%s^" % identifier)
|
|
Pierre-Yves Chibon |
4ea07d |
diff = repo_obj.diff(parent, commit)
|
|
Pierre-Yves Chibon |
4ea07d |
except (KeyError, ValueError):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Identifier not found")
|
|
Johan Cwiklinski |
002118 |
else:
|
|
Johan Cwiklinski |
002118 |
# First commit in the repo
|
|
Johan Cwiklinski |
002118 |
diff = commit.tree.diff_to_tree(swap=True)
|
|
Johan Cwiklinski |
002118 |
data = diff.patch
|
|
Johan Cwiklinski |
740adc |
|
|
Pierre-Yves Chibon |
42708f |
if not data:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="No content found")
|
|
Pierre-Yves Chibon |
42708f |
|
|
Shengjing Zhu |
c28196 |
return (data, 200, pagure.lib.mimetype.get_type_headers(filename, data))
|
|
Johan Cwiklinski |
740adc |
|
|
Johan Cwiklinski |
740adc |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/blame/<path:filename>")</path:filename></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/blame/<path:filename>")</path:filename></repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/blame/<path:filename>")</path:filename></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/blame/<path:filename>")</path:filename></repo></namespace></username>
|
|
Pierre-Yves Chibon |
833d1f |
def view_blame_file(repo, filename, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
833d1f |
""" Displays the blame of a file or a tree for the specified repo.
|
|
Pierre-Yves Chibon |
833d1f |
"""
|
|
Pierre-Yves Chibon |
833d1f |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
833d1f |
repo_obj = flask.g.repo_obj
|
|
Pierre-Yves Chibon |
833d1f |
|
|
Julen Landa Alustiza |
c9c857 |
branchname = flask.request.args.get("identifier")
|
|
Pierre-Yves Chibon |
833d1f |
|
|
Julen Landa Alustiza |
c9c857 |
if repo_obj.is_empty:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Empty repo cannot have a file")
|
|
Pierre-Yves Chibon |
833d1f |
|
|
Julen Landa Alustiza |
c9c857 |
if branchname is None:
|
|
Julen Landa Alustiza |
c9c857 |
if repo_obj.head_is_unborn:
|
|
Julen Landa Alustiza |
c9c857 |
flask.abort(
|
|
Julen Landa Alustiza |
c9c857 |
404, description="Identifier is mandatory on unborn HEAD repos"
|
|
Julen Landa Alustiza |
c9c857 |
)
|
|
Julen Landa Alustiza |
c9c857 |
|
|
Julen Landa Alustiza |
c9c857 |
branchname = repo_obj.head.shorthand
|
|
Julen Landa Alustiza |
c9c857 |
commit = repo_obj[repo_obj.head.target]
|
|
Julen Landa Alustiza |
c9c857 |
|
|
Pierre-Yves Chibon |
8655c1 |
else:
|
|
Julen Landa Alustiza |
c9c857 |
if branchname in repo_obj.listall_branches():
|
|
Julen Landa Alustiza |
c9c857 |
branch = repo_obj.lookup_branch(branchname)
|
|
Julen Landa Alustiza |
c9c857 |
commit = branch.peel(pygit2.Commit)
|
|
Julen Landa Alustiza |
c9c857 |
elif branchname in pagure.lib.git.get_git_tags(repo):
|
|
Julen Landa Alustiza |
c9c857 |
branch = repo_obj.lookup_reference(
|
|
Julen Landa Alustiza |
c9c857 |
"refs/tags/{}".format(branchname)
|
|
Julen Landa Alustiza |
c9c857 |
)
|
|
Julen Landa Alustiza |
c9c857 |
commit = branch.peel(pygit2.Commit)
|
|
Julen Landa Alustiza |
c9c857 |
else:
|
|
Julen Landa Alustiza |
c9c857 |
try:
|
|
Julen Landa Alustiza |
c9c857 |
commit = repo_obj[branchname]
|
|
Julen Landa Alustiza |
c9c857 |
except ValueError:
|
|
Julen Landa Alustiza |
c9c857 |
flask.abort(
|
|
Julen Landa Alustiza |
c9c857 |
404, description="Cannot find specified identifier"
|
|
Julen Landa Alustiza |
c9c857 |
)
|
|
Pierre-Yves Chibon |
8655c1 |
|
|
Pierre-Yves Chibon |
0e35e9 |
if isinstance(commit, pygit2.Tag):
|
|
Pierre-Yves Chibon |
91cec1 |
commit = commit.peel(pygit2.Commit)
|
|
Pierre-Yves Chibon |
0e35e9 |
|
|
Pierre-Yves Chibon |
833d1f |
content = __get_file_in_tree(
|
|
Pierre-Yves Chibon |
9c2953 |
repo_obj, commit.tree, filename.split("/"), bail_on_tree=True
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
833d1f |
if not content:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="File not found")
|
|
Pierre-Yves Chibon |
833d1f |
|
|
Pierre-Yves Chibon |
833d1f |
if not isinstance(content, pygit2.Blob):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="File not found")
|
|
Pierre-Yves Chibon |
833d1f |
if is_binary_string(content.data):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(400, description="Binary files cannot be blamed")
|
|
Pierre-Yves Chibon |
833d1f |
|
|
Pierre-Yves Chibon |
65d40a |
try:
|
|
Pierre-Yves Chibon |
65d40a |
content = encoding_utils.decode(content.data)
|
|
Pierre-Yves Chibon |
65d40a |
except pagure.exceptions.PagureException:
|
|
Pierre-Yves Chibon |
65d40a |
# We cannot decode the file, so bail but warn the admins
|
|
Pierre-Yves Chibon |
9c2953 |
_log.exception("File could not be decoded")
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(500, description="File could not be decoded")
|
|
Pierre-Yves Chibon |
65d40a |
|
|
Pierre-Yves Chibon |
8655c1 |
blame = repo_obj.blame(filename, newest_commit=commit.oid.hex)
|
|
Pierre-Yves Chibon |
833d1f |
|
|
Pierre-Yves Chibon |
833d1f |
return flask.render_template(
|
|
Pierre-Yves Chibon |
9c2953 |
"blame.html",
|
|
Pierre-Yves Chibon |
9c2953 |
select="tree",
|
|
Pierre-Yves Chibon |
833d1f |
repo=repo,
|
|
Pierre-Yves Chibon |
9c2953 |
origin="view_file",
|
|
Pierre-Yves Chibon |
833d1f |
username=username,
|
|
Pierre-Yves Chibon |
833d1f |
filename=filename,
|
|
Pierre-Yves Chibon |
833d1f |
branchname=branchname,
|
|
Pierre-Yves Chibon |
833d1f |
content=content,
|
|
Pierre-Yves Chibon |
9c2953 |
output_type="blame",
|
|
Pierre-Yves Chibon |
833d1f |
blame=blame,
|
|
Pierre-Yves Chibon |
833d1f |
)
|
|
Pierre-Yves Chibon |
833d1f |
|
|
Pierre-Yves Chibon |
833d1f |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/c/<commitid>/")</commitid></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/c/<commitid>")</commitid></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/c/<commitid>/")</commitid></repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/c/<commitid>")</commitid></repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/c/<commitid>/")</commitid></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/c/<commitid>")</commitid></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/c/<commitid>/")</commitid></repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/c/<commitid>")</commitid></repo></namespace></username>
|
|
Pierre-Yves Chibon |
4501da |
def view_commit(repo, commitid, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
47950c |
""" Render a commit in a repo
|
|
Pierre-Yves Chibon |
47950c |
"""
|
|
Pierre-Yves Chibon |
16572e |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
d49b8c |
if not repo:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Project not found")
|
|
Pierre-Yves Chibon |
d49b8c |
|
|
Pierre-Yves Chibon |
16572e |
repo_obj = flask.g.repo_obj
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
9c2953 |
branchname = flask.request.args.get("branch", None)
|
|
Vivek Anand |
1ff64e |
|
|
Pierre-Yves Chibon |
9c2953 |
splitview = flask.request.args.get("splitview", False)
|
|
Ryan Lerch |
e2f045 |
|
|
Pierre-Yves Chibon |
9c2953 |
if "splitview" in flask.request.args:
|
|
Ryan Lerch |
e2f045 |
splitview = True
|
|
Ryan Lerch |
e2f045 |
else:
|
|
Ryan Lerch |
e2f045 |
splitview = False
|
|
Ryan Lerch |
e2f045 |
|
|
Vivek Anand |
1ff64e |
if branchname and branchname not in repo_obj.listall_branches():
|
|
Vivek Anand |
d3485c |
branchname = None
|
|
Vivek Anand |
1ff64e |
|
|
Pierre-Yves Chibon |
47950c |
try:
|
|
Pierre-Yves Chibon |
47950c |
commit = repo_obj.get(commitid)
|
|
Pierre-Yves Chibon |
47950c |
except ValueError:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Commit not found")
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
0a3e63 |
if commit is None:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Commit not found")
|
|
Pierre-Yves Chibon |
0a3e63 |
|
|
Pierre-Yves Chibon |
66b80e |
if isinstance(commit, pygit2.Blob):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Commit not found")
|
|
Pierre-Yves Chibon |
66b80e |
|
|
Pierre-Yves Chibon |
47950c |
if commit.parents:
|
|
Carlos Mogas da Silva |
dbd6dd |
diff = repo_obj.diff(commit.parents[0], commit)
|
|
Pierre-Yves Chibon |
47950c |
else:
|
|
Pierre-Yves Chibon |
47950c |
# First commit in the repo
|
|
Pierre-Yves Chibon |
47950c |
diff = commit.tree.diff_to_tree(swap=True)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Ryan Lerch |
e2f045 |
if diff:
|
|
Ryan Lerch |
e2f045 |
diff.find_similar()
|
|
Ryan Lerch |
e2f045 |
|
|
Pierre-Yves Chibon |
47950c |
return flask.render_template(
|
|
Pierre-Yves Chibon |
9c2953 |
"commit.html",
|
|
Pierre-Yves Chibon |
9c2953 |
select="commits",
|
|
Pierre-Yves Chibon |
47950c |
repo=repo,
|
|
Vivek Anand |
1ff64e |
branchname=branchname,
|
|
Pierre-Yves Chibon |
47950c |
username=username,
|
|
Pierre-Yves Chibon |
47950c |
commitid=commitid,
|
|
Pierre-Yves Chibon |
47950c |
commit=commit,
|
|
Pierre-Yves Chibon |
47950c |
diff=diff,
|
|
Ryan Lerch |
e2f045 |
splitview=splitview,
|
|
Pierre-Yves Chibon |
930073 |
flags=pagure.lib.query.get_commit_flag(
|
|
Pierre-Yves Chibon |
930073 |
flask.g.session, repo, commitid
|
|
Pierre-Yves Chibon |
930073 |
),
|
|
Pierre-Yves Chibon |
47950c |
)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/c/<commitid>.patch")</commitid></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/c/<commitid>.patch")</commitid></repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/c/<commitid>.patch")</commitid></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/c/<commitid>.patch")</commitid></repo></namespace></username>
|
|
Pierre-Yves Chibon |
4501da |
def view_commit_patch(repo, commitid, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
74eefa |
""" Render a commit in a repo as patch
|
|
Pierre-Yves Chibon |
74eefa |
"""
|
|
Pierre-Yves Chibon |
4b90cc |
return view_commit_patch_or_diff(
|
|
Pierre-Yves Chibon |
9c2953 |
repo, commitid, username, namespace, diff=False
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
4b90cc |
|
|
Pierre-Yves Chibon |
4b90cc |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/c/<commitid>.diff")</commitid></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/c/<commitid>.diff")</commitid></repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/c/<commitid>.diff")</commitid></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/c/<commitid>.diff")</commitid></repo></namespace></username>
|
|
Pierre-Yves Chibon |
4b90cc |
def view_commit_diff(repo, commitid, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
4b90cc |
""" Render a commit in a repo as diff
|
|
Pierre-Yves Chibon |
4b90cc |
"""
|
|
Ryan Lerch |
e2f045 |
|
|
Pierre-Yves Chibon |
9c2953 |
is_js = is_true(flask.request.args.get("js"))
|
|
Ryan Lerch |
e2f045 |
|
|
Pierre-Yves Chibon |
4b90cc |
return view_commit_patch_or_diff(
|
|
Pierre-Yves Chibon |
9c2953 |
repo, commitid, username, namespace, diff=True, is_js=is_js
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
4b90cc |
|
|
Pierre-Yves Chibon |
4b90cc |
|
|
Pierre-Yves Chibon |
4b90cc |
def view_commit_patch_or_diff(
|
|
Pierre-Yves Chibon |
9c2953 |
repo, commitid, username=None, namespace=None, diff=False, is_js=False
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Pierre-Yves Chibon |
4b90cc |
""" Renders a commit either as a patch or as a diff. """
|
|
Pierre-Yves Chibon |
4b90cc |
|
|
Pierre-Yves Chibon |
16572e |
repo_obj = flask.g.repo_obj
|
|
Pierre-Yves Chibon |
74eefa |
|
|
Ryan Lerch |
e2f045 |
if is_js:
|
|
Pierre-Yves Chibon |
9c2953 |
errorresponse = flask.jsonify(
|
|
Pierre-Yves Chibon |
9c2953 |
{"code": "ERROR", "message": "Commit not found"}
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Ryan Lerch |
e2f045 |
errorresponse.status_code = 404
|
|
Ryan Lerch |
e2f045 |
|
|
Pierre-Yves Chibon |
74eefa |
try:
|
|
Pierre-Yves Chibon |
74eefa |
commit = repo_obj.get(commitid)
|
|
Pierre-Yves Chibon |
74eefa |
except ValueError:
|
|
Ryan Lerch |
e2f045 |
if is_js:
|
|
Ryan Lerch |
e2f045 |
return errorresponse
|
|
Ryan Lerch |
e2f045 |
else:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Commit not found")
|
|
Pierre-Yves Chibon |
2f0596 |
|
|
Pierre-Yves Chibon |
2f0596 |
if commit is None:
|
|
Ryan Lerch |
e2f045 |
if is_js:
|
|
Ryan Lerch |
e2f045 |
return errorresponse
|
|
Ryan Lerch |
e2f045 |
else:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Commit not found")
|
|
Ryan Lerch |
e2f045 |
|
|
Ryan Lerch |
e2f045 |
if is_js:
|
|
Pierre-Yves Chibon |
86e455 |
patches = pagure.lib.git.commit_to_patch(
|
|
Pierre-Yves Chibon |
9c2953 |
repo_obj, commit, diff_view=True, find_similar=True, separated=True
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
86e455 |
|
|
Pierre-Yves Chibon |
86e455 |
diffs = {}
|
|
Pierre-Yves Chibon |
86e455 |
for idx, patch in enumerate(patches):
|
|
Pierre-Yves Chibon |
86e455 |
diffs[idx + 1] = patch
|
|
Ryan Lerch |
e2f045 |
|
|
Ryan Lerch |
e2f045 |
return flask.jsonify(diffs)
|
|
Ryan Lerch |
e2f045 |
else:
|
|
Ryan Lerch |
e2f045 |
patch = pagure.lib.git.commit_to_patch(
|
|
Pierre-Yves Chibon |
9c2953 |
repo_obj, commit, diff_view=diff
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Ryan Lerch |
e2f045 |
return flask.Response(patch, content_type="text/plain;charset=UTF-8")
|
|
Pierre-Yves Chibon |
74eefa |
|
|
Pierre-Yves Chibon |
74eefa |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/tree/")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/tree")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/tree/")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/tree")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/tree/<path:identifier>")</path:identifier></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/tree/<path:identifier>")</path:identifier></repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/tree/")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/tree")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/tree/")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/tree")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/tree/<path:identifier>")</path:identifier></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/tree/<path:identifier>")</path:identifier></repo></namespace></username>
|
|
Pierre-Yves Chibon |
4501da |
def view_tree(repo, identifier=None, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
47950c |
""" Render the tree of the repo
|
|
Pierre-Yves Chibon |
47950c |
"""
|
|
Pierre-Yves Chibon |
16572e |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
16572e |
repo_obj = flask.g.repo_obj
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
c184e7 |
branchname = None
|
|
Pierre-Yves Chibon |
c184e7 |
content = None
|
|
Pierre-Yves Chibon |
c184e7 |
output_type = None
|
|
Pierre-Yves Chibon |
d27f13 |
commit = None
|
|
Pierre-Yves Chibon |
0359fe |
readme = None
|
|
Pierre-Yves Chibon |
0359fe |
safe = False
|
|
Pierre-Yves Chibon |
0359fe |
readme_ext = None
|
|
Pierre-Yves Chibon |
c184e7 |
if not repo_obj.is_empty:
|
|
Pierre-Yves Chibon |
c184e7 |
if identifier in repo_obj.listall_branches():
|
|
Pierre-Yves Chibon |
47950c |
branchname = identifier
|
|
Pierre-Yves Chibon |
c184e7 |
branch = repo_obj.lookup_branch(identifier)
|
|
Pierre-Yves Chibon |
91cec1 |
commit = branch.peel(pygit2.Commit)
|
|
Pierre-Yves Chibon |
c184e7 |
else:
|
|
Pierre-Yves Chibon |
c184e7 |
try:
|
|
Pierre-Yves Chibon |
c184e7 |
commit = repo_obj.get(identifier)
|
|
Pierre-Yves Chibon |
c184e7 |
branchname = identifier
|
|
Pierre-Yves Chibon |
c184e7 |
except (ValueError, TypeError):
|
|
Pierre-Yves Chibon |
c184e7 |
# If it's not a commit id then it's part of the filename
|
|
Vivek Anand |
692787 |
if not repo_obj.head_is_unborn:
|
|
Vivek Anand |
692787 |
branchname = repo_obj.head.shorthand
|
|
Pierre-Yves Chibon |
cef492 |
commit = repo_obj[repo_obj.head.target]
|
|
Pierre-Yves Chibon |
0fb867 |
if identifier:
|
|
Pierre-Yves Chibon |
0fb867 |
flask.flash(
|
|
Pierre-Yves Chibon |
0fb867 |
"'%s' not found in the git repository, going back "
|
|
Pierre-Yves Chibon |
0fb867 |
"to: %s" % (identifier, branchname),
|
|
Pierre-Yves Chibon |
0fb867 |
"error",
|
|
Pierre-Yves Chibon |
0fb867 |
)
|
|
Pierre-Yves Chibon |
b4fa1c |
# If we're arriving here from the release page, we may have a Tag
|
|
Pierre-Yves Chibon |
b4fa1c |
# where we expected a commit, in this case, get the actual commit
|
|
Pierre-Yves Chibon |
b4fa1c |
if isinstance(commit, pygit2.Tag):
|
|
Pierre-Yves Chibon |
91cec1 |
commit = commit.peel(pygit2.Commit)
|
|
Pierre-Yves Chibon |
d4bfa3 |
branchname = commit.oid.hex
|
|
Pierre-Yves Chibon |
c184e7 |
|
|
Pierre-Yves Chibon |
a83847 |
if commit and not isinstance(commit, pygit2.Blob):
|
|
Pierre-Yves Chibon |
d27f13 |
content = sorted(commit.tree, key=lambda x: x.filemode)
|
|
Ryan Lerch |
4c1bc5 |
for i in commit.tree:
|
|
Ryan Lerch |
4c1bc5 |
name, ext = os.path.splitext(i.name)
|
|
Pierre-Yves Chibon |
9c2953 |
if name == "README":
|
|
Ryan Lerch |
4c1bc5 |
readme_file = __get_file_in_tree(
|
|
Pierre-Yves Chibon |
9c2953 |
repo_obj, commit.tree, [i.name]
|
|
Pierre-Yves Chibon |
9c2953 |
).data
|
|
Ryan Lerch |
4c1bc5 |
|
|
Ryan Lerch |
4c1bc5 |
readme, safe = pagure.doc_utils.convert_readme(
|
|
Pierre-Yves Chibon |
9c2953 |
readme_file, ext
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Ryan Lerch |
4c1bc5 |
|
|
Ryan Lerch |
4c1bc5 |
readme_ext = ext
|
|
Pierre-Yves Chibon |
9c2953 |
output_type = "tree"
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
return flask.render_template(
|
|
Pierre-Yves Chibon |
9c2953 |
"file.html",
|
|
Pierre-Yves Chibon |
9c2953 |
select="tree",
|
|
Pierre-Yves Chibon |
9c2953 |
origin="view_tree",
|
|
Pierre-Yves Chibon |
47950c |
repo=repo,
|
|
Pierre-Yves Chibon |
47950c |
username=username,
|
|
Pierre-Yves Chibon |
47950c |
branchname=branchname,
|
|
Pierre-Yves Chibon |
9c2953 |
filename="",
|
|
Pierre-Yves Chibon |
47950c |
content=content,
|
|
Pierre-Yves Chibon |
47950c |
output_type=output_type,
|
|
Ryan Lerch |
4c1bc5 |
readme=readme,
|
|
Ryan Lerch |
4c1bc5 |
readme_ext=readme_ext,
|
|
Ryan Lerch |
4c1bc5 |
safe=safe,
|
|
Pierre-Yves Chibon |
47950c |
)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/releases/")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/releases")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/releases/")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/releases")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/releases/")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/releases")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/releases/")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/releases")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
4501da |
def view_tags(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
f63ab5 |
""" Presents all the tags of the project.
|
|
Pierre-Yves Chibon |
f63ab5 |
"""
|
|
Pierre-Yves Chibon |
16572e |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
f63ab5 |
tags = pagure.lib.git.get_git_tags_objects(repo)
|
|
Pierre-Yves Chibon |
0fcf17 |
|
|
Slavek Kabrda |
c3aef6 |
upload_folder_path = pagure_config["UPLOAD_FOLDER_PATH"] or ""
|
|
Pierre-Yves Chibon |
9c2953 |
pagure_checksum = os.path.exists(
|
|
Patrick Uiterwijk |
3f97f6 |
os.path.join(upload_folder_path, repo.fullname, "CHECKSUMS")
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
36309a |
|
|
Pierre-Yves Chibon |
f63ab5 |
return flask.render_template(
|
|
Pierre-Yves Chibon |
9c2953 |
"releases.html",
|
|
Pierre-Yves Chibon |
9c2953 |
select="tags",
|
|
Pierre-Yves Chibon |
f63ab5 |
username=username,
|
|
Pierre-Yves Chibon |
f63ab5 |
repo=repo,
|
|
Clement Verna |
c99c18 |
tags=tags,
|
|
Pierre-Yves Chibon |
36309a |
pagure_checksum=pagure_checksum,
|
|
Pierre-Yves Chibon |
cda607 |
)
|
|
Pierre-Yves Chibon |
cda607 |
|
|
Pierre-Yves Chibon |
77bdcd |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/branches/")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/branches")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/branches/")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/branches")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/branches/")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/branches")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/branches/")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/branches")</repo></namespace></username>
|
|
Ryan Lerch |
6d2e06 |
def view_branches(repo, username=None, namespace=None):
|
|
Ryan Lerch |
6d2e06 |
""" Branches
|
|
Ryan Lerch |
6d2e06 |
"""
|
|
Ryan Lerch |
6d2e06 |
repo_db = flask.g.repo
|
|
Ryan Lerch |
6d2e06 |
repo_obj = flask.g.repo_obj
|
|
Ryan Lerch |
6d2e06 |
|
|
Ryan Lerch |
6d2e06 |
if not repo_obj.is_empty and not repo_obj.head_is_unborn:
|
|
Ryan Lerch |
6d2e06 |
head = repo_obj.head.shorthand
|
|
Ryan Lerch |
6d2e06 |
else:
|
|
Ryan Lerch |
6d2e06 |
head = None
|
|
Ryan Lerch |
6d2e06 |
|
|
Ryan Lerch |
6d2e06 |
if not repo_obj.is_empty and not repo_obj.head_is_unborn:
|
|
Ryan Lerch |
6d2e06 |
branchname = repo_obj.head.shorthand
|
|
Ryan Lerch |
6d2e06 |
else:
|
|
Ryan Lerch |
6d2e06 |
branchname = None
|
|
Ryan Lerch |
6d2e06 |
|
|
Ryan Lerch |
6d2e06 |
return flask.render_template(
|
|
Pierre-Yves Chibon |
9c2953 |
"repo_branches.html",
|
|
Pierre-Yves Chibon |
9c2953 |
select="branches",
|
|
Ryan Lerch |
6d2e06 |
repo=repo_db,
|
|
Ryan Lerch |
6d2e06 |
username=username,
|
|
Ryan Lerch |
6d2e06 |
head=head,
|
|
Pierre-Yves Chibon |
9c2953 |
origin="view_repo",
|
|
Ryan Lerch |
6d2e06 |
branchname=branchname,
|
|
Ryan Lerch |
6d2e06 |
)
|
|
Ryan Lerch |
6d2e06 |
|
|
Ryan Lerch |
321fde |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/forks/")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/forks")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/forks/")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/forks")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/forks/")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/forks")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/forks/")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/forks")</repo></namespace></username>
|
|
Ryan Lerch |
583102 |
def view_forks(repo, username=None, namespace=None):
|
|
Ryan Lerch |
583102 |
""" Forks
|
|
Ryan Lerch |
583102 |
"""
|
|
Ryan Lerch |
321fde |
|
|
Ryan Lerch |
583102 |
return flask.render_template(
|
|
Pierre-Yves Chibon |
9c2953 |
"repo_forks.html", select="forks", username=username, repo=flask.g.repo
|
|
Ryan Lerch |
583102 |
)
|
|
Ryan Lerch |
583102 |
|
|
Ryan Lerch |
6d2e06 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/upload/", methods=("GET", "POST"))</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/upload", methods=("GET", "POST"))</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/upload/", methods=("GET", "POST"))</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/upload", methods=("GET", "POST"))</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/upload/", methods=("GET", "POST"))</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/upload", methods=("GET", "POST"))</repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/upload/", methods=("GET", "POST")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/upload", methods=("GET", "POST")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
cf7f54 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
4501da |
def new_release(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
cda607 |
""" Upload a new release.
|
|
Pierre-Yves Chibon |
cda607 |
"""
|
|
Pierre-Yves Chibon |
9c2953 |
if not pagure_config.get("UPLOAD_FOLDER_PATH") or not pagure_config.get(
|
|
Pierre-Yves Chibon |
9c2953 |
"UPLOAD_FOLDER_URL"
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Pierre-Yves Chibon |
1791e7 |
flask.abort(404)
|
|
Pierre-Yves Chibon |
1791e7 |
|
|
Pierre-Yves Chibon |
74dadb |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
cda607 |
|
|
Pierre-Yves Chibon |
cda607 |
form = pagure.forms.UploadFileForm()
|
|
Pierre-Yves Chibon |
cda607 |
|
|
Pierre-Yves Chibon |
cda607 |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
36309a |
filenames = []
|
|
Pierre-Yves Chibon |
4c06f0 |
error = False
|
|
Pierre-Yves Chibon |
9c2953 |
for filestream in flask.request.files.getlist("filestream"):
|
|
Pierre-Yves Chibon |
d68be6 |
filename = werkzeug.secure_filename(filestream.filename)
|
|
Pierre-Yves Chibon |
36309a |
filenames.append(filename)
|
|
Pierre-Yves Chibon |
d68be6 |
try:
|
|
Pierre-Yves Chibon |
d68be6 |
folder = os.path.join(
|
|
Pierre-Yves Chibon |
9c2953 |
pagure_config["UPLOAD_FOLDER_PATH"], repo.fullname
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
d68be6 |
if not os.path.exists(folder):
|
|
Pierre-Yves Chibon |
70b432 |
os.makedirs(folder)
|
|
Pierre-Yves Chibon |
db5bf1 |
dest = os.path.join(folder, filename)
|
|
Pierre-Yves Chibon |
db5bf1 |
if os.path.exists(dest):
|
|
Pierre-Yves Chibon |
db5bf1 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
9c2953 |
"This tarball has already been uploaded"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
1a1f1e |
|
|
Pierre-Yves Chibon |
1a1f1e |
filestream.save(dest)
|
|
Pierre-Yves Chibon |
1a1f1e |
flask.flash('File "%s" uploaded' % filename)
|
|
Pierre-Yves Chibon |
db5bf1 |
except pagure.exceptions.PagureException as err:
|
|
Pierre-Yves Chibon |
d9dd52 |
_log.debug(err)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash(str(err), "error")
|
|
Pierre-Yves Chibon |
4c06f0 |
error = True
|
|
Pierre-Yves Chibon |
d68be6 |
except Exception as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
4635b5 |
_log.exception(err)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Upload failed", "error")
|
|
Pierre-Yves Chibon |
4c06f0 |
error = True
|
|
Pierre-Yves Chibon |
4c06f0 |
|
|
Pierre-Yves Chibon |
4c06f0 |
if not error:
|
|
Pierre-Yves Chibon |
4c06f0 |
task = pagure.lib.tasks.update_checksums_file.delay(
|
|
Pierre-Yves Chibon |
9c2953 |
folder=folder, filenames=filenames
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
4c06f0 |
_log.info(
|
|
Pierre-Yves Chibon |
9c2953 |
"Updating checksums for %s of project %s in task: %s"
|
|
Pierre-Yves Chibon |
9c2953 |
% (filenames, repo.fullname, task.id)
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
36309a |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_tags",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=repo.namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
cda607 |
|
|
Pierre-Yves Chibon |
cda607 |
return flask.render_template(
|
|
Pierre-Yves Chibon |
9c2953 |
"new_release.html",
|
|
Pierre-Yves Chibon |
9c2953 |
select="tags",
|
|
Pierre-Yves Chibon |
cda607 |
username=username,
|
|
Pierre-Yves Chibon |
cda607 |
repo=repo,
|
|
Pierre-Yves Chibon |
cda607 |
form=form,
|
|
Pierre-Yves Chibon |
f63ab5 |
)
|
|
Pierre-Yves Chibon |
f63ab5 |
|
|
Pierre-Yves Chibon |
f63ab5 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/settings/", methods=("GET", "POST"))</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/settings", methods=("GET", "POST"))</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/settings/", methods=("GET", "POST"))</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/settings", methods=("GET", "POST"))</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/settings/", methods=("GET", "POST"))</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/settings", methods=("GET", "POST"))</repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/settings/", methods=("GET", "POST")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/settings", methods=("GET", "POST")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
cf7f54 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
4501da |
def view_settings(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
0261ce |
""" Presents the settings of the project.
|
|
Pierre-Yves Chibon |
0261ce |
"""
|
|
Pierre-Yves Chibon |
0812cb |
|
|
Pierre-Yves Chibon |
16572e |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
16572e |
repo_obj = flask.g.repo_obj
|
|
Pierre-Yves Chibon |
0261ce |
|
|
Pierre-Yves Chibon |
295cfb |
plugins = pagure.lib.plugins.get_plugin_names(
|
|
Pierre-Yves Chibon |
9c2953 |
pagure_config.get("DISABLED_PLUGINS")
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
930073 |
tags = pagure.lib.query.get_tags_of_project(flask.g.session, repo)
|
|
Pierre-Yves Chibon |
58eba3 |
|
|
Pierre-Yves Chibon |
4d8ef3 |
form = pagure.forms.ConfirmationForm()
|
|
Pierre-Yves Chibon |
fe5017 |
tag_form = pagure.forms.AddIssueTagForm()
|
|
Ghost-script |
d50d9e |
|
|
Ghost-script |
966a39 |
branches = repo_obj.listall_branches()
|
|
Ghost-script |
966a39 |
branches_form = pagure.forms.DefaultBranchForm(branches=branches)
|
|
Pierre-Yves Chibon |
dff667 |
priority_form = pagure.forms.DefaultPriorityForm(
|
|
Pierre-Yves Chibon |
9c2953 |
priorities=repo.priorities.values()
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
dff667 |
|
|
Pierre-Yves Chibon |
0261ce |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
4d8ef3 |
settings = {}
|
|
Pierre-Yves Chibon |
4d8ef3 |
for key in flask.request.form:
|
|
Pierre-Yves Chibon |
9c2953 |
if key == "csrf_token":
|
|
Pierre-Yves Chibon |
4d8ef3 |
continue
|
|
Pierre-Yves Chibon |
4d8ef3 |
settings[key] = flask.request.form[key]
|
|
Pierre-Yves Chibon |
0261ce |
|
|
Pierre-Yves Chibon |
0261ce |
try:
|
|
Pierre-Yves Chibon |
930073 |
message = pagure.lib.query.update_project_settings(
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session,
|
|
Pierre-Yves Chibon |
0261ce |
repo=repo,
|
|
Pierre-Yves Chibon |
4d8ef3 |
settings=settings,
|
|
Pierre-Yves Chibon |
67b177 |
user=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
0261ce |
)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
0261ce |
flask.flash(message)
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_repo",
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=repo.namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
2ac7df |
except pagure.exceptions.PagureException as msg:
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
d9dd52 |
_log.debug(msg)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash(str(msg), "error")
|
|
Pierre-Yves Chibon |
fa97f7 |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash(str(err), "error")
|
|
Ghost-script |
d50d9e |
|
|
Ghost-script |
d50d9e |
if not repo_obj.is_empty and not repo_obj.head_is_unborn:
|
|
Ghost-script |
d50d9e |
branchname = repo_obj.head.shorthand
|
|
Ghost-script |
d50d9e |
else:
|
|
Ghost-script |
d50d9e |
branchname = None
|
|
Pierre-Yves Chibon |
c11edb |
|
|
Pierre-Yves Chibon |
9c2953 |
if flask.request.method == "GET" and branchname:
|
|
Pierre-Yves Chibon |
6780a1 |
branches_form.branches.data = branchname
|
|
Pierre-Yves Chibon |
6e51b2 |
priority_form.priority.data = repo.default_priority
|
|
Pierre-Yves Chibon |
6780a1 |
|
|
Pierre-Yves Chibon |
0261ce |
return flask.render_template(
|
|
Pierre-Yves Chibon |
9c2953 |
"settings.html",
|
|
Pierre-Yves Chibon |
9c2953 |
select="settings",
|
|
Pierre-Yves Chibon |
0261ce |
username=username,
|
|
Pierre-Yves Chibon |
0261ce |
repo=repo,
|
|
Matt Prahl |
cbadc1 |
access_users=repo.access_users,
|
|
Matt Prahl |
cbadc1 |
access_groups=repo.access_groups,
|
|
Pierre-Yves Chibon |
0261ce |
form=form,
|
|
Pierre-Yves Chibon |
77cd34 |
tag_form=tag_form,
|
|
Ghost-script |
966a39 |
branches_form=branches_form,
|
|
Pierre-Yves Chibon |
dff667 |
priority_form=priority_form,
|
|
Pierre-Yves Chibon |
77cd34 |
tags=tags,
|
|
Pierre-Yves Chibon |
58eba3 |
plugins=plugins,
|
|
Pierre-Yves Chibon |
53e4c2 |
branchname=branchname,
|
|
Ryan Lerch |
6d2e06 |
pagure_admin=pagure.utils.is_admin(),
|
|
Pierre-Yves Chibon |
0261ce |
)
|
|
Pierre-Yves Chibon |
55a6e0 |
|
|
Pierre-Yves Chibon |
55a6e0 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/settings/test_hook", methods=("GET", "POST"))</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/settings/test_hook", methods=("GET", "POST"))</repo></namespace>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<repo>/settings/test_hook", methods=("GET", "POST")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/settings/test_hook",</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
methods=("GET", "POST"),
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
8c8487 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
8c8487 |
def test_web_hook(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
640383 |
""" Endpoint that can be called to send a test message to the web-hook
|
|
Pierre-Yves Chibon |
640383 |
service allowing to test the web-hooks set.
|
|
Pierre-Yves Chibon |
8c8487 |
"""
|
|
Pierre-Yves Chibon |
8c8487 |
|
|
Pierre-Yves Chibon |
8c8487 |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
8c8487 |
|
|
Pierre-Yves Chibon |
8c8487 |
form = pagure.forms.ConfirmationForm()
|
|
Pierre-Yves Chibon |
8c8487 |
if form.validate_on_submit():
|
|
Clement Verna |
df1eef |
|
|
Clement Verna |
df1eef |
pagure.lib.notify.log(
|
|
Clement Verna |
df1eef |
project=repo,
|
|
Clement Verna |
df1eef |
topic="Test.notification",
|
|
Clement Verna |
df1eef |
msg={"content": "Test message"},
|
|
Pierre-Yves Chibon |
cc01b8 |
webhook=True,
|
|
Clement Verna |
df1eef |
)
|
|
Clement Verna |
df1eef |
flask.flash("Notification triggered")
|
|
Pierre-Yves Chibon |
8c8487 |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=repo.namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#projectoptions-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
8c8487 |
|
|
Pierre-Yves Chibon |
8c8487 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/update", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/update", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/update", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/update", methods=["POST"])</repo></namespace></username>
|
|
Pierre-Yves Chibon |
cf7f54 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
4501da |
def update_project(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
64a70d |
""" Update the description of a project.
|
|
Pierre-Yves Chibon |
64a70d |
"""
|
|
Pierre-Yves Chibon |
ced1fc |
|
|
Pierre-Yves Chibon |
74dadb |
repo = flask.g.repo
|
|
farhaanbukhsh |
83ccf7 |
|
|
Pierre-Yves Chibon |
2e67a4 |
form = pagure.forms.ProjectFormSimplified()
|
|
Pierre-Yves Chibon |
64a70d |
|
|
Pierre-Yves Chibon |
64a70d |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
1878ce |
|
|
Pierre-Yves Chibon |
64a70d |
try:
|
|
Pierre-Yves Chibon |
64a70d |
repo.description = form.description.data
|
|
Pierre-Yves Chibon |
2e67a4 |
repo.avatar_email = form.avatar_email.data.strip()
|
|
Pierre-Yves Chibon |
2e67a4 |
repo.url = form.url.data.strip()
|
|
Pierre-Yves Chibon |
6efa08 |
if repo.private:
|
|
Pierre-Yves Chibon |
6efa08 |
repo.private = form.private.data
|
|
Pierre-Yves Chibon |
930073 |
pagure.lib.query.update_tags(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session,
|
|
Pierre-Yves Chibon |
9c2953 |
repo,
|
|
Pierre-Yves Chibon |
9c2953 |
tags=[t.strip() for t in form.tags.data.split(",")],
|
|
Pierre-Yves Chibon |
8f0ef0 |
username=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
2e464a |
)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.add(repo)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Project updated")
|
|
Pierre-Yves Chibon |
fa97f7 |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash(str(err), "error")
|
|
Pierre-Yves Chibon |
e64870 |
else:
|
|
Pierre-Yves Chibon |
e64870 |
for field in form.errors:
|
|
Pierre-Yves Chibon |
e64870 |
flask.flash(
|
|
Pierre-Yves Chibon |
9c2953 |
'Field "%s" errored with errors: %s'
|
|
Pierre-Yves Chibon |
9c2953 |
% (field, ", ".join(form.errors[field])),
|
|
Pierre-Yves Chibon |
9c2953 |
"error",
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
64a70d |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=repo.namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#projectdetails-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
64a70d |
|
|
Pierre-Yves Chibon |
64a70d |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/update/priorities", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/update/priorities", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/update/priorities", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/update/priorities", methods=["POST"]</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
ca0eec |
@login_required
|
|
Clement Verna |
afe475 |
@has_issue_tracker
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
4501da |
def update_priorities(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
ca0eec |
""" Update the priorities of a project.
|
|
Pierre-Yves Chibon |
ca0eec |
"""
|
|
Pierre-Yves Chibon |
ca0eec |
|
|
Pierre-Yves Chibon |
74dadb |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
ca0eec |
|
|
Pierre-Yves Chibon |
ca0eec |
form = pagure.forms.ConfirmationForm()
|
|
Pierre-Yves Chibon |
ca0eec |
|
|
Pierre-Yves Chibon |
ca0eec |
error = False
|
|
Pierre-Yves Chibon |
ca0eec |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
ca0eec |
weights = [
|
|
Pierre-Yves Chibon |
9c2953 |
w.strip()
|
|
Pierre-Yves Chibon |
9c2953 |
for w in flask.request.form.getlist("priority_weigth")
|
|
Pierre-Yves Chibon |
ca0eec |
if w.strip()
|
|
Pierre-Yves Chibon |
ca0eec |
]
|
|
Pierre-Yves Chibon |
ca0eec |
try:
|
|
Pierre-Yves Chibon |
ca0eec |
weights = [int(w) for w in weights]
|
|
Abhijeet Kasurde |
f4bf50 |
except (ValueError, TypeError):
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Priorities weights must be numbers", "error")
|
|
Pierre-Yves Chibon |
ca0eec |
error = True
|
|
Pierre-Yves Chibon |
ca0eec |
|
|
Pierre-Yves Chibon |
ca0eec |
titles = [
|
|
Pierre-Yves Chibon |
9c2953 |
p.strip()
|
|
Pierre-Yves Chibon |
9c2953 |
for p in flask.request.form.getlist("priority_title")
|
|
Pierre-Yves Chibon |
ca0eec |
if p.strip()
|
|
Pierre-Yves Chibon |
ca0eec |
]
|
|
Pierre-Yves Chibon |
ca0eec |
|
|
Pierre-Yves Chibon |
ca0eec |
if len(weights) != len(titles):
|
|
Pierre-Yves Chibon |
ca0eec |
flask.flash(
|
|
Pierre-Yves Chibon |
9c2953 |
"Priorities weights and titles are not of the same length",
|
|
Pierre-Yves Chibon |
9c2953 |
"error",
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
ca0eec |
error = True
|
|
Pierre-Yves Chibon |
ca0eec |
|
|
Pierre-Yves Chibon |
bd9d21 |
for weight in weights:
|
|
Pierre-Yves Chibon |
bd9d21 |
if weights.count(weight) != 1:
|
|
Pierre-Yves Chibon |
bd9d21 |
flask.flash(
|
|
Pierre-Yves Chibon |
9c2953 |
"Priority weight %s is present %s times"
|
|
Pierre-Yves Chibon |
9c2953 |
% (weight, weights.count(weight)),
|
|
Pierre-Yves Chibon |
9c2953 |
"error",
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
bd9d21 |
error = True
|
|
Pierre-Yves Chibon |
bd9d21 |
break
|
|
Pierre-Yves Chibon |
bd9d21 |
|
|
Pierre-Yves Chibon |
bd9d21 |
for title in titles:
|
|
Pierre-Yves Chibon |
bd9d21 |
if titles.count(title) != 1:
|
|
Pierre-Yves Chibon |
bd9d21 |
flask.flash(
|
|
Pierre-Yves Chibon |
9c2953 |
"Priority %s is present %s times"
|
|
Pierre-Yves Chibon |
9c2953 |
% (title, titles.count(title)),
|
|
Pierre-Yves Chibon |
9c2953 |
"error",
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
bd9d21 |
error = True
|
|
Pierre-Yves Chibon |
bd9d21 |
break
|
|
Pierre-Yves Chibon |
bd9d21 |
|
|
Pierre-Yves Chibon |
ca0eec |
if not error:
|
|
Pierre-Yves Chibon |
ca0eec |
priorities = {}
|
|
Pierre-Yves Chibon |
7b3aee |
if weights:
|
|
Pierre-Yves Chibon |
7b3aee |
for cnt in range(len(weights)):
|
|
Pierre-Yves Chibon |
7b3aee |
priorities[weights[cnt]] = titles[cnt]
|
|
Pierre-Yves Chibon |
9c2953 |
priorities[""] = ""
|
|
Pierre-Yves Chibon |
ca0eec |
try:
|
|
Pierre-Yves Chibon |
ca0eec |
repo.priorities = priorities
|
|
Pierre-Yves Chibon |
606ecb |
if repo.default_priority not in priorities.values():
|
|
Pierre-Yves Chibon |
606ecb |
flask.flash(
|
|
Pierre-Yves Chibon |
9c2953 |
"Default priority reset as it is no longer one of "
|
|
Pierre-Yves Chibon |
9c2953 |
"set priorities."
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
606ecb |
repo.default_priority = None
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.add(repo)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Priorities updated")
|
|
Pierre-Yves Chibon |
ca0eec |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash(str(err), "error")
|
|
Pierre-Yves Chibon |
ca0eec |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=repo.namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#priorities-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
ca0eec |
|
|
Pierre-Yves Chibon |
e49493 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/update/default_priority", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/update/default_priority", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<repo>/update/default_priority", methods=["POST"]</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/update/default_priority",</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
methods=["POST"],
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
dff667 |
@login_required
|
|
Clement Verna |
afe475 |
@has_issue_tracker
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
dff667 |
def default_priority(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
dff667 |
""" Update the default priority of a project.
|
|
Pierre-Yves Chibon |
dff667 |
"""
|
|
Pierre-Yves Chibon |
dff667 |
|
|
Pierre-Yves Chibon |
dff667 |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
dff667 |
|
|
Pierre-Yves Chibon |
dff667 |
form = pagure.forms.DefaultPriorityForm(
|
|
Pierre-Yves Chibon |
9c2953 |
priorities=repo.priorities.values()
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
dff667 |
|
|
Pierre-Yves Chibon |
dff667 |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
dff667 |
priority = form.priority.data or None
|
|
Pierre-Yves Chibon |
dff667 |
if priority in repo.priorities.values() or priority is None:
|
|
Pierre-Yves Chibon |
dff667 |
repo.default_priority = priority
|
|
Pierre-Yves Chibon |
dff667 |
try:
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.add(repo)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
dff667 |
if priority:
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Default priority set to %s" % priority)
|
|
Pierre-Yves Chibon |
dff667 |
else:
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Default priority reset")
|
|
Pierre-Yves Chibon |
dff667 |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash(str(err), "error")
|
|
Pierre-Yves Chibon |
dff667 |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=repo.namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#priorities-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
dff667 |
|
|
Pierre-Yves Chibon |
dff667 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/update/milestones", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/update/milestones", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/update/milestones", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/update/milestones", methods=["POST"]</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
ccf782 |
@login_required
|
|
Clement Verna |
afe475 |
@has_issue_tracker
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
4501da |
def update_milestones(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
ccf782 |
""" Update the milestones of a project.
|
|
Pierre-Yves Chibon |
ccf782 |
"""
|
|
Pierre-Yves Chibon |
ccf782 |
|
|
Pierre-Yves Chibon |
74dadb |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
ccf782 |
|
|
Pierre-Yves Chibon |
ccf782 |
form = pagure.forms.ConfirmationForm()
|
|
Pierre-Yves Chibon |
ccf782 |
|
|
Pierre-Yves Chibon |
ccf782 |
error = False
|
|
Pierre-Yves Chibon |
ccf782 |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
9c2953 |
redirect = flask.request.args.get("from")
|
|
Akanksha |
d86ac1 |
milestones = flask.request.form.getlist("milestones")
|
|
Akanksha |
d86ac1 |
miles = {}
|
|
Akanksha |
d86ac1 |
keys = []
|
|
Pierre-Yves Chibon |
ccf782 |
|
|
Akanksha |
d86ac1 |
for idx in milestones:
|
|
Akanksha |
d86ac1 |
|
|
Akanksha |
d86ac1 |
milestone = flask.request.form.get(
|
|
Akanksha |
d86ac1 |
"milestone_%s_name" % (idx), None
|
|
Akanksha |
d86ac1 |
)
|
|
Akanksha |
d86ac1 |
|
|
Pierre-Yves Chibon |
365671 |
date = flask.request.form.get("milestone_%s_date" % (idx), None)
|
|
Akanksha |
d86ac1 |
|
|
Akanksha |
d86ac1 |
active = (
|
|
Akanksha |
d86ac1 |
True
|
|
Pierre-Yves Chibon |
365671 |
if flask.request.form.get("milestone_%s_active" % (idx))
|
|
Akanksha |
d86ac1 |
else False
|
|
Akanksha |
d86ac1 |
)
|
|
Pierre-Yves Chibon |
ccf782 |
|
|
Akanksha |
d86ac1 |
if milestone and milestone.strip():
|
|
Akanksha |
d86ac1 |
milestone = milestone.strip()
|
|
Akanksha |
d86ac1 |
if milestone in miles:
|
|
Akanksha |
d86ac1 |
flask.flash(
|
|
Akanksha |
d86ac1 |
"Milestone %s is present multiple times" % milestone,
|
|
Akanksha |
d86ac1 |
"error",
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Akanksha |
d86ac1 |
error = True
|
|
Akanksha |
d86ac1 |
break
|
|
Pierre-Yves Chibon |
0619e5 |
|
|
Akanksha |
d86ac1 |
miles[milestone] = {
|
|
Akanksha |
d86ac1 |
"date": date.strip() if date else None,
|
|
Akanksha |
d86ac1 |
"active": active,
|
|
Akanksha |
d86ac1 |
}
|
|
Akanksha |
d86ac1 |
keys.append(milestone)
|
|
Akanksha |
d86ac1 |
|
|
Akanksha |
d86ac1 |
if not error:
|
|
Pierre-Yves Chibon |
ccf782 |
try:
|
|
Pierre-Yves Chibon |
ccf782 |
repo.milestones = miles
|
|
Pierre-Yves Chibon |
0619e5 |
repo.milestones_keys = keys
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.add(repo)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Milestones updated")
|
|
Pierre-Yves Chibon |
ccf782 |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash(str(err), "error")
|
|
Pierre-Yves Chibon |
9c2953 |
|
|
Pierre-Yves Chibon |
9c2953 |
if redirect == "issues":
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_issues",
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
f9f2d5 |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#roadmap-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
ccf782 |
|
|
Pierre-Yves Chibon |
ccf782 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/default/branch/", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/default/branch/", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/default/branch/", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/default/branch/", methods=["POST"]</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
cf7f54 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
4501da |
def change_ref_head(repo, username=None, namespace=None):
|
|
Ghost-script |
966a39 |
""" Change HEAD reference
|
|
Ghost-script |
966a39 |
"""
|
|
Ghost-script |
966a39 |
|
|
Pierre-Yves Chibon |
16572e |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
16572e |
repo_obj = flask.g.repo_obj
|
|
Ghost-script |
966a39 |
|
|
Ghost-script |
d50d9e |
branches = repo_obj.listall_branches()
|
|
Ghost-script |
d50d9e |
form = pagure.forms.DefaultBranchForm(branches=branches)
|
|
Ghost-script |
d50d9e |
|
|
Ghost-script |
d50d9e |
if form.validate_on_submit():
|
|
Ghost-script |
d50d9e |
branchname = form.branches.data
|
|
Ghost-script |
d50d9e |
try:
|
|
Julen Landa Alustiza |
4de8f2 |
pagure.lib.git.git_set_ref_head(project=repo, branch=branchname)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Default branch updated to %s" % branchname)
|
|
Pierre-Yves Chibon |
cff1c9 |
except Exception as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
4635b5 |
_log.exception(err)
|
|
Ghost-script |
966a39 |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#defaultbranch-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Ghost-script |
966a39 |
|
|
Ghost-script |
966a39 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/delete", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/delete", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/delete", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/delete", methods=["POST"])</repo></namespace></username>
|
|
Pierre-Yves Chibon |
cf7f54 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
4501da |
def delete_repo(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
55a6e0 |
""" Delete the present project.
|
|
Pierre-Yves Chibon |
55a6e0 |
"""
|
|
Pierre-Yves Chibon |
3f19a5 |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
3f19a5 |
|
|
Pierre-Yves Chibon |
9c2953 |
del_project = pagure_config.get("ENABLE_DEL_PROJECTS", True)
|
|
Pierre-Yves Chibon |
9c2953 |
del_fork = pagure_config.get("ENABLE_DEL_FORKS", del_project)
|
|
Pierre-Yves Chibon |
9c2953 |
if (not repo.is_fork and not del_project) or (
|
|
Pierre-Yves Chibon |
9c2953 |
repo.is_fork and not del_fork
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Pierre-Yves Chibon |
86d0e0 |
flask.abort(404)
|
|
Pierre-Yves Chibon |
86d0e0 |
|
|
Pierre-Yves Chibon |
1dc86f |
if repo.read_only:
|
|
Pierre-Yves Chibon |
1dc86f |
flask.flash(
|
|
Pierre-Yves Chibon |
9c2953 |
"The ACLs of this project are being refreshed in the backend "
|
|
Pierre-Yves Chibon |
9c2953 |
"this prevents the project from being deleted. Please wait "
|
|
Pierre-Yves Chibon |
9c2953 |
"for this task to finish before trying again. Thanks!"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#deleteproject-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
1dc86f |
|
|
Pierre-Yves Chibon |
5b06f7 |
task = pagure.lib.tasks.delete_project.delay(
|
|
Pierre-Yves Chibon |
b130e5 |
namespace=repo.namespace,
|
|
Pierre-Yves Chibon |
b130e5 |
name=repo.name,
|
|
Pierre-Yves Chibon |
b130e5 |
user=repo.user.user if repo.is_fork else None,
|
|
Pierre-Yves Chibon |
9c2953 |
action_user=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Aurélien Bompard |
a7f281 |
return pagure.utils.wait_for_task(task)
|
|
Pierre-Yves Chibon |
8782bc |
|
|
Pierre-Yves Chibon |
8782bc |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/hook_token", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/hook_token", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/hook_token", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/hook_token", methods=["POST"]</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
cf7f54 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
4501da |
def new_repo_hook_token(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
e3ecd9 |
""" Re-generate a hook token for the present project.
|
|
Pierre-Yves Chibon |
e3ecd9 |
"""
|
|
Pierre-Yves Chibon |
9c2953 |
if not pagure_config.get("WEBHOOK", False):
|
|
Pierre-Yves Chibon |
ec8a64 |
flask.abort(404)
|
|
Pierre-Yves Chibon |
ec8a64 |
|
|
Clement Verna |
afe475 |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
e3ecd9 |
|
|
Pierre-Yves Chibon |
08f719 |
form = pagure.forms.ConfirmationForm()
|
|
Pierre-Yves Chibon |
08f719 |
if not form.validate_on_submit():
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(400, description="Invalid request")
|
|
Pierre-Yves Chibon |
08f719 |
|
|
Pierre-Yves Chibon |
e3ecd9 |
try:
|
|
Pierre-Yves Chibon |
e3ecd9 |
repo.hook_token = pagure.lib.login.id_generator(40)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("New hook token generated")
|
|
Pierre-Yves Chibon |
fa97f7 |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
4635b5 |
_log.exception(err)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Could not generate a new token for this project", "error")
|
|
Pierre-Yves Chibon |
e3ecd9 |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#privatehookkey-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
e3ecd9 |
|
|
Pierre-Yves Chibon |
e3ecd9 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/dropdeploykey/<int:keyid>", methods=["POST"])</int:keyid></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/dropdeploykey/<int:keyid>", methods=["POST"])</int:keyid></repo></namespace>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<repo>/dropdeploykey/<int:keyid>", methods=["POST"]</int:keyid></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/dropdeploykey/<int:keyid>",</int:keyid></repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
methods=["POST"],
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Patrick Uiterwijk |
9a7915 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Patrick Uiterwijk |
9a7915 |
def remove_deploykey(repo, keyid, username=None, namespace=None):
|
|
Patrick Uiterwijk |
9a7915 |
""" Remove the specified deploy key from the project.
|
|
Patrick Uiterwijk |
9a7915 |
"""
|
|
Patrick Uiterwijk |
9a7915 |
|
|
Pierre-Yves Chibon |
9c2953 |
if not pagure_config.get("DEPLOY_KEY", True):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(
|
|
Pierre-Yves Chibon |
c6cc5c |
404, description="This pagure instance disabled deploy keys"
|
|
Pierre-Yves Chibon |
c6cc5c |
)
|
|
Pierre-Yves Chibon |
39f1dc |
|
|
Patrick Uiterwijk |
9a7915 |
repo = flask.g.repo
|
|
Patrick Uiterwijk |
9a7915 |
|
|
Patrick Uiterwijk |
9a7915 |
form = pagure.forms.ConfirmationForm()
|
|
Patrick Uiterwijk |
9a7915 |
if form.validate_on_submit():
|
|
Patrick Uiterwijk |
9b237b |
found = False
|
|
Patrick Uiterwijk |
9b237b |
for key in repo.deploykeys:
|
|
Patrick Uiterwijk |
9b237b |
if key.id == keyid:
|
|
Patrick Uiterwijk |
9b237b |
flask.g.session.delete(key)
|
|
Patrick Uiterwijk |
9b237b |
found = True
|
|
Patrick Uiterwijk |
9b237b |
break
|
|
Patrick Uiterwijk |
9a7915 |
|
|
Patrick Uiterwijk |
9b237b |
if not found:
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Deploy key does not exist in project.", "error")
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=repo.namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#deploykeys-tab"
|
|
Patrick Uiterwijk |
9a7915 |
)
|
|
Patrick Uiterwijk |
9a7915 |
|
|
Patrick Uiterwijk |
9a7915 |
try:
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
930073 |
pagure.lib.query.create_deploykeys_ssh_keys_on_disk(
|
|
Pierre-Yves Chibon |
9c2953 |
repo, pagure_config.get("GITOLITE_KEYDIR", None)
|
|
Patrick Uiterwijk |
9a7915 |
)
|
|
Slavek Kabrda |
f68223 |
pagure.lib.tasks.gitolite_post_compile_only.delay()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Deploy key removed")
|
|
Patrick Uiterwijk |
9a7915 |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
4635b5 |
_log.exception(err)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Deploy key could not be removed", "error")
|
|
Patrick Uiterwijk |
9a7915 |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#deploykey-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Patrick Uiterwijk |
9a7915 |
|
|
Patrick Uiterwijk |
9a7915 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/dropuser/<int:userid>", methods=["POST"])</int:userid></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/dropuser/<int:userid>", methods=["POST"])</int:userid></repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/dropuser/<int:userid>", methods=["POST"])</int:userid></repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/dropuser/<int:userid>",</int:userid></repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
methods=["POST"],
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
cf7f54 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
4501da |
def remove_user(repo, userid, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
681845 |
""" Remove the specified user from the project.
|
|
Pierre-Yves Chibon |
681845 |
"""
|
|
Vivek Anand |
58143d |
|
|
Pierre-Yves Chibon |
9c2953 |
if not pagure_config.get("ENABLE_USER_MNGT", True):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(
|
|
Pierre-Yves Chibon |
c6cc5c |
404,
|
|
Pierre-Yves Chibon |
c6cc5c |
description="User management not allowed in the pagure instance",
|
|
Pierre-Yves Chibon |
c6cc5c |
)
|
|
Vivek Anand |
58143d |
|
|
Pierre-Yves Chibon |
3119c6 |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
681845 |
|
|
Pierre-Yves Chibon |
fe5017 |
form = pagure.forms.ConfirmationForm()
|
|
Pierre-Yves Chibon |
a04944 |
delete_themselves = False
|
|
Pierre-Yves Chibon |
9dd7da |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
9dd7da |
try:
|
|
Pierre-Yves Chibon |
930073 |
user = pagure.lib.query.get_user_by_id(
|
|
Pierre-Yves Chibon |
930073 |
flask.g.session, int(userid)
|
|
Pierre-Yves Chibon |
930073 |
)
|
|
Pierre-Yves Chibon |
59005a |
delete_themselves = user.username == flask.g.fas_user.username
|
|
Pierre-Yves Chibon |
930073 |
msg = pagure.lib.query.remove_user_of_project(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session, user, repo, flask.g.fas_user.username
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
59005a |
flask.flash(msg)
|
|
Pierre-Yves Chibon |
9dd7da |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
4635b5 |
_log.exception(err)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("User could not be removed", "error")
|
|
Pierre-Yves Chibon |
59005a |
except pagure.exceptions.PagureException as err:
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("%s" % err, "error")
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=repo.namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#usersgroups-tab"
|
|
Pierre-Yves Chibon |
59005a |
)
|
|
Pierre-Yves Chibon |
e1b7ed |
|
|
Pierre-Yves Chibon |
9c2953 |
endpoint = "ui_ns.view_settings"
|
|
Pierre-Yves Chibon |
9c2953 |
tab = "#usersgroups-tab"
|
|
Pierre-Yves Chibon |
a04944 |
if delete_themselves:
|
|
Pierre-Yves Chibon |
9c2953 |
endpoint = "ui_ns.view_repo"
|
|
Pierre-Yves Chibon |
9c2953 |
tab = ""
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
endpoint, repo=repo.name, username=username, namespace=namespace
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ tab
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
|
|
Pierre-Yves Chibon |
9c2953 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/adddeploykey/", methods=("GET", "POST"))</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/adddeploykey", methods=("GET", "POST"))</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/adddeploykey/", methods=("GET", "POST"))</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/adddeploykey", methods=("GET", "POST"))</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/adddeploykey/", methods=("GET", "POST"))</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/adddeploykey", methods=("GET", "POST"))</repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/adddeploykey/",</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
methods=("GET", "POST"),
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/adddeploykey", methods=("GET", "POST")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Patrick Uiterwijk |
9a7915 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Patrick Uiterwijk |
9a7915 |
def add_deploykey(repo, username=None, namespace=None):
|
|
Patrick Uiterwijk |
9a7915 |
""" Add the specified deploy key to the project.
|
|
Patrick Uiterwijk |
9a7915 |
"""
|
|
Patrick Uiterwijk |
9a7915 |
|
|
Pierre-Yves Chibon |
9c2953 |
if not pagure_config.get("DEPLOY_KEY", True):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(
|
|
Pierre-Yves Chibon |
c6cc5c |
404, description="This pagure instance disabled deploy keys"
|
|
Pierre-Yves Chibon |
c6cc5c |
)
|
|
Pierre-Yves Chibon |
39f1dc |
|
|
Patrick Uiterwijk |
9a7915 |
repo = flask.g.repo
|
|
Patrick Uiterwijk |
9a7915 |
|
|
Patrick Uiterwijk |
9a7915 |
form = pagure.forms.AddDeployKeyForm()
|
|
Patrick Uiterwijk |
9a7915 |
|
|
Patrick Uiterwijk |
9a7915 |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
9efbd5 |
user = _get_user(username=flask.g.fas_user.username)
|
|
Patrick Uiterwijk |
9a7915 |
try:
|
|
Pierre-Yves Chibon |
930073 |
msg = pagure.lib.query.add_sshkey_to_project_or_user(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session,
|
|
Patrick Uiterwijk |
9a7915 |
ssh_key=form.ssh_key.data,
|
|
Pierre-Yves Chibon |
9efbd5 |
creator=user,
|
|
Patrick Uiterwijk |
9b237b |
project=repo,
|
|
Patrick Uiterwijk |
9a7915 |
pushaccess=form.pushaccess.data,
|
|
Patrick Uiterwijk |
9a7915 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
930073 |
pagure.lib.query.create_deploykeys_ssh_keys_on_disk(
|
|
Pierre-Yves Chibon |
9c2953 |
repo, pagure_config.get("GITOLITE_KEYDIR", None)
|
|
Patrick Uiterwijk |
9a7915 |
)
|
|
Slavek Kabrda |
f68223 |
pagure.lib.tasks.gitolite_post_compile_only.delay()
|
|
Patrick Uiterwijk |
9a7915 |
flask.flash(msg)
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#deploykey-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Patrick Uiterwijk |
9a7915 |
except pagure.exceptions.PagureException as msg:
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
d9dd52 |
_log.debug(msg)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash(str(msg), "error")
|
|
Patrick Uiterwijk |
9a7915 |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
4635b5 |
_log.exception(err)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Deploy key could not be added", "error")
|
|
Patrick Uiterwijk |
9a7915 |
|
|
Patrick Uiterwijk |
9a7915 |
return flask.render_template(
|
|
Pierre-Yves Chibon |
9c2953 |
"add_deploykey.html", form=form, username=username, repo=repo
|
|
Patrick Uiterwijk |
9a7915 |
)
|
|
Patrick Uiterwijk |
9a7915 |
|
|
Patrick Uiterwijk |
9a7915 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/adduser/", methods=("GET", "POST"))</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/adduser", methods=("GET", "POST"))</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/adduser/", methods=("GET", "POST"))</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/adduser", methods=("GET", "POST"))</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/adduser/", methods=("GET", "POST"))</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/adduser", methods=("GET", "POST"))</repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/adduser/", methods=("GET", "POST")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/adduser", methods=("GET", "POST")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
cf7f54 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
4501da |
def add_user(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
761495 |
""" Add the specified user to the project.
|
|
Pierre-Yves Chibon |
8782bc |
"""
|
|
Vivek Anand |
58143d |
|
|
Pierre-Yves Chibon |
9c2953 |
if not pagure_config.get("ENABLE_USER_MNGT", True):
|
|
Pierre-Yves Chibon |
53e4c2 |
flask.abort(
|
|
Pierre-Yves Chibon |
c6cc5c |
404,
|
|
Pierre-Yves Chibon |
c6cc5c |
description="User management is not allowed in this "
|
|
Pierre-Yves Chibon |
c6cc5c |
"pagure instance",
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
7be364 |
|
|
Pierre-Yves Chibon |
3119c6 |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
8782bc |
|
|
Pierre-Yves Chibon |
9c2953 |
user_to_update = flask.request.args.get("user", "").strip()
|
|
Vivek Anand |
963f9a |
user_to_update_obj = None
|
|
Vivek Anand |
5a7449 |
user_access = None
|
|
Vivek Anand |
963f9a |
if user_to_update:
|
|
Pierre-Yves Chibon |
930073 |
user_to_update_obj = pagure.lib.query.search_user(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session, username=user_to_update
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
930073 |
user_access = pagure.lib.query.get_obj_access(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session, repo, user_to_update_obj
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Vivek Anand |
963f9a |
|
|
Vivek Anand |
963f9a |
# The requested user is not found
|
|
Vivek Anand |
963f9a |
if user_to_update_obj is None:
|
|
Vivek Anand |
963f9a |
user_to_update = None
|
|
Vivek Anand |
5a7449 |
user_access = None
|
|
Vivek Anand |
963f9a |
|
|
Pierre-Yves Chibon |
fe5017 |
form = pagure.forms.AddUserForm()
|
|
Pierre-Yves Chibon |
8782bc |
|
|
Pierre-Yves Chibon |
8782bc |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
10f22f |
try:
|
|
Pierre-Yves Chibon |
930073 |
msg = pagure.lib.query.add_user_to_project(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session,
|
|
Pierre-Yves Chibon |
9c2953 |
repo,
|
|
Pierre-Yves Chibon |
ceb5d8 |
new_user=form.user.data,
|
|
Pierre-Yves Chibon |
ceb5d8 |
user=flask.g.fas_user.username,
|
|
Vivek Anand |
967335 |
access=form.access.data,
|
|
Pierre-Yves Chibon |
9c2953 |
required_groups=pagure_config.get("REQUIRED_GROUPS"),
|
|
Pierre-Yves Chibon |
ceb5d8 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
274e60 |
pagure.lib.git.generate_gitolite_acls(project=repo)
|
|
Pierre-Yves Chibon |
10f22f |
flask.flash(msg)
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#usersgroups-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
fe5017 |
except pagure.exceptions.PagureException as msg:
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
d9dd52 |
_log.debug(msg)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash(str(msg), "error")
|
|
Pierre-Yves Chibon |
5c5e6b |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
4635b5 |
_log.exception(err)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("User could not be added", "error")
|
|
Pierre-Yves Chibon |
8782bc |
|
|
Pierre-Yves Chibon |
930073 |
access_levels = pagure.lib.query.get_access_levels(flask.g.session)
|
|
Pierre-Yves Chibon |
8782bc |
return flask.render_template(
|
|
Pierre-Yves Chibon |
9c2953 |
"add_user.html",
|
|
Pierre-Yves Chibon |
8782bc |
form=form,
|
|
Pierre-Yves Chibon |
8782bc |
username=username,
|
|
Pierre-Yves Chibon |
8782bc |
repo=repo,
|
|
Vivek Anand |
967335 |
access_levels=access_levels,
|
|
Vivek Anand |
963f9a |
user_to_update=user_to_update,
|
|
Vivek Anand |
5a7449 |
user_access=user_access,
|
|
Pierre-Yves Chibon |
8782bc |
)
|
|
Pierre-Yves Chibon |
25c04d |
|
|
Pierre-Yves Chibon |
25c04d |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/dropgroup/<int:groupid>", methods=["POST"])</int:groupid></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/dropgroup/<int:groupid>", methods=["POST"])</int:groupid></repo></namespace>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<repo>/dropgroup/<int:groupid>", methods=["POST"]</int:groupid></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/dropgroup/<int:groupid>",</int:groupid></repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
methods=["POST"],
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
761d06 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
4501da |
def remove_group_project(repo, groupid, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
761d06 |
""" Remove the specified group from the project.
|
|
Pierre-Yves Chibon |
761d06 |
"""
|
|
Vivek Anand |
58143d |
|
|
Pierre-Yves Chibon |
9c2953 |
if not pagure_config.get("ENABLE_USER_MNGT", True):
|
|
Pierre-Yves Chibon |
53e4c2 |
flask.abort(
|
|
Pierre-Yves Chibon |
c6cc5c |
404,
|
|
Pierre-Yves Chibon |
c6cc5c |
description="User management is not allowed in this "
|
|
Pierre-Yves Chibon |
c6cc5c |
"pagure instance",
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Vivek Anand |
58143d |
|
|
Pierre-Yves Chibon |
3119c6 |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
761d06 |
|
|
Pierre-Yves Chibon |
761d06 |
form = pagure.forms.ConfirmationForm()
|
|
Pierre-Yves Chibon |
761d06 |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
761d06 |
grpids = [grp.id for grp in repo.groups]
|
|
Pierre-Yves Chibon |
761d06 |
|
|
Pierre-Yves Chibon |
761d06 |
if groupid not in grpids:
|
|
Pierre-Yves Chibon |
761d06 |
flask.flash(
|
|
Pierre-Yves Chibon |
9c2953 |
"Group does not seem to be part of this project", "error"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#usersgroups-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
761d06 |
|
|
Pierre-Yves Chibon |
761d06 |
for grp in repo.groups:
|
|
Pierre-Yves Chibon |
761d06 |
if grp.id == groupid:
|
|
Pierre-Yves Chibon |
761d06 |
repo.groups.remove(grp)
|
|
Pierre-Yves Chibon |
761d06 |
break
|
|
Pierre-Yves Chibon |
761d06 |
try:
|
|
Vivek Anand |
9888e8 |
# Mark the project as read_only, celery will unmark it
|
|
Pierre-Yves Chibon |
930073 |
pagure.lib.query.update_read_only_mode(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session, repo, read_only=True
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
274e60 |
pagure.lib.git.generate_gitolite_acls(project=repo)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Group removed")
|
|
Pierre-Yves Chibon |
761d06 |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
4635b5 |
_log.exception(err)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Group could not be removed", "error")
|
|
Pierre-Yves Chibon |
761d06 |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#usersgroups-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
761d06 |
|
|
Pierre-Yves Chibon |
761d06 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/addgroup/", methods=("GET", "POST"))</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/addgroup", methods=("GET", "POST"))</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/addgroup/", methods=("GET", "POST"))</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/addgroup", methods=("GET", "POST"))</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/addgroup/", methods=("GET", "POST"))</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/addgroup", methods=("GET", "POST"))</repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/addgroup/", methods=("GET", "POST")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/addgroup", methods=("GET", "POST")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
cf7f54 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
4501da |
def add_group_project(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
761495 |
""" Add the specified group to the project.
|
|
Pierre-Yves Chibon |
2e56e5 |
"""
|
|
Vivek Anand |
58143d |
|
|
Pierre-Yves Chibon |
9c2953 |
if not pagure_config.get("ENABLE_USER_MNGT", True):
|
|
Pierre-Yves Chibon |
53e4c2 |
flask.abort(
|
|
Pierre-Yves Chibon |
c6cc5c |
404,
|
|
Pierre-Yves Chibon |
c6cc5c |
description="User management is not allowed in this "
|
|
Pierre-Yves Chibon |
c6cc5c |
"pagure instance",
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
7be364 |
|
|
Pierre-Yves Chibon |
3119c6 |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
2e56e5 |
|
|
Pierre-Yves Chibon |
9c2953 |
group_to_update = flask.request.args.get("group", "").strip()
|
|
Vivek Anand |
963f9a |
group_to_update_obj = None
|
|
Vivek Anand |
5a7449 |
group_access = None
|
|
Vivek Anand |
963f9a |
if group_to_update:
|
|
Pierre-Yves Chibon |
930073 |
group_to_update_obj = pagure.lib.query.search_groups(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session, group_name=group_to_update
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
930073 |
group_access = pagure.lib.query.get_obj_access(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session, repo, group_to_update_obj
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Vivek Anand |
963f9a |
|
|
Vivek Anand |
963f9a |
# The requested group is not found
|
|
Vivek Anand |
963f9a |
if group_to_update_obj is None:
|
|
Vivek Anand |
963f9a |
group_to_update = None
|
|
Vivek Anand |
5a7449 |
group_access = None
|
|
Vivek Anand |
963f9a |
|
|
Pierre-Yves Chibon |
2e56e5 |
form = pagure.forms.AddGroupForm()
|
|
Pierre-Yves Chibon |
2e56e5 |
|
|
Pierre-Yves Chibon |
2e56e5 |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
2e56e5 |
try:
|
|
Pierre-Yves Chibon |
930073 |
msg = pagure.lib.query.add_group_to_project(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session,
|
|
Pierre-Yves Chibon |
9c2953 |
repo,
|
|
Pierre-Yves Chibon |
2e56e5 |
new_group=form.group.data,
|
|
Pierre-Yves Chibon |
2e56e5 |
user=flask.g.fas_user.username,
|
|
Vivek Anand |
967335 |
access=form.access.data,
|
|
Pierre-Yves Chibon |
9c2953 |
create=pagure_config.get("ENABLE_GROUP_MNGT", False),
|
|
Pierre-Yves Chibon |
b130e5 |
is_admin=pagure.utils.is_admin(),
|
|
Pierre-Yves Chibon |
2e56e5 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
274e60 |
pagure.lib.git.generate_gitolite_acls(project=repo)
|
|
Pierre-Yves Chibon |
2e56e5 |
flask.flash(msg)
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#usersgroups-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
2e56e5 |
except pagure.exceptions.PagureException as msg:
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
d9dd52 |
_log.debug(msg)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash(str(msg), "error")
|
|
Pierre-Yves Chibon |
2e56e5 |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
4635b5 |
_log.exception(err)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Group could not be added", "error")
|
|
Pierre-Yves Chibon |
2e56e5 |
|
|
Pierre-Yves Chibon |
930073 |
access_levels = pagure.lib.query.get_access_levels(flask.g.session)
|
|
Pierre-Yves Chibon |
2e56e5 |
return flask.render_template(
|
|
Pierre-Yves Chibon |
9c2953 |
"add_group_project.html",
|
|
Pierre-Yves Chibon |
2e56e5 |
form=form,
|
|
Pierre-Yves Chibon |
2e56e5 |
username=username,
|
|
Pierre-Yves Chibon |
2e56e5 |
repo=repo,
|
|
Vivek Anand |
967335 |
access_levels=access_levels,
|
|
Vivek Anand |
963f9a |
group_to_update=group_to_update,
|
|
Vivek Anand |
5a7449 |
group_access=group_access,
|
|
Pierre-Yves Chibon |
2e56e5 |
)
|
|
Pierre-Yves Chibon |
2e56e5 |
|
|
Pierre-Yves Chibon |
2e56e5 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/regenerate", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/regenerate", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/regenerate", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/regenerate", methods=["POST"]</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
cf7f54 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
4501da |
def regenerate_git(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
25c04d |
""" Regenerate the specified git repo with the content in the project.
|
|
Pierre-Yves Chibon |
25c04d |
"""
|
|
Pierre-Yves Chibon |
25c04d |
|
|
Pierre-Yves Chibon |
74dadb |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
25c04d |
|
|
Pierre-Yves Chibon |
9c2953 |
regenerate = flask.request.form.get("regenerate")
|
|
Pierre-Yves Chibon |
9c2953 |
if not regenerate or regenerate.lower() not in ["tickets", "requests"]:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(
|
|
Pierre-Yves Chibon |
c6cc5c |
400,
|
|
Pierre-Yves Chibon |
c6cc5c |
description="You can only regenerate tickest or requests repos",
|
|
Pierre-Yves Chibon |
c6cc5c |
)
|
|
Pierre-Yves Chibon |
25c04d |
|
|
Pierre-Yves Chibon |
25c04d |
form = pagure.forms.ConfirmationForm()
|
|
Pierre-Yves Chibon |
25c04d |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
9c2953 |
if regenerate.lower() == "requests" and repo.settings.get(
|
|
Pierre-Yves Chibon |
9c2953 |
"pull_requests"
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Vivek Anand |
8ced04 |
|
|
Vivek Anand |
8ced04 |
# delete the requests repo and reinit
|
|
Vivek Anand |
8ced04 |
# in case there are no requests
|
|
Vivek Anand |
8ced04 |
if len(repo.requests) == 0:
|
|
Vivek Anand |
8ced04 |
pagure.lib.git.reinit_git(
|
|
Pierre-Yves Chibon |
9c2953 |
project=repo, repofolder=pagure_config["REQUESTS_FOLDER"]
|
|
Vivek Anand |
8ced04 |
)
|
|
Pierre-Yves Chibon |
25c04d |
for request in repo.requests:
|
|
Pierre-Yves Chibon |
25c04d |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
9c2953 |
request,
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo,
|
|
Pierre-Yves Chibon |
9c2953 |
repofolder=pagure_config["REQUESTS_FOLDER"],
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Requests git repo updated")
|
|
Pierre-Yves Chibon |
b8f582 |
|
|
Pierre-Yves Chibon |
9c2953 |
elif (
|
|
Pierre-Yves Chibon |
9c2953 |
regenerate.lower() == "tickets"
|
|
Pierre-Yves Chibon |
9c2953 |
and repo.settings.get("issue_tracker")
|
|
Pierre-Yves Chibon |
9c2953 |
and pagure_config.get("ENABLE_TICKETS")
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Vivek Anand |
8ced04 |
|
|
Vivek Anand |
8ced04 |
# delete the ticket repo and reinit
|
|
Vivek Anand |
8ced04 |
# in case there are no tickets
|
|
Vivek Anand |
8ced04 |
if len(repo.issues) == 0:
|
|
Vivek Anand |
8ced04 |
pagure.lib.git.reinit_git(
|
|
Pierre-Yves Chibon |
9c2953 |
project=repo, repofolder=pagure_config["TICKETS_FOLDER"]
|
|
Vivek Anand |
8ced04 |
)
|
|
Pierre-Yves Chibon |
25c04d |
for ticket in repo.issues:
|
|
Pierre-Yves Chibon |
25c04d |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
9c2953 |
ticket,
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo,
|
|
Pierre-Yves Chibon |
9c2953 |
repofolder=pagure_config["TICKETS_FOLDER"],
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Tickets git repo updated")
|
|
Pierre-Yves Chibon |
25c04d |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#regen-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
110198 |
|
|
Pierre-Yves Chibon |
110198 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/token/new/", methods=("GET", "POST"))</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/token/new", methods=("GET", "POST"))</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/token/new/", methods=("GET", "POST"))</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/token/new", methods=("GET", "POST"))</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/token/new/", methods=("GET", "POST"))</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/token/new", methods=("GET", "POST"))</repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/token/new/", methods=("GET", "POST")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/token/new", methods=("GET", "POST")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
cf7f54 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Pierre-Yves Chibon |
4501da |
def add_token(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
110198 |
""" Add a token to a specified project.
|
|
Pierre-Yves Chibon |
110198 |
"""
|
|
Pierre-Yves Chibon |
110198 |
|
|
Pierre-Yves Chibon |
16572e |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
110198 |
|
|
Vivek Anand |
967335 |
if not flask.g.repo_committer:
|
|
Pierre-Yves Chibon |
0ae8d3 |
flask.abort(
|
|
Pierre-Yves Chibon |
c6cc5c |
403,
|
|
Pierre-Yves Chibon |
c6cc5c |
description="You are not allowed to change the settings for "
|
|
Pierre-Yves Chibon |
c6cc5c |
"this project",
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
0ae8d3 |
|
|
Pierre-Yves Chibon |
930073 |
acls = pagure.lib.query.get_acls(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session, restrict=pagure_config.get("USER_ACLS")
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
110198 |
form = pagure.forms.NewTokenForm(acls=acls)
|
|
Pierre-Yves Chibon |
110198 |
|
|
Pierre-Yves Chibon |
110198 |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
110198 |
try:
|
|
Pierre-Yves Chibon |
696f19 |
pagure.lib.query.add_token_to_user(
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session,
|
|
Pierre-Yves Chibon |
110198 |
repo,
|
|
Pierre-Yves Chibon |
60a786 |
description=form.description.data.strip() or None,
|
|
Pierre-Yves Chibon |
110198 |
acls=form.acls.data,
|
|
Pierre-Yves Chibon |
110198 |
username=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
110198 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
696f19 |
flask.flash("Token created")
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#apikeys-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
110198 |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
4635b5 |
_log.exception(err)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("API token could not be added", "error")
|
|
Pierre-Yves Chibon |
110198 |
|
|
Pradeep CE (cep) |
9d305f |
# When form is displayed after an empty submission, show an error.
|
|
Pierre-Yves Chibon |
9c2953 |
if form.errors.get("acls"):
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("You must select at least one permission.", "error")
|
|
Pradeep CE (cep) |
9d305f |
|
|
Pierre-Yves Chibon |
110198 |
return flask.render_template(
|
|
Pierre-Yves Chibon |
9c2953 |
"add_token.html",
|
|
Pierre-Yves Chibon |
9c2953 |
select="settings",
|
|
Pierre-Yves Chibon |
110198 |
form=form,
|
|
Pierre-Yves Chibon |
110198 |
acls=acls,
|
|
Pierre-Yves Chibon |
110198 |
username=username,
|
|
Pierre-Yves Chibon |
110198 |
repo=repo,
|
|
Pierre-Yves Chibon |
110198 |
)
|
|
Pierre-Yves Chibon |
e649cf |
|
|
Pierre-Yves Chibon |
e649cf |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/token/renew/<token_id>", methods=["POST"])</token_id></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/token/renew/<token_id>", methods=["POST"])</token_id></repo></namespace>
|
|
Pierre-Yves Chibon |
c8e85f |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<repo>/token/renew/<token_id>", methods=["POST"]</token_id></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
c8e85f |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/token/renew/<token_id>",</token_id></repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
methods=["POST"],
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
c8e85f |
@login_required
|
|
Pierre-Yves Chibon |
c8e85f |
@is_admin_sess_timedout
|
|
Pierre-Yves Chibon |
c8e85f |
@is_repo_admin
|
|
Pierre-Yves Chibon |
c8e85f |
def renew_api_token(repo, token_id, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
c8e85f |
""" Renew a token to a specified project.
|
|
Pierre-Yves Chibon |
c8e85f |
"""
|
|
Pierre-Yves Chibon |
c8e85f |
|
|
Pierre-Yves Chibon |
c8e85f |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
c8e85f |
|
|
Pierre-Yves Chibon |
930073 |
token = pagure.lib.query.get_api_token(flask.g.session, token_id)
|
|
Pierre-Yves Chibon |
c8e85f |
|
|
Pierre-Yves Chibon |
9c2953 |
if (
|
|
Pierre-Yves Chibon |
9c2953 |
not token
|
|
Pierre-Yves Chibon |
9c2953 |
or token.project.fullname != repo.fullname
|
|
Pierre-Yves Chibon |
9c2953 |
or token.user.username != flask.g.fas_user.username
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Token not found")
|
|
Pierre-Yves Chibon |
c8e85f |
|
|
Pierre-Yves Chibon |
c8e85f |
form = pagure.forms.ConfirmationForm()
|
|
Pierre-Yves Chibon |
c8e85f |
|
|
Pierre-Yves Chibon |
c8e85f |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
c8e85f |
acls = [acl.name for acl in token.acls]
|
|
Pierre-Yves Chibon |
c8e85f |
try:
|
|
Pierre-Yves Chibon |
696f19 |
pagure.lib.query.add_token_to_user(
|
|
Pierre-Yves Chibon |
c8e85f |
flask.g.session,
|
|
Pierre-Yves Chibon |
c8e85f |
repo,
|
|
Pierre-Yves Chibon |
c8e85f |
description=token.description or None,
|
|
Pierre-Yves Chibon |
c8e85f |
acls=acls,
|
|
Pierre-Yves Chibon |
c8e85f |
username=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
c8e85f |
)
|
|
Pierre-Yves Chibon |
c8e85f |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
696f19 |
flask.flash("Token created")
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#apikeys-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
c8e85f |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
c8e85f |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
c8e85f |
_log.exception(err)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("API token could not be renewed", "error")
|
|
Pierre-Yves Chibon |
c8e85f |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#apikeys-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
c8e85f |
|
|
Pierre-Yves Chibon |
c8e85f |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/token/revoke/<token_id>", methods=["POST"])</token_id></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/token/revoke/<token_id>", methods=["POST"])</token_id></repo></namespace>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<repo>/token/revoke/<token_id>", methods=["POST"]</token_id></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/token/revoke/<token_id>",</token_id></repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
methods=["POST"],
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
cf7f54 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
4501da |
def revoke_api_token(repo, token_id, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
e649cf |
""" Revokie a token to a specified project.
|
|
Pierre-Yves Chibon |
e649cf |
"""
|
|
Pierre-Yves Chibon |
e649cf |
|
|
Pierre-Yves Chibon |
16572e |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
e649cf |
|
|
Pierre-Yves Chibon |
930073 |
token = pagure.lib.query.get_api_token(flask.g.session, token_id)
|
|
Pierre-Yves Chibon |
e649cf |
|
|
Pierre-Yves Chibon |
9c2953 |
if (
|
|
Pierre-Yves Chibon |
9c2953 |
not token
|
|
Pierre-Yves Chibon |
9c2953 |
or token.project.fullname != repo.fullname
|
|
Pierre-Yves Chibon |
9c2953 |
or token.user.username != flask.g.fas_user.username
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Token not found")
|
|
Pierre-Yves Chibon |
e649cf |
|
|
Pierre-Yves Chibon |
e649cf |
form = pagure.forms.ConfirmationForm()
|
|
Pierre-Yves Chibon |
e649cf |
|
|
Pierre-Yves Chibon |
e649cf |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
e649cf |
try:
|
|
Pierre-Yves Chibon |
e3dee7 |
if token.expiration >= datetime.datetime.utcnow():
|
|
Pierre-Yves Chibon |
e3dee7 |
token.expiration = datetime.datetime.utcnow()
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.add(token)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Token revoked")
|
|
Pierre-Yves Chibon |
e649cf |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
4635b5 |
_log.exception(err)
|
|
Mary Kate Fain |
a16918 |
message = flask.Markup(
|
|
Mary Kate Fain |
a16918 |
"Token could not be revoked,"
|
|
Mary Kate Fain |
a16918 |
' please contact an administrator'
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Mary Kate Fain |
a16918 |
flask.flash(message, "error")
|
|
Pierre-Yves Chibon |
e649cf |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#apikeys-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
7ff840 |
|
|
Pierre-Yves Chibon |
7ff840 |
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/<repo>/edit/<path:branchname>/f/<path:filename>", methods=("GET", "POST")</path:filename></path:branchname></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/<namespace>/<repo>/edit/<path:branchname>/f/<path:filename>",</path:filename></path:branchname></repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
methods=("GET", "POST"),
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<repo>/edit/<path:branchname>/f/<path:filename>",</path:filename></path:branchname></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
methods=("GET", "POST"),
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/edit/<path:branchname>/f/"</path:branchname></repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
"<path:filename>",</path:filename>
|
|
Pierre-Yves Chibon |
9c2953 |
methods=("GET", "POST"),
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
cf7f54 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
4501da |
def edit_file(repo, branchname, filename, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
7ff840 |
""" Edit a file online.
|
|
Pierre-Yves Chibon |
7ff840 |
"""
|
|
Pierre-Yves Chibon |
16572e |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
16572e |
repo_obj = flask.g.repo_obj
|
|
Pierre-Yves Chibon |
7ff840 |
|
|
Pierre-Yves Chibon |
930073 |
user = pagure.lib.query.search_user(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session, username=flask.g.fas_user.username
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
383b8e |
|
|
Pierre-Yves Chibon |
7ff840 |
if repo_obj.is_empty:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Empty repo cannot have a file")
|
|
Pierre-Yves Chibon |
7ff840 |
|
|
Pierre-Yves Chibon |
d3f55d |
form = pagure.forms.EditFileForm(emails=user.emails)
|
|
Pierre-Yves Chibon |
d3f55d |
|
|
Pierre-Yves Chibon |
7ff840 |
branch = None
|
|
Pierre-Yves Chibon |
7ff840 |
if branchname in repo_obj.listall_branches():
|
|
Pierre-Yves Chibon |
7ff840 |
branch = repo_obj.lookup_branch(branchname)
|
|
Pierre-Yves Chibon |
91cec1 |
commit = branch.peel(pygit2.Commit)
|
|
Pierre-Yves Chibon |
7ff840 |
else:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(400, description="Invalid branch specified")
|
|
Pierre-Yves Chibon |
7ff840 |
|
|
Pierre-Yves Chibon |
7ff840 |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
7ff840 |
try:
|
|
Aurélien Bompard |
a7f281 |
task = pagure.lib.tasks.update_file_in_git.delay(
|
|
Patrick Uiterwijk |
8cb224 |
repo.name,
|
|
Patrick Uiterwijk |
8cb224 |
repo.namespace,
|
|
Patrick Uiterwijk |
fb0175 |
repo.user.username if repo.is_fork else None,
|
|
Pierre-Yves Chibon |
7ff840 |
branch=branchname,
|
|
Pierre-Yves Chibon |
d3f55d |
branchto=form.branch.data,
|
|
Pierre-Yves Chibon |
7ff840 |
filename=filename,
|
|
Pierre-Yves Chibon |
7ff840 |
content=form.content.data,
|
|
Pierre-Yves Chibon |
9c2953 |
message="%s\n\n%s"
|
|
Pierre-Yves Chibon |
9c2953 |
% (
|
|
Pierre-Yves Chibon |
7ff840 |
form.commit_title.data.strip(),
|
|
Pierre-Yves Chibon |
9c2953 |
form.commit_message.data.strip(),
|
|
Pierre-Yves Chibon |
7ff840 |
),
|
|
Pierre-Yves Chibon |
715218 |
username=user.username,
|
|
Pierre-Yves Chibon |
383b8e |
email=form.email.data,
|
|
Aurélien Bompard |
a7f281 |
)
|
|
Aurélien Bompard |
a7f281 |
return pagure.utils.wait_for_task(task)
|
|
Pierre-Yves Chibon |
7ff840 |
except pagure.exceptions.PagureException as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
4635b5 |
_log.exception(err)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Commit could not be done", "error")
|
|
Pierre-Yves Chibon |
7ff840 |
data = form.content.data
|
|
Pierre-Yves Chibon |
9c2953 |
elif flask.request.method == "GET":
|
|
Pierre-Yves Chibon |
4148e0 |
form.email.data = user.default_email
|
|
Pierre-Yves Chibon |
7ff840 |
content = __get_file_in_tree(
|
|
Pierre-Yves Chibon |
9c2953 |
repo_obj, commit.tree, filename.split("/")
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
7ff840 |
if not content or isinstance(content, pygit2.Tree):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="File not found")
|
|
Pierre-Yves Chibon |
3836a7 |
|
|
Pierre-Yves Chibon |
801c6f |
if is_binary_string(content.data):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(400, description="Cannot edit binary files")
|
|
Pierre-Yves Chibon |
03b973 |
|
|
Pierre-Yves Chibon |
a443ef |
try:
|
|
Pierre-Yves Chibon |
9c2953 |
data = repo_obj[content.oid].data.decode("utf-8")
|
|
Pierre-Yves Chibon |
a443ef |
except UnicodeDecodeError: # pragma: no cover
|
|
Pierre-Yves Chibon |
a443ef |
# In theory we shouldn't reach here since we check if the file
|
|
Pierre-Yves Chibon |
a443ef |
# is binary with `is_binary_string()` above
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(400, description="Cannot edit binary files")
|
|
Pierre-Yves Chibon |
a443ef |
|
|
Pierre-Yves Chibon |
7ff840 |
else:
|
|
Aurélien Bompard |
831553 |
data = form.content.data
|
|
Aurélien Bompard |
619e2a |
if not isinstance(data, six.text_type):
|
|
Pierre-Yves Chibon |
9c2953 |
data = data.decode("utf-8")
|
|
Pierre-Yves Chibon |
7ff840 |
|
|
Pierre-Yves Chibon |
7ff840 |
return flask.render_template(
|
|
Pierre-Yves Chibon |
9c2953 |
"edit_file.html",
|
|
Pierre-Yves Chibon |
9c2953 |
select="tree",
|
|
Pierre-Yves Chibon |
7ff840 |
repo=repo,
|
|
Pierre-Yves Chibon |
7ff840 |
username=username,
|
|
Pierre-Yves Chibon |
7ff840 |
branchname=branchname,
|
|
Pierre-Yves Chibon |
7ff840 |
data=data,
|
|
Pierre-Yves Chibon |
7ff840 |
filename=filename,
|
|
Pierre-Yves Chibon |
7ff840 |
form=form,
|
|
Pierre-Yves Chibon |
383b8e |
user=user,
|
|
Pierre-Yves Chibon |
7ff840 |
)
|
|
Pierre-Yves Chibon |
a541e0 |
|
|
Pierre-Yves Chibon |
a541e0 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/b/<path:branchname>/delete", methods=["POST"])</path:branchname></repo>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/<namespace>/<repo>/b/<path:branchname>/delete", methods=["POST"]</path:branchname></repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<repo>/b/<path:branchname>/delete", methods=["POST"]</path:branchname></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/b/<path:branchname>/delete",</path:branchname></repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
methods=["POST"],
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
cf7f54 |
@login_required
|
|
Pierre-Yves Chibon |
4501da |
def delete_branch(repo, branchname, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
a541e0 |
""" Delete the branch of a project.
|
|
Pierre-Yves Chibon |
a541e0 |
"""
|
|
Pierre-Yves Chibon |
9c2953 |
if not flask.g.repo.is_fork and not pagure_config.get(
|
|
Pierre-Yves Chibon |
9c2953 |
"ALLOW_DELETE_BRANCH", True
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(
|
|
Pierre-Yves Chibon |
c6cc5c |
404,
|
|
Pierre-Yves Chibon |
c6cc5c |
description="This pagure instance does not allow branch deletion",
|
|
Pierre-Yves Chibon |
c6cc5c |
)
|
|
Pierre-Yves Chibon |
1ee8ed |
|
|
Pierre-Yves Chibon |
16572e |
repo_obj = flask.g.repo_obj
|
|
Pierre-Yves Chibon |
a541e0 |
|
|
Vivek Anand |
967335 |
if not flask.g.repo_committer:
|
|
Pierre-Yves Chibon |
a541e0 |
flask.abort(
|
|
Pierre-Yves Chibon |
c6cc5c |
403,
|
|
Pierre-Yves Chibon |
c6cc5c |
description="You are not allowed to delete branch for "
|
|
Pierre-Yves Chibon |
c6cc5c |
"this project",
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
a541e0 |
|
|
Pierre-Yves Chibon |
5aa4e8 |
if six.PY2:
|
|
Pierre-Yves Chibon |
5aa4e8 |
branchname = branchname.encode("utf-8")
|
|
Pierre-Yves Chibon |
5aa4e8 |
|
|
Pierre-Yves Chibon |
9c2953 |
if branchname == "master":
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(
|
|
Pierre-Yves Chibon |
c6cc5c |
403, description="You are not allowed to delete the master branch"
|
|
Pierre-Yves Chibon |
c6cc5c |
)
|
|
Pierre-Yves Chibon |
a541e0 |
|
|
Pierre-Yves Chibon |
16572e |
if branchname not in repo_obj.listall_branches():
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Branch not found")
|
|
Pierre-Yves Chibon |
a541e0 |
|
|
Pierre-Yves Chibon |
9c2953 |
task = pagure.lib.tasks.delete_branch.delay(
|
|
Pierre-Yves Chibon |
9c2953 |
repo, namespace, username, branchname
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Aurélien Bompard |
a7f281 |
return pagure.utils.wait_for_task(task)
|
|
Pierre-Yves Chibon |
4501da |
|
|
Pierre-Yves Chibon |
4501da |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/docs/<repo>/")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/docs/<repo>/<path:filename>")</path:filename></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/docs/<namespace>/<repo>/")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/docs/<namespace>/<repo>/<path:filename>")</path:filename></repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/docs/fork/<username>/<repo>/")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/docs/fork/<username>/<namespace>/<repo>/<path:filename>")</path:filename></repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/docs/fork/<username>/<repo>/")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/docs/fork/<username>/<namespace>/<repo>/<path:filename>")</path:filename></repo></namespace></username>
|
|
Pierre-Yves Chibon |
4501da |
def view_docs(repo, username=None, filename=None, namespace=None):
|
|
Pierre-Yves Chibon |
4699f0 |
""" Display the documentation
|
|
Pierre-Yves Chibon |
4699f0 |
"""
|
|
Pierre-Yves Chibon |
45aebf |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
0171c3 |
|
|
Pierre-Yves Chibon |
9c2953 |
if not pagure_config.get("DOC_APP_URL"):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="This pagure instance has no doc server")
|
|
Pierre-Yves Chibon |
39a3da |
|
|
Pierre-Yves Chibon |
4699f0 |
return flask.render_template(
|
|
Pierre-Yves Chibon |
9c2953 |
"docs.html",
|
|
Pierre-Yves Chibon |
9c2953 |
select="docs",
|
|
Pierre-Yves Chibon |
45aebf |
repo=repo,
|
|
Pierre-Yves Chibon |
4699f0 |
username=username,
|
|
Pierre-Yves Chibon |
4699f0 |
filename=filename,
|
|
Pierre-Yves Chibon |
9c2953 |
endpoint="view_docs",
|
|
Pierre-Yves Chibon |
4699f0 |
)
|
|
Ryan Lerch |
1ee5ad |
|
|
Pierre-Yves Chibon |
0fcf17 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/activity/")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/activity")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/activity/")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/activity")</repo></namespace>
|
|
Pierre-Yves Chibon |
4501da |
def view_project_activity(repo, namespace=None):
|
|
Ryan Lerch |
8eb9dd |
""" Display the activity feed
|
|
Ryan Lerch |
1ee5ad |
"""
|
|
Ryan Lerch |
8eb9dd |
|
|
Pierre-Yves Chibon |
9c2953 |
if not pagure_config.get("DATAGREPPER_URL"):
|
|
Ryan Lerch |
8eb9dd |
flask.abort(404)
|
|
Ryan Lerch |
8eb9dd |
|
|
Pierre-Yves Chibon |
45aebf |
repo = flask.g.repo
|
|
Ryan Lerch |
1ee5ad |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.render_template("activity.html", repo=repo)
|
|
Gaurav Kumar |
00f2c8 |
|
|
Pierre-Yves Chibon |
0fcf17 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/stargazers/")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/stargazers/")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/stargazers/")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/stargazers/")</repo></namespace></username>
|
|
Vivek Anand |
f019f5 |
def view_stargazers(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
9c2953 |
""" View all the users who have starred the project """
|
|
Vivek Anand |
f019f5 |
|
|
Vivek Anand |
f019f5 |
stargazers = flask.g.repo.stargazers
|
|
Vivek Anand |
f019f5 |
users = [star.user for star in stargazers]
|
|
Vivek Anand |
f019f5 |
return flask.render_template(
|
|
Ryan Lerch |
e360a1 |
"repo_stargazers.html",
|
|
Ryan Lerch |
e360a1 |
repo=flask.g.repo,
|
|
Ryan Lerch |
e360a1 |
username=username,
|
|
Ryan Lerch |
e360a1 |
namespace=namespace,
|
|
Patrick Uiterwijk |
3f97f6 |
users=users,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Vivek Anand |
f019f5 |
|
|
Vivek Anand |
f019f5 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/star/<star>", methods=["POST"])</star></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/star/<star>", methods=["POST"])</star></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/star/<star>", methods=["POST"])</star></repo></namespace>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/star/<star>", methods=["POST"]</star></repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Vivek Anand |
f019f5 |
@login_required
|
|
Vivek Anand |
f019f5 |
def star_project(repo, star, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
9c2953 |
""" Star or Unstar a project
|
|
Vivek Anand |
bd4dd9 |
|
|
Vivek Anand |
bd4dd9 |
:arg repo: string representing the project which has to be starred or
|
|
Vivek Anand |
bd4dd9 |
unstarred.
|
|
Vivek Anand |
bd4dd9 |
:arg star: either '0' or '1' for unstar and star respectively
|
|
Vivek Anand |
bd4dd9 |
:arg username: string representing the user the fork of whose is being
|
|
Vivek Anand |
bd4dd9 |
starred or unstarred.
|
|
Vivek Anand |
bd4dd9 |
:arg namespace: namespace of the project if any
|
|
Pierre-Yves Chibon |
9c2953 |
"""
|
|
Vivek Anand |
f019f5 |
|
|
Pierre-Yves Chibon |
9c2953 |
return_point = flask.url_for("ui_ns.index")
|
|
Pierre-Yves Chibon |
9c2953 |
if flask.request.referrer is not None and pagure.utils.is_safe_url(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.request.referrer
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Vivek Anand |
f019f5 |
return_point = flask.request.referrer
|
|
Vivek Anand |
f019f5 |
|
|
Vivek Anand |
f019f5 |
form = pagure.forms.ConfirmationForm()
|
|
Vivek Anand |
f019f5 |
if not form.validate_on_submit():
|
|
Vivek Anand |
f019f5 |
flask.abort(400)
|
|
Vivek Anand |
f019f5 |
|
|
Pierre-Yves Chibon |
9c2953 |
if star not in ["0", "1"]:
|
|
Vivek Anand |
f019f5 |
flask.abort(400)
|
|
Vivek Anand |
f019f5 |
|
|
Vivek Anand |
f019f5 |
try:
|
|
Pierre-Yves Chibon |
930073 |
msg = pagure.lib.query.update_star_project(
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session,
|
|
Vivek Anand |
f019f5 |
user=flask.g.fas_user.username,
|
|
Vivek Anand |
f019f5 |
repo=flask.g.repo,
|
|
Vivek Anand |
f019f5 |
star=star,
|
|
Vivek Anand |
f019f5 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Vivek Anand |
f019f5 |
flask.flash(msg)
|
|
Vivek Anand |
f019f5 |
except SQLAlchemyError:
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Could not star the project")
|
|
Vivek Anand |
f019f5 |
|
|
Vivek Anand |
f019f5 |
return flask.redirect(return_point)
|
|
Vivek Anand |
f019f5 |
|
|
Vivek Anand |
f019f5 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/watch/settings/<watch>", methods=["POST"])</watch></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/watch/settings/<watch>", methods=["POST"])</watch></repo></namespace>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<repo>/watch/settings/<watch>", methods=["POST"]</watch></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/watch/settings/<watch>",</watch></repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
methods=["POST"],
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Gaurav Kumar |
c65751 |
@login_required
|
|
Pierre-Yves Chibon |
4501da |
def watch_repo(repo, watch, username=None, namespace=None):
|
|
Matt Prahl |
b49f93 |
""" Marked for watching or unwatching
|
|
Gaurav Kumar |
00f2c8 |
"""
|
|
Pierre-Yves Chibon |
4501da |
|
|
Pierre-Yves Chibon |
9c2953 |
return_point = flask.url_for("ui_ns.index")
|
|
Pierre-Yves Chibon |
b130e5 |
if pagure.utils.is_safe_url(flask.request.referrer):
|
|
Gaurav Kumar |
604af6 |
return_point = flask.request.referrer
|
|
Gaurav Kumar |
00f2c8 |
|
|
Gaurav Kumar |
604af6 |
form = pagure.forms.ConfirmationForm()
|
|
Gaurav Kumar |
604af6 |
if not form.validate_on_submit():
|
|
Gaurav Kumar |
604af6 |
flask.abort(400)
|
|
Gaurav Kumar |
00f2c8 |
|
|
Pierre-Yves Chibon |
9c2953 |
if "%s" % watch not in ["0", "1", "2", "3", "-1"]:
|
|
Gaurav Kumar |
604af6 |
flask.abort(400)
|
|
Gaurav Kumar |
604af6 |
|
|
Gaurav Kumar |
604af6 |
try:
|
|
Pierre-Yves Chibon |
930073 |
msg = pagure.lib.query.update_watch_status(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session, flask.g.repo, flask.g.fas_user.username, watch
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Gaurav Kumar |
604af6 |
flask.flash(msg)
|
|
Gaurav Kumar |
604af6 |
except pagure.exceptions.PagureException as msg:
|
|
Pierre-Yves Chibon |
d9dd52 |
_log.debug(msg)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash(str(msg), "error")
|
|
Gaurav Kumar |
00f2c8 |
|
|
Gaurav Kumar |
604af6 |
return flask.redirect(return_point)
|
|
Pierre-Yves Chibon |
080c15 |
|
|
Pierre-Yves Chibon |
080c15 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/update/public_notif", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/public_notif", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/public_notif", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/public_notif", methods=["POST"]</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
080c15 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
080c15 |
def update_public_notifications(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
080c15 |
""" Update the public notification settings of a project.
|
|
Pierre-Yves Chibon |
080c15 |
"""
|
|
Pierre-Yves Chibon |
080c15 |
|
|
Pierre-Yves Chibon |
080c15 |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
080c15 |
|
|
Pierre-Yves Chibon |
080c15 |
form = pagure.forms.PublicNotificationForm()
|
|
Pierre-Yves Chibon |
080c15 |
|
|
Pierre-Yves Chibon |
080c15 |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
080c15 |
issue_notifs = [
|
|
Pierre-Yves Chibon |
9c2953 |
w.strip() for w in form.issue_notifs.data.split(",") if w.strip()
|
|
Pierre-Yves Chibon |
080c15 |
]
|
|
Pierre-Yves Chibon |
080c15 |
pr_notifs = [
|
|
Pierre-Yves Chibon |
9c2953 |
w.strip() for w in form.pr_notifs.data.split(",") if w.strip()
|
|
Pierre-Yves Chibon |
080c15 |
]
|
|
Pierre-Yves Chibon |
080c15 |
|
|
Pierre-Yves Chibon |
080c15 |
try:
|
|
Pierre-Yves Chibon |
080c15 |
notifs = repo.notifications
|
|
Pierre-Yves Chibon |
9c2953 |
notifs["issues"] = issue_notifs
|
|
Pierre-Yves Chibon |
9c2953 |
notifs["requests"] = pr_notifs
|
|
Pierre-Yves Chibon |
080c15 |
repo.notifications = notifs
|
|
Pierre-Yves Chibon |
080c15 |
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.add(repo)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Project updated")
|
|
Pierre-Yves Chibon |
080c15 |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash(str(err), "error")
|
|
Pierre-Yves Chibon |
e1cd0d |
else:
|
|
Pierre-Yves Chibon |
e1cd0d |
flask.flash(
|
|
Pierre-Yves Chibon |
9c2953 |
"Unable to adjust one or more of the email provided", "error"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
080c15 |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=repo.namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#publicnotifications-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
827c77 |
|
|
Pierre-Yves Chibon |
827c77 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/update/close_status", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/update/close_status", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/update/close_status", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/update/close_status", methods=["POST"]</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
827c77 |
@login_required
|
|
Clement Verna |
afe475 |
@has_issue_tracker
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
827c77 |
def update_close_status(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
827c77 |
""" Update the close_status of a project.
|
|
Pierre-Yves Chibon |
827c77 |
"""
|
|
Pierre-Yves Chibon |
827c77 |
|
|
Pierre-Yves Chibon |
827c77 |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
827c77 |
|
|
Pierre-Yves Chibon |
827c77 |
form = pagure.forms.ConfirmationForm()
|
|
Pierre-Yves Chibon |
827c77 |
|
|
Pierre-Yves Chibon |
827c77 |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
827c77 |
close_status = [
|
|
Pierre-Yves Chibon |
9c2953 |
w.strip()
|
|
Pierre-Yves Chibon |
9c2953 |
for w in flask.request.form.getlist("close_status")
|
|
Pierre-Yves Chibon |
827c77 |
if w.strip()
|
|
Pierre-Yves Chibon |
827c77 |
]
|
|
Pierre-Yves Chibon |
827c77 |
try:
|
|
Pierre-Yves Chibon |
827c77 |
repo.close_status = close_status
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.add(repo)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("List of close status updated")
|
|
Pierre-Yves Chibon |
827c77 |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash(str(err), "error")
|
|
Lubomír Sedlář |
9871f9 |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#closestatus-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Lubomír Sedlář |
9871f9 |
|
|
Lubomír Sedlář |
9871f9 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/update/quick_replies", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/update/quick_replies", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/update/quick_replies", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/update/quick_replies",</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
methods=["POST"],
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Lubomír Sedlář |
9871f9 |
@login_required
|
|
Clement Verna |
36168f |
@has_issue_tracker
|
|
Clement Verna |
36168f |
@has_pr_enabled
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Lubomír Sedlář |
9871f9 |
def update_quick_replies(repo, username=None, namespace=None):
|
|
Lubomír Sedlář |
9871f9 |
""" Update the quick_replies of a project.
|
|
Lubomír Sedlář |
9871f9 |
"""
|
|
Lubomír Sedlář |
9871f9 |
|
|
Lubomír Sedlář |
9871f9 |
repo = flask.g.repo
|
|
Lubomír Sedlář |
9871f9 |
|
|
Pierre-Yves Chibon |
9c2953 |
if not repo.settings.get("pull_requests", True):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(
|
|
Pierre-Yves Chibon |
c6cc5c |
404, description="Pull requests are disabled for this project"
|
|
Pierre-Yves Chibon |
c6cc5c |
)
|
|
Lubomír Sedlář |
9871f9 |
|
|
Lubomír Sedlář |
9871f9 |
form = pagure.forms.ConfirmationForm()
|
|
Lubomír Sedlář |
9871f9 |
|
|
Lubomír Sedlář |
9871f9 |
if form.validate_on_submit():
|
|
Lubomír Sedlář |
9871f9 |
quick_replies = [
|
|
Pierre-Yves Chibon |
9c2953 |
w.strip()
|
|
Pierre-Yves Chibon |
9c2953 |
for w in flask.request.form.getlist("quick_reply")
|
|
Lubomír Sedlář |
9871f9 |
if w.strip()
|
|
Lubomír Sedlář |
9871f9 |
]
|
|
Lubomír Sedlář |
9871f9 |
try:
|
|
Lubomír Sedlář |
9871f9 |
repo.quick_replies = quick_replies
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.add(repo)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("List of quick replies updated")
|
|
Lubomír Sedlář |
9871f9 |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash(str(err), "error")
|
|
Pierre-Yves Chibon |
827c77 |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#quickreplies-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
3841b3 |
|
|
Pierre-Yves Chibon |
3841b3 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/update/custom_keys", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/update/custom_keys", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/update/custom_keys", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/update/custom_keys", methods=["POST"]</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
3841b3 |
@login_required
|
|
Clement Verna |
afe475 |
@has_issue_tracker
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
3841b3 |
def update_custom_keys(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
3841b3 |
""" Update the custom_keys of a project.
|
|
Pierre-Yves Chibon |
3841b3 |
"""
|
|
Pierre-Yves Chibon |
3841b3 |
|
|
Pierre-Yves Chibon |
3841b3 |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
3841b3 |
|
|
Pierre-Yves Chibon |
3841b3 |
form = pagure.forms.ConfirmationForm()
|
|
Pierre-Yves Chibon |
3841b3 |
|
|
Pierre-Yves Chibon |
3841b3 |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
3841b3 |
custom_keys = [
|
|
Pierre-Yves Chibon |
9c2953 |
w.strip()
|
|
Pierre-Yves Chibon |
9c2953 |
for w in flask.request.form.getlist("custom_keys")
|
|
Pierre-Yves Chibon |
3841b3 |
if w.strip()
|
|
Pierre-Yves Chibon |
3841b3 |
]
|
|
Pierre-Yves Chibon |
3841b3 |
custom_keys_type = [
|
|
Pierre-Yves Chibon |
9c2953 |
w.strip()
|
|
Pierre-Yves Chibon |
9c2953 |
for w in flask.request.form.getlist("custom_keys_type")
|
|
Pierre-Yves Chibon |
3841b3 |
if w.strip()
|
|
Pierre-Yves Chibon |
3841b3 |
]
|
|
Mark Reynolds |
e18f6c |
custom_keys_data = [
|
|
Pierre-Yves Chibon |
9c2953 |
w.strip() for w in flask.request.form.getlist("custom_keys_data")
|
|
Mark Reynolds |
e18f6c |
]
|
|
Mark Reynolds |
a8f1ac |
custom_keys_notify = []
|
|
Mark Reynolds |
a8f1ac |
for idx in range(len(custom_keys)):
|
|
Aurélien Bompard |
619e2a |
custom_keys_notify.append(
|
|
Pierre-Yves Chibon |
9c2953 |
"%s"
|
|
Pierre-Yves Chibon |
9c2953 |
% flask.request.form.get("custom_keys_notify-%s" % (idx + 1))
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
3841b3 |
|
|
Pierre-Yves Chibon |
3841b3 |
try:
|
|
Pierre-Yves Chibon |
930073 |
msg = pagure.lib.query.set_custom_key_fields(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session,
|
|
Pierre-Yves Chibon |
9c2953 |
repo,
|
|
Pierre-Yves Chibon |
9c2953 |
custom_keys,
|
|
Pierre-Yves Chibon |
9c2953 |
custom_keys_type,
|
|
Pierre-Yves Chibon |
9c2953 |
custom_keys_data,
|
|
Pierre-Yves Chibon |
9c2953 |
custom_keys_notify,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
3841b3 |
flask.flash(msg)
|
|
Pierre-Yves Chibon |
3841b3 |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash(str(err), "error")
|
|
Pierre-Yves Chibon |
3841b3 |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#customfields-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
abf91e |
|
|
Pierre-Yves Chibon |
abf91e |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/delete/report", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/delete/report", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/delete/report", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
b130e5 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/delete/report", methods=["POST"]</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
abf91e |
@login_required
|
|
Clement Verna |
afe475 |
@has_issue_tracker
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
abf91e |
def delete_report(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
abf91e |
""" Delete a report from a project.
|
|
Pierre-Yves Chibon |
abf91e |
"""
|
|
Pierre-Yves Chibon |
abf91e |
|
|
Pierre-Yves Chibon |
abf91e |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
abf91e |
|
|
Pierre-Yves Chibon |
abf91e |
form = pagure.forms.ConfirmationForm()
|
|
Pierre-Yves Chibon |
abf91e |
|
|
Pierre-Yves Chibon |
abf91e |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
9c2953 |
report = flask.request.form.get("report")
|
|
Pierre-Yves Chibon |
abf91e |
reports = repo.reports
|
|
Pierre-Yves Chibon |
abf91e |
if report not in reports:
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("Unknown report: %s" % report, "error")
|
|
Pierre-Yves Chibon |
abf91e |
else:
|
|
Pierre-Yves Chibon |
6d4fc2 |
del reports[report]
|
|
Pierre-Yves Chibon |
abf91e |
repo.reports = reports
|
|
Pierre-Yves Chibon |
abf91e |
try:
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.add(repo)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash("List of reports updated")
|
|
Pierre-Yves Chibon |
abf91e |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash(str(err), "error")
|
|
Pierre-Yves Chibon |
abf91e |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
+ "#reports-tab"
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
fd7da8 |
|
|
Pierre-Yves Chibon |
fd7da8 |
|
|
Patrick Uiterwijk |
3f97f6 |
@UI_NS.route("/<repo>/torepospanner", methods=["POST"])</repo>
|
|
Patrick Uiterwijk |
3f97f6 |
@UI_NS.route("/<namespace>/<repo>/torepospanner", methods=["POST"])</repo></namespace>
|
|
Patrick Uiterwijk |
3f97f6 |
@UI_NS.route("/fork/<username>/<repo>/torepospanner", methods=["POST"])</repo></username>
|
|
Patrick Uiterwijk |
3f97f6 |
@UI_NS.route(
|
|
Patrick Uiterwijk |
3f97f6 |
"/fork/<username>/<namespace>/<repo>/torepospanner", methods=["POST"]</repo></namespace></username>
|
|
Patrick Uiterwijk |
3f97f6 |
)
|
|
Patrick Uiterwijk |
3f97f6 |
@login_required
|
|
Patrick Uiterwijk |
3f97f6 |
@is_admin_sess_timedout
|
|
Patrick Uiterwijk |
3f97f6 |
@is_repo_admin
|
|
Patrick Uiterwijk |
3f97f6 |
def move_to_repospanner(repo, username=None, namespace=None):
|
|
Patrick Uiterwijk |
3f97f6 |
""" Give a project to someone else.
|
|
Patrick Uiterwijk |
3f97f6 |
"""
|
|
Patrick Uiterwijk |
3f97f6 |
repo = flask.g.repo
|
|
Patrick Uiterwijk |
3f97f6 |
|
|
Patrick Uiterwijk |
3f97f6 |
if not pagure.utils.is_admin():
|
|
Patrick Uiterwijk |
3f97f6 |
flask.abort(
|
|
Pierre-Yves Chibon |
c6cc5c |
403,
|
|
Pierre-Yves Chibon |
c6cc5c |
description="You are not allowed to transfer this project "
|
|
Pierre-Yves Chibon |
c6cc5c |
"to repoSpanner",
|
|
Patrick Uiterwijk |
3f97f6 |
)
|
|
Patrick Uiterwijk |
3f97f6 |
|
|
Patrick Uiterwijk |
3f97f6 |
if not pagure_config.get("REPOSPANNER_ADMIN_MIGRATION"):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(
|
|
Pierre-Yves Chibon |
c6cc5c |
403, description="It is not allowed to request migration of a repo"
|
|
Pierre-Yves Chibon |
c6cc5c |
)
|
|
Patrick Uiterwijk |
3f97f6 |
|
|
Patrick Uiterwijk |
3f97f6 |
form = pagure.forms.ConfirmationForm()
|
|
Patrick Uiterwijk |
3f97f6 |
|
|
Patrick Uiterwijk |
3f97f6 |
if form.validate_on_submit():
|
|
Patrick Uiterwijk |
3f97f6 |
region = flask.request.form.get("region", "").strip()
|
|
Patrick Uiterwijk |
3f97f6 |
if not region:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="No target region specified")
|
|
Patrick Uiterwijk |
3f97f6 |
|
|
Patrick Uiterwijk |
3f97f6 |
if region not in pagure_config.get("REPOSPANNER_REGIONS"):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Invalid region specified")
|
|
Patrick Uiterwijk |
3f97f6 |
|
|
Patrick Uiterwijk |
3f97f6 |
_log.info(
|
|
Patrick Uiterwijk |
3f97f6 |
"Repo %s requested to be migrated to repoSpanner region %s",
|
|
Patrick Uiterwijk |
3f97f6 |
repo.fullname,
|
|
Patrick Uiterwijk |
3f97f6 |
region,
|
|
Patrick Uiterwijk |
3f97f6 |
)
|
|
Patrick Uiterwijk |
3f97f6 |
|
|
Patrick Uiterwijk |
3f97f6 |
task = pagure.lib.tasks.move_to_repospanner.delay(
|
|
Patrick Uiterwijk |
3f97f6 |
repo.name, namespace, username, region
|
|
Patrick Uiterwijk |
3f97f6 |
)
|
|
Patrick Uiterwijk |
3f97f6 |
|
|
Patrick Uiterwijk |
3f97f6 |
return pagure.utils.wait_for_task(
|
|
Patrick Uiterwijk |
3f97f6 |
task,
|
|
Patrick Uiterwijk |
3f97f6 |
prev=flask.url_for(
|
|
Patrick Uiterwijk |
3f97f6 |
"ui_ns.view_repo",
|
|
Patrick Uiterwijk |
3f97f6 |
username=username,
|
|
Patrick Uiterwijk |
3f97f6 |
repo=repo.name,
|
|
Patrick Uiterwijk |
3f97f6 |
namespace=namespace,
|
|
Patrick Uiterwijk |
3f97f6 |
),
|
|
Patrick Uiterwijk |
3f97f6 |
)
|
|
Patrick Uiterwijk |
3f97f6 |
|
|
Patrick Uiterwijk |
3f97f6 |
return flask.redirect(
|
|
Patrick Uiterwijk |
3f97f6 |
flask.url_for(
|
|
Patrick Uiterwijk |
3f97f6 |
"ui_ns.view_repo",
|
|
Patrick Uiterwijk |
3f97f6 |
username=username,
|
|
Patrick Uiterwijk |
3f97f6 |
repo=repo.name,
|
|
Patrick Uiterwijk |
3f97f6 |
namespace=namespace,
|
|
Patrick Uiterwijk |
3f97f6 |
)
|
|
Patrick Uiterwijk |
3f97f6 |
)
|
|
Patrick Uiterwijk |
3f97f6 |
|
|
Patrick Uiterwijk |
3f97f6 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/give", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/give", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/give", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/give", methods=["POST"])</repo></namespace></username>
|
|
Pierre-Yves Chibon |
fd7da8 |
@login_required
|
|
Clement Verna |
91fd11 |
@is_admin_sess_timedout
|
|
Clement Verna |
91fd11 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
fd7da8 |
def give_project(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
fd7da8 |
""" Give a project to someone else.
|
|
Pierre-Yves Chibon |
fd7da8 |
"""
|
|
Pierre-Yves Chibon |
9c2953 |
if not pagure_config.get("ENABLE_GIVE_PROJECTS", True):
|
|
Pierre-Yves Chibon |
fd7da8 |
flask.abort(404)
|
|
Pierre-Yves Chibon |
fd7da8 |
|
|
Pierre-Yves Chibon |
fd7da8 |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
fd7da8 |
|
|
Pierre-Yves Chibon |
9c2953 |
if (
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.fas_user.username != repo.user.user
|
|
Pierre-Yves Chibon |
9c2953 |
and not pagure.utils.is_admin()
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(
|
|
Pierre-Yves Chibon |
c6cc5c |
403, description="You are not allowed to give this project"
|
|
Pierre-Yves Chibon |
c6cc5c |
)
|
|
Pierre-Yves Chibon |
fd7da8 |
|
|
Pierre-Yves Chibon |
fd7da8 |
form = pagure.forms.ConfirmationForm()
|
|
Pierre-Yves Chibon |
fd7da8 |
|
|
Pierre-Yves Chibon |
fd7da8 |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
9c2953 |
new_username = flask.request.form.get("user", "").strip()
|
|
Pierre-Yves Chibon |
6f43f3 |
if not new_username:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="No user specified")
|
|
Pierre-Yves Chibon |
930073 |
new_owner = pagure.lib.query.search_user(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session, username=new_username
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
fd7da8 |
if not new_owner:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(
|
|
Pierre-Yves Chibon |
c6cc5c |
404, description="No such user %s found" % new_username
|
|
Pierre-Yves Chibon |
c6cc5c |
)
|
|
Pierre-Yves Chibon |
02088b |
|
|
Pierre-Yves Chibon |
02088b |
failed = False
|
|
Pierre-Yves Chibon |
fd7da8 |
try:
|
|
mprahl |
8f40ee |
old_main_admin = repo.user.user
|
|
Pierre-Yves Chibon |
930073 |
pagure.lib.query.set_project_owner(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session,
|
|
Pierre-Yves Chibon |
9c2953 |
repo,
|
|
Pierre-Yves Chibon |
9c2953 |
new_owner,
|
|
Pierre-Yves Chibon |
9c2953 |
required_groups=pagure_config.get("REQUIRED_GROUPS"),
|
|
Pierre-Yves Chibon |
411690 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
411690 |
except pagure.exceptions.PagureException as msg:
|
|
Pierre-Yves Chibon |
02088b |
failed = True
|
|
Pierre-Yves Chibon |
411690 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
411690 |
_log.debug(msg)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash(str(msg), "error")
|
|
Pierre-Yves Chibon |
4ec145 |
except SQLAlchemyError: # pragma: no cover
|
|
Pierre-Yves Chibon |
02088b |
failed = True
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
ff8c8b |
flask.flash(
|
|
Pierre-Yves Chibon |
9c2953 |
"Due to a database error, this project could not be "
|
|
Pierre-Yves Chibon |
9c2953 |
"transferred.",
|
|
Pierre-Yves Chibon |
9c2953 |
"error",
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
|
|
Pierre-Yves Chibon |
02088b |
if not failed:
|
|
Pierre-Yves Chibon |
02088b |
try:
|
|
Pierre-Yves Chibon |
02088b |
# If the person doing the action is the former main admin, keep
|
|
Pierre-Yves Chibon |
02088b |
# them as admins
|
|
Pierre-Yves Chibon |
02088b |
if flask.g.fas_user.username == old_main_admin:
|
|
Pierre-Yves Chibon |
02088b |
pagure.lib.query.add_user_to_project(
|
|
Pierre-Yves Chibon |
02088b |
flask.g.session,
|
|
Pierre-Yves Chibon |
02088b |
repo,
|
|
Pierre-Yves Chibon |
02088b |
new_user=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
02088b |
user=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
02088b |
)
|
|
Pierre-Yves Chibon |
02088b |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
02088b |
except pagure.exceptions.PagureException as msg:
|
|
Pierre-Yves Chibon |
02088b |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
02088b |
_log.debug(msg)
|
|
Pierre-Yves Chibon |
02088b |
except SQLAlchemyError: # pragma: no cover
|
|
Pierre-Yves Chibon |
02088b |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
02088b |
flask.flash(
|
|
Pierre-Yves Chibon |
02088b |
"Due to a database error, this access could not be "
|
|
Pierre-Yves Chibon |
02088b |
"entirely set.",
|
|
Pierre-Yves Chibon |
02088b |
"error",
|
|
Pierre-Yves Chibon |
02088b |
)
|
|
Pierre-Yves Chibon |
02088b |
|
|
Pierre-Yves Chibon |
02088b |
pagure.lib.git.generate_gitolite_acls(project=repo)
|
|
Pierre-Yves Chibon |
02088b |
flask.flash(
|
|
Pierre-Yves Chibon |
02088b |
"The project has been transferred to %s" % new_username
|
|
Pierre-Yves Chibon |
02088b |
)
|
|
Pierre-Yves Chibon |
02088b |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.url_for(
|
|
Pierre-Yves Chibon |
9c2953 |
"ui_ns.view_repo",
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
|
|
Pierre-Yves Chibon |
9c2953 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/dowait/")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/dowait")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/dowait/")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/dowait")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/dowait/")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/dowait")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/dowait/")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/dowait")</repo></namespace></username>
|
|
Patrick Uiterwijk |
7b9080 |
def project_dowait(repo, username=None, namespace=None):
|
|
Patrick Uiterwijk |
7b9080 |
""" Schedules a task that just waits 10 seconds for testing locking.
|
|
Patrick Uiterwijk |
7b9080 |
|
|
Patrick Uiterwijk |
7b9080 |
This is not available unless ALLOW_PROJECT_DOWAIT is set to True, which
|
|
Patrick Uiterwijk |
7b9080 |
should only ever be done in test instances.
|
|
Patrick Uiterwijk |
7b9080 |
"""
|
|
Pierre-Yves Chibon |
9c2953 |
if not pagure_config.get("ALLOW_PROJECT_DOWAIT", False):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(401, description="No")
|
|
Patrick Uiterwijk |
7b9080 |
|
|
Aurélien Bompard |
a7f281 |
task = pagure.lib.tasks.project_dowait.delay(
|
|
Pierre-Yves Chibon |
9c2953 |
name=repo, namespace=namespace, user=username
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Patrick Uiterwijk |
7b9080 |
|
|
Aurélien Bompard |
a7f281 |
return pagure.utils.wait_for_task(task)
|
|
Pierre-Yves Chibon |
716362 |
|
|
Pierre-Yves Chibon |
716362 |
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/stats/")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<repo>/stats")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/stats/")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/<namespace>/<repo>/stats")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/stats/")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<repo>/stats")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/stats/")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/stats")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
716362 |
def view_stats(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
716362 |
""" Displays some statistics about the specified repo.
|
|
Pierre-Yves Chibon |
716362 |
"""
|
|
Pierre-Yves Chibon |
716362 |
return flask.render_template(
|
|
Pierre-Yves Chibon |
9c2953 |
"repo_stats.html", select="stats", username=username, repo=flask.g.repo
|
|
Pierre-Yves Chibon |
716362 |
)
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
@UI_NS.route("/<repo>/update/tags", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
d36429 |
@UI_NS.route("/<namespace>/<repo>/update/tags", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
d36429 |
@login_required
|
|
Pierre-Yves Chibon |
d36429 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
d86b5c |
@has_issue_or_pr_enabled
|
|
Pierre-Yves Chibon |
d36429 |
def update_tags(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
d36429 |
""" Update the tags of a project.
|
|
Pierre-Yves Chibon |
d36429 |
"""
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
form = pagure.forms.ConfirmationForm()
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
error = False
|
|
Pierre-Yves Chibon |
d36429 |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
d36429 |
# Uniquify and order preserving
|
|
Pierre-Yves Chibon |
d36429 |
seen = set()
|
|
Pierre-Yves Chibon |
d36429 |
tags = [
|
|
Pierre-Yves Chibon |
d36429 |
tag.strip()
|
|
Pierre-Yves Chibon |
d36429 |
for tag in flask.request.form.getlist("tag")
|
|
Pierre-Yves Chibon |
d36429 |
if tag.strip()
|
|
Pierre-Yves Chibon |
d36429 |
and tag.strip() not in seen # noqa
|
|
Pierre-Yves Chibon |
d36429 |
and not seen.add(tag.strip())
|
|
Pierre-Yves Chibon |
d36429 |
]
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
tag_descriptions = [
|
|
Pierre-Yves Chibon |
d36429 |
desc.strip()
|
|
Pierre-Yves Chibon |
d36429 |
for desc in flask.request.form.getlist("tag_description")
|
|
Pierre-Yves Chibon |
d36429 |
]
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
# Uniquify and order preserving
|
|
Pierre-Yves Chibon |
d36429 |
colors = [
|
|
Pierre-Yves Chibon |
d36429 |
col.strip()
|
|
Pierre-Yves Chibon |
d36429 |
for col in flask.request.form.getlist("tag_color")
|
|
Pierre-Yves Chibon |
d36429 |
if col.strip()
|
|
Pierre-Yves Chibon |
d36429 |
]
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
pattern = re.compile(pagure.forms.TAGS_REGEX, re.IGNORECASE)
|
|
Pierre-Yves Chibon |
d36429 |
for tag in tags:
|
|
Pierre-Yves Chibon |
d36429 |
if not pattern.match(tag):
|
|
Pierre-Yves Chibon |
d36429 |
flask.flash(
|
|
Pierre-Yves Chibon |
d36429 |
"Tag: %s contains one or more invalid characters" % tag,
|
|
Pierre-Yves Chibon |
d36429 |
"error",
|
|
Pierre-Yves Chibon |
d36429 |
)
|
|
Pierre-Yves Chibon |
d36429 |
error = True
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Karsten Hopp |
b310af |
color_pattern = re.compile(r"^#\w{3,6}$")
|
|
Pierre-Yves Chibon |
d36429 |
for color in colors:
|
|
Pierre-Yves Chibon |
d36429 |
if not color_pattern.match(color):
|
|
Pierre-Yves Chibon |
d36429 |
flask.flash(
|
|
Pierre-Yves Chibon |
d36429 |
"Color: %s does not match the expected pattern" % color,
|
|
Pierre-Yves Chibon |
d36429 |
"error",
|
|
Pierre-Yves Chibon |
d36429 |
)
|
|
Pierre-Yves Chibon |
d36429 |
error = True
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
if not (len(tags) == len(colors) == len(tag_descriptions)):
|
|
Pierre-Yves Chibon |
d36429 |
error = True
|
|
Pierre-Yves Chibon |
d36429 |
# Store the lengths because we are going to use them a lot
|
|
Pierre-Yves Chibon |
d36429 |
len_tags = len(tags)
|
|
Pierre-Yves Chibon |
d36429 |
len_tag_descriptions = len(tag_descriptions)
|
|
Pierre-Yves Chibon |
d36429 |
len_colors = len(colors)
|
|
Pierre-Yves Chibon |
d36429 |
error_message = "Error: Incomplete request. "
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
if len_colors > len_tags or len_tag_descriptions > len_tags:
|
|
Pierre-Yves Chibon |
d36429 |
error_message += "One or more tag fields missing."
|
|
Pierre-Yves Chibon |
d36429 |
elif len_colors < len_tags:
|
|
Pierre-Yves Chibon |
d36429 |
error_message += "One or more tag color fields missing."
|
|
Pierre-Yves Chibon |
d36429 |
elif len_tag_descriptions < len_tags:
|
|
Pierre-Yves Chibon |
d36429 |
error_message += "One or more tag description fields missing."
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
flask.flash(error_message, "error")
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
if not error:
|
|
Pierre-Yves Chibon |
d36429 |
known_tags = [tag.tag for tag in repo.tags_colored]
|
|
Pierre-Yves Chibon |
d36429 |
for idx, tag in enumerate(tags):
|
|
Pierre-Yves Chibon |
d36429 |
if tag in known_tags:
|
|
Pierre-Yves Chibon |
d36429 |
flask.flash("Duplicated tag: %s" % tag, "error")
|
|
Pierre-Yves Chibon |
d36429 |
break
|
|
Pierre-Yves Chibon |
d36429 |
try:
|
|
Pierre-Yves Chibon |
930073 |
pagure.lib.query.new_tag(
|
|
Pierre-Yves Chibon |
d36429 |
flask.g.session,
|
|
Pierre-Yves Chibon |
d36429 |
tag,
|
|
Pierre-Yves Chibon |
d36429 |
tag_descriptions[idx],
|
|
Pierre-Yves Chibon |
d36429 |
colors[idx],
|
|
Pierre-Yves Chibon |
d36429 |
repo.id,
|
|
Pierre-Yves Chibon |
d36429 |
)
|
|
Pierre-Yves Chibon |
d36429 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
d36429 |
flask.flash("Tags updated")
|
|
Pierre-Yves Chibon |
d36429 |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
d36429 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
d36429 |
flask.flash(str(err), "error")
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
d36429 |
flask.url_for(
|
|
Pierre-Yves Chibon |
d36429 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
d36429 |
username=username,
|
|
Pierre-Yves Chibon |
d36429 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
d36429 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
d36429 |
)
|
|
Pierre-Yves Chibon |
d36429 |
+ "#projecttags-tab"
|
|
Pierre-Yves Chibon |
d36429 |
)
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
@UI_NS.route("/<repo>/droptag/", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
d36429 |
@UI_NS.route("/<namespace>/<repo>/droptag/", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
d36429 |
@UI_NS.route("/fork/<username>/<repo>/droptag/", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
d36429 |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/droptag/", methods=["POST"])</repo></namespace></username>
|
|
Pierre-Yves Chibon |
d36429 |
@login_required
|
|
Pierre-Yves Chibon |
d36429 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
d86b5c |
@has_issue_or_pr_enabled
|
|
Pierre-Yves Chibon |
d36429 |
def remove_tag(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
d36429 |
""" Remove the specified tag, associated with the issues, from the project.
|
|
Pierre-Yves Chibon |
d36429 |
"""
|
|
Pierre-Yves Chibon |
d36429 |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
form = pagure.forms.DeleteIssueTagForm()
|
|
Pierre-Yves Chibon |
d36429 |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
d36429 |
tags = form.tag.data
|
|
Pierre-Yves Chibon |
d36429 |
tags = [tag.strip() for tag in tags.split(",")]
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
930073 |
msgs = pagure.lib.query.remove_tags(
|
|
Pierre-Yves Chibon |
d36429 |
flask.g.session, repo, tags, user=flask.g.fas_user.username
|
|
Pierre-Yves Chibon |
d36429 |
)
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
try:
|
|
Pierre-Yves Chibon |
d36429 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
d36429 |
for msg in msgs:
|
|
Pierre-Yves Chibon |
d36429 |
flask.flash(msg)
|
|
Pierre-Yves Chibon |
d36429 |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
d36429 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
d36429 |
_log.error(err)
|
|
Pierre-Yves Chibon |
d36429 |
flask.flash("Could not remove tag: %s" % ",".join(tags), "error")
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
d36429 |
flask.url_for(
|
|
Pierre-Yves Chibon |
d36429 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
d36429 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
d36429 |
username=username,
|
|
Pierre-Yves Chibon |
d36429 |
namespace=repo.namespace,
|
|
Pierre-Yves Chibon |
d36429 |
)
|
|
Pierre-Yves Chibon |
d36429 |
+ "#projecttags-tab"
|
|
Pierre-Yves Chibon |
d36429 |
)
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
@UI_NS.route("/<repo>/tag/<tag>/edit/", methods=("GET", "POST"))</tag></repo>
|
|
Pierre-Yves Chibon |
d36429 |
@UI_NS.route("/<repo>/tag/<tag>/edit", methods=("GET", "POST"))</tag></repo>
|
|
Pierre-Yves Chibon |
d36429 |
@UI_NS.route("/<namespace>/<repo>/tag/<tag>/edit/", methods=("GET", "POST"))</tag></repo></namespace>
|
|
Pierre-Yves Chibon |
d36429 |
@UI_NS.route("/<namespace>/<repo>/tag/<tag>/edit", methods=("GET", "POST"))</tag></repo></namespace>
|
|
Pierre-Yves Chibon |
d36429 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
d36429 |
"/fork/<username>/<repo>/tag/<tag>/edit/", methods=("GET", "POST")</tag></repo></username>
|
|
Pierre-Yves Chibon |
d36429 |
)
|
|
Pierre-Yves Chibon |
d36429 |
@UI_NS.route("/fork/<username>/<repo>/tag/<tag>/edit", methods=("GET", "POST"))</tag></repo></username>
|
|
Pierre-Yves Chibon |
d36429 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
d36429 |
"/fork/<username>/<namespace>/<repo>/tag/<tag>/edit/",</tag></repo></namespace></username>
|
|
Pierre-Yves Chibon |
d36429 |
methods=("GET", "POST"),
|
|
Pierre-Yves Chibon |
d36429 |
)
|
|
Pierre-Yves Chibon |
d36429 |
@UI_NS.route(
|
|
Pierre-Yves Chibon |
d36429 |
"/fork/<username>/<namespace>/<repo>/tag/<tag>/edit",</tag></repo></namespace></username>
|
|
Pierre-Yves Chibon |
d36429 |
methods=("GET", "POST"),
|
|
Pierre-Yves Chibon |
d36429 |
)
|
|
Pierre-Yves Chibon |
d36429 |
@login_required
|
|
Pierre-Yves Chibon |
d36429 |
@is_repo_admin
|
|
Pierre-Yves Chibon |
d86b5c |
@has_issue_or_pr_enabled
|
|
Pierre-Yves Chibon |
d36429 |
def edit_tag(repo, tag, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
d36429 |
""" Edit the specified tag associated with the issues of a project.
|
|
Pierre-Yves Chibon |
d36429 |
"""
|
|
Pierre-Yves Chibon |
d36429 |
repo = flask.g.repo
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
930073 |
tags = pagure.lib.query.get_tags_of_project(flask.g.session, repo)
|
|
Pierre-Yves Chibon |
d36429 |
if not tags:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Project has no tags to edit")
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
# Check the tag exists, and get its old/original color
|
|
Pierre-Yves Chibon |
930073 |
tagobj = pagure.lib.query.get_colored_tag(flask.g.session, tag, repo.id)
|
|
Pierre-Yves Chibon |
d36429 |
if not tagobj:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Tag %s not found in this project" % tag)
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
form = pagure.forms.AddIssueTagForm()
|
|
Pierre-Yves Chibon |
d36429 |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
d36429 |
new_tag = form.tag.data
|
|
Pierre-Yves Chibon |
d36429 |
new_tag_description = form.tag_description.data
|
|
Pierre-Yves Chibon |
d36429 |
new_tag_color = form.tag_color.data
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
930073 |
msgs = pagure.lib.query.edit_issue_tags(
|
|
Pierre-Yves Chibon |
d36429 |
flask.g.session,
|
|
Pierre-Yves Chibon |
d36429 |
repo,
|
|
Pierre-Yves Chibon |
d36429 |
tagobj,
|
|
Pierre-Yves Chibon |
d36429 |
new_tag,
|
|
Pierre-Yves Chibon |
d36429 |
new_tag_description,
|
|
Pierre-Yves Chibon |
d36429 |
new_tag_color,
|
|
Pierre-Yves Chibon |
d36429 |
user=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
d36429 |
)
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
try:
|
|
Pierre-Yves Chibon |
d36429 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
d36429 |
for msg in msgs:
|
|
Pierre-Yves Chibon |
d36429 |
flask.flash(msg)
|
|
Pierre-Yves Chibon |
d36429 |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
d36429 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
d36429 |
_log.error(err)
|
|
Pierre-Yves Chibon |
d36429 |
flask.flash("Could not edit tag: %s" % tag, "error")
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
d36429 |
flask.url_for(
|
|
Pierre-Yves Chibon |
d36429 |
"ui_ns.view_settings",
|
|
Pierre-Yves Chibon |
d36429 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
d36429 |
username=username,
|
|
Pierre-Yves Chibon |
d36429 |
namespace=repo.namespace,
|
|
Pierre-Yves Chibon |
d36429 |
)
|
|
Pierre-Yves Chibon |
d36429 |
+ "#projecttags-tab"
|
|
Pierre-Yves Chibon |
d36429 |
)
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
elif flask.request.method == "GET":
|
|
Pierre-Yves Chibon |
d36429 |
tag_color = tagobj.tag_color
|
|
Pierre-Yves Chibon |
d36429 |
if tag_color == "DeepSkyBlue":
|
|
Pierre-Yves Chibon |
d36429 |
tag_color = "#00bfff"
|
|
Pierre-Yves Chibon |
d36429 |
form.tag_color.data = tag_color
|
|
Pierre-Yves Chibon |
d36429 |
form.tag_description.data = tagobj.tag_description
|
|
Pierre-Yves Chibon |
d36429 |
form.tag.data = tag
|
|
Pierre-Yves Chibon |
d36429 |
|
|
Pierre-Yves Chibon |
d36429 |
return flask.render_template(
|
|
Pierre-Yves Chibon |
d36429 |
"edit_tag.html", username=username, repo=repo, form=form, tagname=tag
|
|
Pierre-Yves Chibon |
d36429 |
)
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
@UI_NS.route("/<repo>/archive/<ref>/<name>.tar")</name></ref></repo>
|
|
Pierre-Yves Chibon |
ded1fa |
@UI_NS.route("/<namespace>/<repo>/archive/<ref>/<name>.tar")</name></ref></repo></namespace>
|
|
Pierre-Yves Chibon |
ded1fa |
@UI_NS.route("/fork/<username>/<repo>/archive/<ref>/<name>.tar")</name></ref></repo></username>
|
|
Pierre-Yves Chibon |
ded1fa |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/archive/<ref>/<name>.tar")</name></ref></repo></namespace></username>
|
|
Pierre-Yves Chibon |
ded1fa |
def get_project_archive_tar(repo, ref, name, namespace=None, username=None):
|
|
Pierre-Yves Chibon |
ded1fa |
""" Generate an archive or redirect the user to where it already exists
|
|
Pierre-Yves Chibon |
ded1fa |
"""
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
return generate_project_archive(
|
|
Pierre-Yves Chibon |
ded1fa |
repo,
|
|
Pierre-Yves Chibon |
ded1fa |
ref,
|
|
Pierre-Yves Chibon |
ded1fa |
name,
|
|
Pierre-Yves Chibon |
ded1fa |
extension="tar",
|
|
Pierre-Yves Chibon |
ded1fa |
namespace=namespace,
|
|
Pierre-Yves Chibon |
ded1fa |
username=username,
|
|
Pierre-Yves Chibon |
ded1fa |
)
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
@UI_NS.route("/<repo>/archive/<ref>/<name>.tar.gz")</name></ref></repo>
|
|
Pierre-Yves Chibon |
ded1fa |
@UI_NS.route("/<namespace>/<repo>/archive/<ref>/<name>.tar.gz")</name></ref></repo></namespace>
|
|
Pierre-Yves Chibon |
ded1fa |
@UI_NS.route("/fork/<username>/<repo>/archive/<ref>/<name>.tar.gz")</name></ref></repo></username>
|
|
Pierre-Yves Chibon |
ded1fa |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/archive/<ref>/<name>.tar.gz")</name></ref></repo></namespace></username>
|
|
Pierre-Yves Chibon |
ded1fa |
def get_project_archive_tar_gz(repo, ref, name, namespace=None, username=None):
|
|
Pierre-Yves Chibon |
ded1fa |
""" Generate an archive or redirect the user to where it already exists
|
|
Pierre-Yves Chibon |
ded1fa |
"""
|
|
Pierre-Yves Chibon |
ded1fa |
return generate_project_archive(
|
|
Pierre-Yves Chibon |
ded1fa |
repo,
|
|
Pierre-Yves Chibon |
ded1fa |
ref,
|
|
Pierre-Yves Chibon |
ded1fa |
name,
|
|
Pierre-Yves Chibon |
ded1fa |
extension="tar.gz",
|
|
Pierre-Yves Chibon |
ded1fa |
namespace=namespace,
|
|
Pierre-Yves Chibon |
ded1fa |
username=username,
|
|
Pierre-Yves Chibon |
ded1fa |
)
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
@UI_NS.route("/<repo>/archive/<ref>/<name>.zip")</name></ref></repo>
|
|
Pierre-Yves Chibon |
ded1fa |
@UI_NS.route("/<namespace>/<repo>/archive/<ref>/<name>.zip")</name></ref></repo></namespace>
|
|
Pierre-Yves Chibon |
ded1fa |
@UI_NS.route("/fork/<username>/<repo>/archive/<ref>/<name>.zip")</name></ref></repo></username>
|
|
Pierre-Yves Chibon |
ded1fa |
@UI_NS.route("/fork/<username>/<namespace>/<repo>/archive/<ref>/<name>.zip")</name></ref></repo></namespace></username>
|
|
Pierre-Yves Chibon |
ded1fa |
def get_project_archive_zip(repo, ref, name, namespace=None, username=None):
|
|
Pierre-Yves Chibon |
ded1fa |
""" Generate an archive or redirect the user to where it already exists
|
|
Pierre-Yves Chibon |
ded1fa |
"""
|
|
Pierre-Yves Chibon |
ded1fa |
return generate_project_archive(
|
|
Pierre-Yves Chibon |
ded1fa |
repo,
|
|
Pierre-Yves Chibon |
ded1fa |
ref,
|
|
Pierre-Yves Chibon |
ded1fa |
name,
|
|
Pierre-Yves Chibon |
ded1fa |
extension="zip",
|
|
Pierre-Yves Chibon |
ded1fa |
namespace=namespace,
|
|
Pierre-Yves Chibon |
ded1fa |
username=username,
|
|
Pierre-Yves Chibon |
ded1fa |
)
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
def generate_project_archive(
|
|
Pierre-Yves Chibon |
ded1fa |
repo, ref, name, extension, namespace=None, username=None
|
|
Pierre-Yves Chibon |
ded1fa |
):
|
|
Pierre-Yves Chibon |
ded1fa |
""" Generate an archive or redirect the user to where it already
|
|
Pierre-Yves Chibon |
ded1fa |
exists.
|
|
Pierre-Yves Chibon |
ded1fa |
"""
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
archive_folder = pagure_config.get("ARCHIVE_FOLDER")
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
if not archive_folder:
|
|
Pierre-Yves Chibon |
ded1fa |
_log.debug("No ARCHIVE_FOLDER specified in the configuration")
|
|
Pierre-Yves Chibon |
ded1fa |
flask.abort(
|
|
Pierre-Yves Chibon |
ded1fa |
404,
|
|
Pierre-Yves Chibon |
c6cc5c |
description="This pagure instance isn't configured to support "
|
|
Pierre-Yves Chibon |
c6cc5c |
"this feature",
|
|
Pierre-Yves Chibon |
0ed488 |
)
|
|
Pierre-Yves Chibon |
ded1fa |
if not os.path.exists(archive_folder):
|
|
Pierre-Yves Chibon |
ded1fa |
_log.debug("No ARCHIVE_FOLDER could not be found on disk")
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(
|
|
Pierre-Yves Chibon |
c6cc5c |
500,
|
|
Pierre-Yves Chibon |
c6cc5c |
description="Incorrect configuration, please contact your admin",
|
|
Pierre-Yves Chibon |
c6cc5c |
)
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
extensions = ["tar.gz", "tar", "zip"]
|
|
Pierre-Yves Chibon |
ded1fa |
if extension not in extensions:
|
|
Pierre-Yves Chibon |
ded1fa |
_log.debug("%s no in %s", extension, extensions)
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(400, description="Invalid archive format specified")
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
name = werkzeug.secure_filename(name)
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
repo_obj = flask.g.repo_obj
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
ref_string = "refs/tags/%s" % ref
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
commit = None
|
|
Pierre-Yves Chibon |
ded1fa |
tag = None
|
|
Pierre-Yves Chibon |
ded1fa |
if ref_string in repo_obj.listall_references():
|
|
Pierre-Yves Chibon |
ded1fa |
reference = repo_obj.lookup_reference(ref_string)
|
|
Pierre-Yves Chibon |
ded1fa |
tag = repo_obj[reference.target]
|
|
Pierre-Yves Chibon |
7c59e9 |
if isinstance(tag, pygit2.Tag):
|
|
Pierre-Yves Chibon |
7c59e9 |
commit = tag.peel(pygit2.Commit)
|
|
Pierre-Yves Chibon |
7c59e9 |
elif isinstance(tag, pygit2.Commit):
|
|
Pierre-Yves Chibon |
7c59e9 |
commit = tag
|
|
Pierre-Yves Chibon |
7c59e9 |
else:
|
|
Pierre-Yves Chibon |
7c59e9 |
_log.debug("Found %s instead of a tag", tag)
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(400, description="Invalid reference provided")
|
|
Pierre-Yves Chibon |
ded1fa |
else:
|
|
Pierre-Yves Chibon |
ded1fa |
try:
|
|
Pierre-Yves Chibon |
ded1fa |
commit = repo_obj.get(ref)
|
|
Pierre-Yves Chibon |
ded1fa |
except ValueError:
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(404, description="Invalid commit provided")
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
if not isinstance(commit, pygit2.Commit):
|
|
Pierre-Yves Chibon |
c6cc5c |
flask.abort(400, description="Invalid reference specified")
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
tag_path = ""
|
|
Pierre-Yves Chibon |
ded1fa |
tag_filename = None
|
|
Pierre-Yves Chibon |
ded1fa |
if tag:
|
|
Pierre-Yves Chibon |
ded1fa |
tag_filename = werkzeug.secure_filename(ref)
|
|
Pierre-Yves Chibon |
ded1fa |
tag_path = os.path.join("tags", tag_filename)
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
path = os.path.join(
|
|
Pierre-Yves Chibon |
ded1fa |
archive_folder,
|
|
Pierre-Yves Chibon |
ded1fa |
flask.g.repo.fullname,
|
|
Pierre-Yves Chibon |
ded1fa |
tag_path,
|
|
Pierre-Yves Chibon |
ded1fa |
commit.oid.hex,
|
|
Pierre-Yves Chibon |
ded1fa |
"%s.%s" % (name, extension),
|
|
Pierre-Yves Chibon |
ded1fa |
)
|
|
Pierre-Yves Chibon |
ded1fa |
headers = {
|
|
Pierre-Yves Chibon |
ded1fa |
str("Content-Disposition"): "attachment",
|
|
Pierre-Yves Chibon |
ded1fa |
str("Content-Type"): "application/x-gzip",
|
|
Pierre-Yves Chibon |
ded1fa |
}
|
|
Pierre-Yves Chibon |
ded1fa |
if os.path.exists(path):
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
def _send_data():
|
|
Pierre-Yves Chibon |
ded1fa |
with open(path, "rb") as stream:
|
|
Pierre-Yves Chibon |
ded1fa |
yield stream.read()
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
_log.info("Sending the existing archive")
|
|
Pierre-Yves Chibon |
ded1fa |
return flask.Response(
|
|
Pierre-Yves Chibon |
ded1fa |
flask.stream_with_context(_send_data()), headers=headers
|
|
Pierre-Yves Chibon |
ded1fa |
)
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
_log.info("Re-generating the archive")
|
|
Pierre-Yves Chibon |
ded1fa |
task = pagure.lib.tasks.generate_archive.delay(
|
|
Pierre-Yves Chibon |
ded1fa |
repo,
|
|
Pierre-Yves Chibon |
ded1fa |
namespace=namespace,
|
|
Pierre-Yves Chibon |
ded1fa |
username=username,
|
|
Pierre-Yves Chibon |
ded1fa |
commit=commit.oid.hex,
|
|
Pierre-Yves Chibon |
ded1fa |
tag=tag_filename,
|
|
Pierre-Yves Chibon |
ded1fa |
name=name,
|
|
Pierre-Yves Chibon |
ded1fa |
archive_fmt=extension,
|
|
Pierre-Yves Chibon |
ded1fa |
)
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
def _wait_for_task_and_send_data():
|
|
Pierre-Yves Chibon |
ded1fa |
while not task.ready():
|
|
Pierre-Yves Chibon |
ded1fa |
import time
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
_log.info("waiting")
|
|
Pierre-Yves Chibon |
ded1fa |
time.sleep(0.5)
|
|
Pierre-Yves Chibon |
ded1fa |
with open(path, "rb") as stream:
|
|
Pierre-Yves Chibon |
ded1fa |
yield stream.read()
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
_log.info("Sending the existing archive")
|
|
Pierre-Yves Chibon |
ded1fa |
return flask.Response(
|
|
Pierre-Yves Chibon |
ded1fa |
flask.stream_with_context(_wait_for_task_and_send_data()),
|
|
Pierre-Yves Chibon |
ded1fa |
headers=headers,
|
|
Pierre-Yves Chibon |
ded1fa |
)
|
|
Pierre-Yves Chibon |
ded1fa |
|
|
Pierre-Yves Chibon |
ded1fa |
return pagure.utils.wait_for_task(task)
|