|
Pierre-Yves Chibon |
33b534 |
# -*- coding: utf-8 -*-
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
1e2e25 |
"""
|
|
Pierre-Yves Chibon |
341785 |
(c) 2014-2016 - Copyright Red Hat Inc
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
1e2e25 |
Authors:
|
|
Pierre-Yves Chibon |
1e2e25 |
Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
1e2e25 |
"""
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
22a554 |
# pylint: disable=too-many-branches
|
|
Pierre-Yves Chibon |
22a554 |
# pylint: disable=too-many-arguments
|
|
Pierre-Yves Chibon |
22a554 |
# pylint: disable=too-many-locals
|
|
Pierre-Yves Chibon |
22a554 |
# pylint: disable=too-many-statements
|
|
Pierre-Yves Chibon |
22a554 |
# pylint: disable=too-many-lines
|
|
Pierre-Yves Chibon |
c3b072 |
|
|
Pierre-Yves Chibon |
c3b072 |
|
|
Pierre-Yves Chibon |
72a8e7 |
try:
|
|
Pierre-Yves Chibon |
72a8e7 |
import simplejson as json
|
|
Pierre-Yves Chibon |
72a8e7 |
except ImportError:
|
|
Pierre-Yves Chibon |
72a8e7 |
import json
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
9af5a0 |
import datetime
|
|
Pierre-Yves Chibon |
2d9881 |
import markdown
|
|
Pierre-Yves Chibon |
d8110b |
import os
|
|
Pierre-Yves Chibon |
d133cd |
import shutil
|
|
Pierre-Yves Chibon |
d133cd |
import tempfile
|
|
Patrick Uiterwijk |
073828 |
import subprocess
|
|
Pierre-Yves Chibon |
f1e2a9 |
import urlparse
|
|
Pierre-Yves Chibon |
9cb884 |
import uuid
|
|
Pierre-Yves Chibon |
d8110b |
|
|
Pierre-Yves Chibon |
3916b5 |
import bleach
|
|
Pierre-Yves Chibon |
2e464a |
import redis
|
|
Pierre-Yves Chibon |
bbbc71 |
import six
|
|
Pierre-Yves Chibon |
1e2e25 |
import sqlalchemy
|
|
Pierre-Yves Chibon |
42693f |
import sqlalchemy.schema
|
|
Pierre-Yves Chibon |
42693f |
from sqlalchemy import func
|
|
Ryan Lerch |
636f6a |
from sqlalchemy import asc
|
|
Pierre-Yves Chibon |
ed38ee |
from sqlalchemy.orm import aliased
|
|
Pierre-Yves Chibon |
1e2e25 |
from sqlalchemy.orm import sessionmaker
|
|
Pierre-Yves Chibon |
1e2e25 |
from sqlalchemy.orm import scoped_session
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
d8110b |
import pygit2
|
|
Pierre-Yves Chibon |
d8110b |
|
|
Pierre-Yves Chibon |
fe5017 |
import pagure.exceptions
|
|
Pierre-Yves Chibon |
fe5017 |
import pagure.lib.git
|
|
Pierre-Yves Chibon |
4fd1f7 |
import pagure.lib.login
|
|
Pierre-Yves Chibon |
fe5017 |
import pagure.lib.notify
|
|
Pierre-Yves Chibon |
afcf11 |
import pagure.lib.plugins
|
|
Pierre-Yves Chibon |
814bc8 |
import pagure.pfmarkdown
|
|
Pierre-Yves Chibon |
fe5017 |
from pagure.lib import model
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
2e464a |
REDIS = None
|
|
Pierre-Yves Chibon |
587ba8 |
PAGURE_CI = None
|
|
Pierre-Yves Chibon |
2e464a |
|
|
Pierre-Yves Chibon |
b13b92 |
|
|
Pierre-Yves Chibon |
d1e053 |
def set_redis(host, port, dbname):
|
|
Pierre-Yves Chibon |
2e464a |
""" Set the redis connection with the specified information. """
|
|
Pierre-Yves Chibon |
2e464a |
global REDIS
|
|
Pierre-Yves Chibon |
d1e053 |
pool = redis.ConnectionPool(host=host, port=port, db=dbname)
|
|
Pierre-Yves Chibon |
2e464a |
REDIS = redis.StrictRedis(connection_pool=pool)
|
|
Pierre-Yves Chibon |
2e464a |
|
|
Pierre-Yves Chibon |
b13b92 |
|
|
Pierre-Yves Chibon |
587ba8 |
def set_pagure_ci(services):
|
|
Pierre-Yves Chibon |
587ba8 |
""" Set the list of CI services supported by this pagure instance. """
|
|
Pierre-Yves Chibon |
70cf75 |
global PAGURE_CI
|
|
Pierre-Yves Chibon |
587ba8 |
PAGURE_CI = services
|
|
Pierre-Yves Chibon |
587ba8 |
|
|
Pierre-Yves Chibon |
2e464a |
|
|
Pierre-Yves Chibon |
6aa385 |
def get_user(session, key):
|
|
Pierre-Yves Chibon |
60bea3 |
""" Searches for a user in the database for a given username or email.
|
|
Pierre-Yves Chibon |
60bea3 |
"""
|
|
Pierre-Yves Chibon |
60bea3 |
user_obj = search_user(session, username=key)
|
|
Pierre-Yves Chibon |
60bea3 |
if not user_obj:
|
|
Pierre-Yves Chibon |
60bea3 |
user_obj = search_user(session, email=key)
|
|
Pierre-Yves Chibon |
60bea3 |
|
|
Pierre-Yves Chibon |
60bea3 |
if not user_obj:
|
|
Pierre-Yves Chibon |
fe5017 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
60bea3 |
'No user "%s" found' % key
|
|
Pierre-Yves Chibon |
60bea3 |
)
|
|
Pierre-Yves Chibon |
60bea3 |
|
|
Pierre-Yves Chibon |
60bea3 |
return user_obj
|
|
Pierre-Yves Chibon |
60bea3 |
|
|
Pierre-Yves Chibon |
60bea3 |
|
|
Pierre-Yves Chibon |
1e2e25 |
def create_session(db_url, debug=False, pool_recycle=3600):
|
|
Pierre-Yves Chibon |
695ef6 |
''' Create the Session object to use to query the database.
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
1e2e25 |
:arg db_url: URL used to connect to the database. The URL contains
|
|
Pierre-Yves Chibon |
1e2e25 |
information with regards to the database engine, the host to connect
|
|
Pierre-Yves Chibon |
1e2e25 |
to, the user and password and the database name.
|
|
Pierre-Yves Chibon |
1e2e25 |
ie: <engine>://<user>:<password>@<host>/<dbname></dbname></host></password></user></engine>
|
|
Pierre-Yves Chibon |
1e2e25 |
:kwarg debug: a boolean specifying wether we should have the verbose
|
|
Pierre-Yves Chibon |
1e2e25 |
output of sqlalchemy or not.
|
|
Pierre-Yves Chibon |
1e2e25 |
:return a Session that can be used to query the database.
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
695ef6 |
'''
|
|
Ryan Lerch |
6741dd |
if db_url.startswith('sqlite'):
|
|
Ryan Lerch |
cd0b04 |
engine = sqlalchemy.create_engine(
|
|
Ryan Lerch |
cd0b04 |
db_url, echo=debug, pool_recycle=pool_recycle)
|
|
Ryan Lerch |
cd0b04 |
else:
|
|
Ryan Lerch |
cd0b04 |
engine = sqlalchemy.create_engine(
|
|
Ryan Lerch |
cd0b04 |
db_url, echo=debug, pool_recycle=pool_recycle,
|
|
Ryan Lerch |
cd0b04 |
client_encoding='utf8')
|
|
Pierre-Yves Chibon |
1e2e25 |
scopedsession = scoped_session(sessionmaker(bind=engine))
|
|
Pierre-Yves Chibon |
1dbdfe |
model.BASE.metadata.bind = scopedsession
|
|
Pierre-Yves Chibon |
1e2e25 |
return scopedsession
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
1e2e25 |
|
|
Pierre-Yves Chibon |
42693f |
def get_next_id(session, projectid):
|
|
Pierre-Yves Chibon |
42693f |
""" Returns the next identifier of a project ticket or pull-request
|
|
Pierre-Yves Chibon |
42693f |
based on the identifier already in the database.
|
|
Pierre-Yves Chibon |
42693f |
"""
|
|
Pierre-Yves Chibon |
b8c7ae |
query1 = session.query(
|
|
Pierre-Yves Chibon |
7909ea |
func.max(model.Issue.id)
|
|
Pierre-Yves Chibon |
42693f |
).filter(
|
|
Pierre-Yves Chibon |
42693f |
model.Issue.project_id == projectid
|
|
Pierre-Yves Chibon |
42693f |
)
|
|
Pierre-Yves Chibon |
42693f |
|
|
Pierre-Yves Chibon |
b8c7ae |
query2 = session.query(
|
|
Pierre-Yves Chibon |
7909ea |
func.max(model.PullRequest.id)
|
|
Pierre-Yves Chibon |
42693f |
).filter(
|
|
Pierre-Yves Chibon |
42693f |
model.PullRequest.project_id == projectid
|
|
Pierre-Yves Chibon |
42693f |
)
|
|
Pierre-Yves Chibon |
42693f |
|
|
Pierre-Yves Chibon |
b8c7ae |
nid = max([el[0] for el in query1.union(query2).all()]) or 0
|
|
Pierre-Yves Chibon |
42693f |
|
|
Pierre-Yves Chibon |
7909ea |
return nid + 1
|
|
Pierre-Yves Chibon |
42693f |
|
|
Pierre-Yves Chibon |
42693f |
|
|
Pierre-Yves Chibon |
de2a45 |
def search_user(session, username=None, email=None, token=None, pattern=None):
|
|
Pierre-Yves Chibon |
de2a45 |
''' Searches the database for the user or users matching the given
|
|
Pierre-Yves Chibon |
de2a45 |
criterias.
|
|
Pierre-Yves Chibon |
de2a45 |
|
|
Pierre-Yves Chibon |
de2a45 |
:arg session: the session to use to connect to the database.
|
|
Pierre-Yves Chibon |
de2a45 |
:kwarg username: the username of the user to look for.
|
|
Pierre-Yves Chibon |
de2a45 |
:type username: string or None
|
|
Pierre-Yves Chibon |
de2a45 |
:kwarg email: the email or one of the email of the user to look for
|
|
Pierre-Yves Chibon |
de2a45 |
:type email: string or None
|
|
Pierre-Yves Chibon |
de2a45 |
:kwarg token: the token of the user to look for
|
|
Pierre-Yves Chibon |
de2a45 |
:type token: string or None
|
|
Pierre-Yves Chibon |
de2a45 |
:kwarg pattern: a pattern to search the users with.
|
|
Pierre-Yves Chibon |
de2a45 |
:type pattern: string or None
|
|
Pierre-Yves Chibon |
de2a45 |
:return: A single User object if any of username, email or token is
|
|
Pierre-Yves Chibon |
de2a45 |
specified, a list of User objects otherwise.
|
|
Pierre-Yves Chibon |
de2a45 |
:rtype: User or [User]
|
|
Pierre-Yves Chibon |
34cbca |
|
|
Pierre-Yves Chibon |
34cbca |
'''
|
|
Pierre-Yves Chibon |
4cbbea |
query = session.query(
|
|
Pierre-Yves Chibon |
556d85 |
model.User
|
|
Pierre-Yves Chibon |
692bf9 |
).order_by(
|
|
Pierre-Yves Chibon |
692bf9 |
model.User.user
|
|
Pierre-Yves Chibon |
4cbbea |
)
|
|
Pierre-Yves Chibon |
4cbbea |
|
|
Pierre-Yves Chibon |
de2a45 |
if username is not None:
|
|
Pierre-Yves Chibon |
de2a45 |
query = query.filter(
|
|
Pierre-Yves Chibon |
de2a45 |
model.User.user == username
|
|
Pierre-Yves Chibon |
de2a45 |
)
|
|
Pierre-Yves Chibon |
de2a45 |
|
|
Pierre-Yves Chibon |
de2a45 |
if email is not None:
|
|
Pierre-Yves Chibon |
de2a45 |
query = query.filter(
|
|
Pierre-Yves Chibon |
de2a45 |
model.UserEmail.user_id == model.User.id
|
|
Pierre-Yves Chibon |
de2a45 |
).filter(
|
|
Pierre-Yves Chibon |
de2a45 |
model.UserEmail.email == email
|
|
Pierre-Yves Chibon |
de2a45 |
)
|
|
Pierre-Yves Chibon |
de2a45 |
|
|
Pierre-Yves Chibon |
de2a45 |
if token is not None:
|
|
Pierre-Yves Chibon |
de2a45 |
query = query.filter(
|
|
Pierre-Yves Chibon |
de2a45 |
model.User.token == token
|
|
Pierre-Yves Chibon |
de2a45 |
)
|
|
Pierre-Yves Chibon |
de2a45 |
|
|
Pierre-Yves Chibon |
4cbbea |
if pattern:
|
|
Pierre-Yves Chibon |
4cbbea |
pattern = pattern.replace('*', '%')
|
|
Pierre-Yves Chibon |
4cbbea |
query = query.filter(
|
|
Pierre-Yves Chibon |
4cbbea |
model.User.user.like(pattern)
|
|
Pierre-Yves Chibon |
4cbbea |
)
|
|
Pierre-Yves Chibon |
4cbbea |
|
|
Pierre-Yves Chibon |
de2a45 |
if any([username, email, token]):
|
|
Pierre-Yves Chibon |
de2a45 |
output = query.first()
|
|
Pierre-Yves Chibon |
de2a45 |
else:
|
|
Pierre-Yves Chibon |
de2a45 |
output = query.all()
|
|
Pierre-Yves Chibon |
de2a45 |
|
|
Pierre-Yves Chibon |
de2a45 |
return output
|
|
Pierre-Yves Chibon |
556d85 |
|
|
Pierre-Yves Chibon |
f365ae |
|
|
Patrick Uiterwijk |
073828 |
def is_valid_ssh_key(key):
|
|
Patrick Uiterwijk |
073828 |
key = key.strip()
|
|
Patrick Uiterwijk |
073828 |
if not key:
|
|
Patrick Uiterwijk |
073828 |
return None
|
|
Patrick Uiterwijk |
cf336e |
with tempfile.TemporaryFile() as f:
|
|
Pierre-Yves Chibon |
695680 |
f.write(key.encode('utf-8'))
|
|
Patrick Uiterwijk |
cf336e |
f.seek(0)
|
|
Patrick Uiterwijk |
cf336e |
proc = subprocess.Popen(['/usr/bin/ssh-keygen', '-l', '-f',
|
|
Patrick Uiterwijk |
cf336e |
'/dev/stdin'],
|
|
Patrick Uiterwijk |
cf336e |
stdin=f,
|
|
Patrick Uiterwijk |
cf336e |
stdout=subprocess.PIPE,
|
|
Patrick Uiterwijk |
cf336e |
stderr=subprocess.PIPE)
|
|
Patrick Uiterwijk |
cf336e |
proc.communicate()
|
|
Patrick Uiterwijk |
073828 |
return proc.returncode == 0
|
|
Patrick Uiterwijk |
073828 |
|
|
Patrick Uiterwijk |
073828 |
|
|
Patrick Uiterwijk |
f8d590 |
def are_valid_ssh_keys(keys):
|
|
Patrick Uiterwijk |
f8d590 |
return all([is_valid_ssh_key(key) is not False
|
|
Patrick Uiterwijk |
f8d590 |
for key in keys.split('\n')])
|
|
Patrick Uiterwijk |
f8d590 |
|
|
Patrick Uiterwijk |
f8d590 |
|
|
Patrick Uiterwijk |
0e5f4a |
def create_user_ssh_keys_on_disk(user, gitolite_keydir):
|
|
Pierre-Yves Chibon |
d1e053 |
''' Create the ssh keys for the user on the specific folder.
|
|
Pierre-Yves Chibon |
d1e053 |
|
|
Pierre-Yves Chibon |
d1e053 |
This is the method allowing to have multiple ssh keys per user.
|
|
Pierre-Yves Chibon |
d1e053 |
'''
|
|
Patrick Uiterwijk |
0e5f4a |
if gitolite_keydir:
|
|
Patrick Uiterwijk |
0e5f4a |
# First remove any old keyfiles for the user
|
|
Patrick Uiterwijk |
0e5f4a |
# Assumption: we populated the keydir. This means that files
|
|
Patrick Uiterwijk |
0e5f4a |
# will be in 0/<username>.pub, ..., and not in any deeper</username>
|
|
Patrick Uiterwijk |
0e5f4a |
# directory structures. Also, this means that if a user
|
|
Patrick Uiterwijk |
0e5f4a |
# had 5 lines, they will be up to at most keys_4/<username>.pub,</username>
|
|
Patrick Uiterwijk |
0e5f4a |
# meaning that if a user is not in keys_/<username>.pub, with</username>
|
|
Patrick Uiterwijk |
0e5f4a |
# i being any integer, the user is most certainly not in
|
|
Patrick Uiterwijk |
0e5f4a |
# keys_<i+1>/<username>.pub.</username></i+1>
|
|
Patrick Uiterwijk |
0e5f4a |
i = 0
|
|
Patrick Uiterwijk |
0e5f4a |
keyline_file = os.path.join(gitolite_keydir,
|
|
Patrick Uiterwijk |
0e5f4a |
'keys_%i' % i,
|
|
Patrick Uiterwijk |
0e5f4a |
'%s.pub' % user.user)
|
|
Patrick Uiterwijk |
0e5f4a |
while os.path.exists(keyline_file):
|
|
Pierre-Yves Chibon |
11f8ab |
os.unlink(keyline_file)
|
|
Patrick Uiterwijk |
0e5f4a |
i += 1
|
|
Patrick Uiterwijk |
0e5f4a |
keyline_file = os.path.join(gitolite_keydir,
|
|
Patrick Uiterwijk |
0e5f4a |
'keys_%i' % i,
|
|
Patrick Uiterwijk |
0e5f4a |
'%s.pub' % user.user)
|
|
Patrick Uiterwijk |
0e5f4a |
|
|
Patrick Uiterwijk |
0e5f4a |
# Now let's create new keyfiles for the user
|
|
Patrick Uiterwijk |
0e5f4a |
keys = user.public_ssh_key.split('\n')
|
|
Patrick Uiterwijk |
0e5f4a |
for i in range(len(keys)):
|
|
Pierre-Yves Chibon |
57803d |
if not keys[i]:
|
|
Pierre-Yves Chibon |
57803d |
continue
|
|
Patrick Uiterwijk |
073828 |
if not is_valid_ssh_key(keys[i]):
|
|
Patrick Uiterwijk |
073828 |
continue
|
|
Patrick Uiterwijk |
0e5f4a |
keyline_dir = os.path.join(gitolite_keydir, 'keys_%i' % i)
|
|
Patrick Uiterwijk |
0e5f4a |
if not os.path.exists(keyline_dir):
|
|
Patrick Uiterwijk |
0e5f4a |
os.mkdir(keyline_dir)
|
|
Patrick Uiterwijk |
0e5f4a |
keyfile = os.path.join(keyline_dir, '%s.pub' % user.user)
|
|
Patrick Uiterwijk |
0e5f4a |
with open(keyfile, 'w') as stream:
|
|
Patrick Uiterwijk |
0e5f4a |
stream.write(keys[i].strip().encode('UTF-8'))
|
|
Pierre-Yves Chibon |
556d85 |
|
|
Pierre-Yves Chibon |
f365ae |
|
|
Pierre-Yves Chibon |
27fdde |
def add_issue_comment(session, issue, comment, user, ticketfolder,
|
|
Pierre-Yves Chibon |
63d32c |
notify=True, date_created=None, notification=False):
|
|
Pierre-Yves Chibon |
03c11f |
''' Add a comment to an issue. '''
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
e1372f |
|
|
Pierre-Yves Chibon |
00c3f0 |
issue_comment = model.IssueComment(
|
|
Pierre-Yves Chibon |
cc99df |
issue_uid=issue.uid,
|
|
Pierre-Yves Chibon |
359db9 |
comment=comment,
|
|
Pierre-Yves Chibon |
e1372f |
user_id=user_obj.id,
|
|
Clement Verna |
f45e89 |
date_created=date_created,
|
|
Pierre-Yves Chibon |
63d32c |
notification=notification,
|
|
Pierre-Yves Chibon |
359db9 |
)
|
|
Pierre-Yves Chibon |
00c3f0 |
session.add(issue_comment)
|
|
Pierre-Yves Chibon |
db8de8 |
# Make sure we won't have SQLAlchemy error before we continue
|
|
Pierre-Yves Chibon |
44a755 |
session.commit()
|
|
Pierre-Yves Chibon |
359db9 |
|
|
Pierre-Yves Chibon |
fe5017 |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
f7d56f |
issue, repo=issue.project, repofolder=ticketfolder)
|
|
Pierre-Yves Chibon |
a34835 |
|
|
Pierre-Yves Chibon |
27fdde |
if notify:
|
|
Pierre-Yves Chibon |
fe5017 |
pagure.lib.notify.notify_new_comment(issue_comment, user=user_obj)
|
|
Pierre-Yves Chibon |
4b55b4 |
|
|
Pierre-Yves Chibon |
399b0f |
if not issue.private:
|
|
Pierre-Yves Chibon |
c898e5 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
c898e5 |
issue.project,
|
|
Pierre-Yves Chibon |
c898e5 |
topic='issue.comment.added',
|
|
Pierre-Yves Chibon |
c898e5 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
issue=issue.to_json(public=True),
|
|
Pierre-Yves Chibon |
972598 |
project=issue.project.to_json(public=True),
|
|
Pierre-Yves Chibon |
399b0f |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
0ce3a2 |
)
|
|
Pierre-Yves Chibon |
0ce3a2 |
|
|
Pierre-Yves Chibon |
2e464a |
if REDIS:
|
|
Pierre-Yves Chibon |
b7e379 |
if issue.private:
|
|
Pierre-Yves Chibon |
8e41fb |
REDIS.publish('pagure.%s' % issue.uid, json.dumps({
|
|
Pierre-Yves Chibon |
0d9165 |
'issue': 'private',
|
|
Pierre-Yves Chibon |
0d9165 |
'comment_id': issue_comment.id,
|
|
Pierre-Yves Chibon |
0d9165 |
}))
|
|
Pierre-Yves Chibon |
b7e379 |
else:
|
|
Pierre-Yves Chibon |
8e41fb |
REDIS.publish('pagure.%s' % issue.uid, json.dumps({
|
|
Pierre-Yves Chibon |
59df71 |
'comment_id': issue_comment.id,
|
|
Pierre-Yves Chibon |
0110a9 |
'issue_id': issue.id,
|
|
Pierre-Yves Chibon |
e1f29a |
'project': issue.project.fullname,
|
|
Pierre-Yves Chibon |
b7e379 |
'comment_added': text2markdown(issue_comment.comment),
|
|
Pierre-Yves Chibon |
b7e379 |
'comment_user': issue_comment.user.user,
|
|
Pierre-Yves Chibon |
0ee9f8 |
'avatar_url': avatar_url_from_openid(
|
|
Pierre-Yves Chibon |
0ee9f8 |
issue_comment.user.default_email, size=16),
|
|
Pierre-Yves Chibon |
b7e379 |
'comment_date': issue_comment.date_created.strftime(
|
|
Pierre-Yves Chibon |
c1c354 |
'%Y-%m-%d %H:%M:%S'),
|
|
Pierre-Yves Chibon |
63d32c |
'notification': notification,
|
|
Pierre-Yves Chibon |
b7e379 |
}))
|
|
Pierre-Yves Chibon |
72a8e7 |
|
|
Pierre-Yves Chibon |
359db9 |
return 'Comment added'
|
|
Pierre-Yves Chibon |
359db9 |
|
|
Pierre-Yves Chibon |
359db9 |
|
|
Pierre-Yves Chibon |
2e464a |
def add_tag_obj(session, obj, tags, user, ticketfolder):
|
|
Pierre-Yves Chibon |
931b1d |
''' Add a tag to an object (either an issue or a project). '''
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
aafc66 |
|
|
Pierre-Yves Chibon |
e1b51e |
if isinstance(tags, basestring):
|
|
Pierre-Yves Chibon |
e1b51e |
tags = [tags]
|
|
Pierre-Yves Chibon |
e1b51e |
|
|
Pierre-Yves Chibon |
e1b51e |
added_tags = []
|
|
Pierre-Yves Chibon |
931b1d |
for objtag in tags:
|
|
Pierre-Yves Chibon |
931b1d |
objtag = objtag.strip()
|
|
Pierre-Yves Chibon |
e1b51e |
known = False
|
|
Pierre-Yves Chibon |
931b1d |
for tagobj in obj.tags:
|
|
Pierre-Yves Chibon |
931b1d |
if tagobj.tag == objtag:
|
|
Pierre-Yves Chibon |
e1b51e |
known = True
|
|
Pierre-Yves Chibon |
e1b51e |
|
|
Pierre-Yves Chibon |
e1b51e |
if known:
|
|
Pierre-Yves Chibon |
e1b51e |
continue
|
|
Pierre-Yves Chibon |
e1b51e |
|
|
Pierre-Yves Chibon |
931b1d |
tagobj = get_tag(session, objtag)
|
|
Pierre-Yves Chibon |
e1b51e |
if not tagobj:
|
|
Pierre-Yves Chibon |
931b1d |
tagobj = model.Tag(tag=objtag)
|
|
Pierre-Yves Chibon |
e1b51e |
session.add(tagobj)
|
|
Pierre-Yves Chibon |
e1b51e |
session.flush()
|
|
Pierre-Yves Chibon |
e1b51e |
|
|
Pierre-Yves Chibon |
b0ba8a |
if isinstance(obj, model.Issue):
|
|
Pierre-Yves Chibon |
931b1d |
dbobjtag = model.TagIssue(
|
|
Pierre-Yves Chibon |
292bbc |
issue_uid=obj.uid,
|
|
Pierre-Yves Chibon |
931b1d |
tag=tagobj.tag,
|
|
Pierre-Yves Chibon |
931b1d |
)
|
|
Pierre-Yves Chibon |
b0ba8a |
if isinstance(obj, model.Project):
|
|
Pierre-Yves Chibon |
931b1d |
dbobjtag = model.TagProject(
|
|
Pierre-Yves Chibon |
931b1d |
project_id=obj.id,
|
|
Pierre-Yves Chibon |
931b1d |
tag=tagobj.tag,
|
|
Pierre-Yves Chibon |
931b1d |
)
|
|
Pierre-Yves Chibon |
931b1d |
|
|
Pierre-Yves Chibon |
931b1d |
session.add(dbobjtag)
|
|
Pierre-Yves Chibon |
db8de8 |
# Make sure we won't have SQLAlchemy error before we continue
|
|
Pierre-Yves Chibon |
12bd3d |
session.flush()
|
|
Pierre-Yves Chibon |
e1b51e |
added_tags.append(tagobj.tag)
|
|
Pierre-Yves Chibon |
aafc66 |
|
|
Pierre-Yves Chibon |
b0ba8a |
if isinstance(obj, model.Issue):
|
|
Pierre-Yves Chibon |
931b1d |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
292bbc |
obj, repo=obj.project, repofolder=ticketfolder)
|
|
Pierre-Yves Chibon |
aafc66 |
|
|
Pierre-Yves Chibon |
292bbc |
if not obj.private:
|
|
Pierre-Yves Chibon |
931b1d |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
292bbc |
obj.project,
|
|
Pierre-Yves Chibon |
931b1d |
topic='issue.tag.added',
|
|
Pierre-Yves Chibon |
931b1d |
msg=dict(
|
|
Pierre-Yves Chibon |
292bbc |
issue=obj.to_json(public=True),
|
|
Pierre-Yves Chibon |
292bbc |
project=obj.project.to_json(public=True),
|
|
Pierre-Yves Chibon |
931b1d |
tags=added_tags,
|
|
Pierre-Yves Chibon |
931b1d |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
51719b |
)
|
|
Pierre-Yves Chibon |
0ce3a2 |
|
|
Pierre-Yves Chibon |
482d84 |
# Send notification for the event-source server
|
|
Pierre-Yves Chibon |
2e464a |
if REDIS:
|
|
Pierre-Yves Chibon |
8e41fb |
REDIS.publish('pagure.%s' % obj.uid, json.dumps(
|
|
Pierre-Yves Chibon |
8e41fb |
{'added_tags': added_tags}))
|
|
Pierre-Yves Chibon |
26753b |
|
|
Pierre-Yves Chibon |
e1b51e |
if added_tags:
|
|
Pierre-Yves Chibon |
e1b51e |
return 'Tag added: %s' % ', '.join(added_tags)
|
|
Pierre-Yves Chibon |
e1b51e |
else:
|
|
Pierre-Yves Chibon |
e1b51e |
return 'Nothing to add'
|
|
Pierre-Yves Chibon |
aafc66 |
|
|
Pierre-Yves Chibon |
aafc66 |
|
|
Clement Verna |
b46f3d |
def add_issue_assignee(session, issue, assignee, user, ticketfolder,
|
|
Clement Verna |
b46f3d |
notify=True):
|
|
Pierre-Yves Chibon |
cdaaf3 |
''' Add an assignee to an issue, in other words, assigned an issue. '''
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
153903 |
|
|
Pierre-Yves Chibon |
b53eb8 |
if assignee is None and issue.assignee is not None:
|
|
Pierre-Yves Chibon |
e39d28 |
issue.assignee_id = None
|
|
Pierre-Yves Chibon |
e39d28 |
session.add(issue)
|
|
Pierre-Yves Chibon |
e39d28 |
session.commit()
|
|
Pierre-Yves Chibon |
fe5017 |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
2da35f |
issue, repo=issue.project, repofolder=ticketfolder)
|
|
Pierre-Yves Chibon |
e39d28 |
|
|
Clement Verna |
b46f3d |
if notify:
|
|
Clement Verna |
b46f3d |
pagure.lib.notify.notify_assigned_issue(issue, None, user_obj)
|
|
Clement Verna |
ef0ab2 |
|
|
Clement Verna |
ef0ab2 |
if not issue.private:
|
|
Clement Verna |
ef0ab2 |
pagure.lib.notify.log(
|
|
Clement Verna |
ef0ab2 |
issue.project,
|
|
Clement Verna |
ef0ab2 |
topic='issue.assigned.reset',
|
|
Clement Verna |
ef0ab2 |
msg=dict(
|
|
Clement Verna |
ef0ab2 |
issue=issue.to_json(public=True),
|
|
Clement Verna |
ef0ab2 |
project=issue.project.to_json(public=True),
|
|
Clement Verna |
ef0ab2 |
agent=user_obj.username,
|
|
Clement Verna |
ef0ab2 |
),
|
|
Clement Verna |
ef0ab2 |
redis=REDIS,
|
|
Clement Verna |
ef0ab2 |
)
|
|
Clement Verna |
ef0ab2 |
|
|
Clement Verna |
ef0ab2 |
# Send notification for the event-source server
|
|
Clement Verna |
ef0ab2 |
if REDIS:
|
|
Clement Verna |
ef0ab2 |
REDIS.publish('pagure.%s' % issue.uid, json.dumps(
|
|
Clement Verna |
ef0ab2 |
{'unassigned': '-'}))
|
|
Clement Verna |
ef0ab2 |
|
|
Clement Verna |
ef0ab2 |
return 'Assignee reset'
|
|
Pierre-Yves Chibon |
b53eb8 |
elif assignee is None and issue.assignee is None:
|
|
Pierre-Yves Chibon |
25a5fe |
return
|
|
Pierre-Yves Chibon |
e39d28 |
|
|
Pierre-Yves Chibon |
cdaaf3 |
# Validate the assignee
|
|
Pierre-Yves Chibon |
6aa385 |
assignee_obj = get_user(session, assignee)
|
|
Pierre-Yves Chibon |
cdaaf3 |
|
|
Pierre-Yves Chibon |
153903 |
if issue.assignee_id != assignee_obj.id:
|
|
Pierre-Yves Chibon |
153903 |
issue.assignee_id = assignee_obj.id
|
|
Pierre-Yves Chibon |
cdaaf3 |
session.add(issue)
|
|
Pierre-Yves Chibon |
cdaaf3 |
session.flush()
|
|
Pierre-Yves Chibon |
fe5017 |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
2da35f |
issue, repo=issue.project, repofolder=ticketfolder)
|
|
Clement Verna |
ef0ab2 |
if notify:
|
|
Clement Verna |
ef0ab2 |
pagure.lib.notify.notify_assigned_issue(
|
|
Clement Verna |
ef0ab2 |
issue, assignee_obj, user_obj)
|
|
Pierre-Yves Chibon |
ff30f1 |
|
|
Pierre-Yves Chibon |
006a5d |
if not issue.private:
|
|
Pierre-Yves Chibon |
c898e5 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
c898e5 |
issue.project,
|
|
Pierre-Yves Chibon |
c898e5 |
topic='issue.assigned.added',
|
|
Pierre-Yves Chibon |
c898e5 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
issue=issue.to_json(public=True),
|
|
Pierre-Yves Chibon |
972598 |
project=issue.project.to_json(public=True),
|
|
Pierre-Yves Chibon |
006a5d |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
0ce3a2 |
)
|
|
Pierre-Yves Chibon |
0ce3a2 |
|
|
Pierre-Yves Chibon |
482d84 |
# Send notification for the event-source server
|
|
Pierre-Yves Chibon |
2e464a |
if REDIS:
|
|
Pierre-Yves Chibon |
8e41fb |
REDIS.publish('pagure.%s' % issue.uid, json.dumps(
|
|
Pierre-Yves Chibon |
ca0907 |
{'assigned': assignee_obj.to_json(public=True)}))
|
|
Pierre-Yves Chibon |
ca0907 |
|
|
Pierre-Yves Chibon |
cdaaf3 |
return 'Issue assigned'
|
|
Pierre-Yves Chibon |
cdaaf3 |
|
|
Pierre-Yves Chibon |
723e4a |
|
|
Pierre-Yves Chibon |
b1fc61 |
def add_pull_request_assignee(
|
|
Pierre-Yves Chibon |
2e464a |
session, request, assignee, user, requestfolder):
|
|
Pierre-Yves Chibon |
4c8e72 |
''' Add an assignee to a request, in other words, assigned an issue. '''
|
|
Pierre-Yves Chibon |
6aa385 |
get_user(session, assignee)
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
4c8e72 |
|
|
Pierre-Yves Chibon |
4c8e72 |
if assignee is None and request.assignee is not None:
|
|
Pierre-Yves Chibon |
4c8e72 |
request.assignee_id = None
|
|
Pierre-Yves Chibon |
4c8e72 |
session.add(request)
|
|
Pierre-Yves Chibon |
4c8e72 |
session.commit()
|
|
Pierre-Yves Chibon |
4c8e72 |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
4c8e72 |
request, repo=request.project, repofolder=requestfolder)
|
|
Pierre-Yves Chibon |
4c8e72 |
|
|
Pierre-Yves Chibon |
4c8e72 |
pagure.lib.notify.notify_assigned_request(request, None, user_obj)
|
|
Pierre-Yves Chibon |
c898e5 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
c898e5 |
request.project,
|
|
Pierre-Yves Chibon |
c898e5 |
topic='request.assigned.reset',
|
|
Pierre-Yves Chibon |
c898e5 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
request=request.to_json(public=True),
|
|
Pierre-Yves Chibon |
972598 |
project=request.project.to_json(public=True),
|
|
Pierre-Yves Chibon |
4c8e72 |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
4c8e72 |
)
|
|
Pierre-Yves Chibon |
4c8e72 |
|
|
Pierre-Yves Chibon |
4c8e72 |
return 'Request reset'
|
|
Pierre-Yves Chibon |
4c8e72 |
elif assignee is None and request.assignee is None:
|
|
Pierre-Yves Chibon |
4c8e72 |
return
|
|
Pierre-Yves Chibon |
4c8e72 |
|
|
Pierre-Yves Chibon |
4c8e72 |
# Validate the assignee
|
|
Pierre-Yves Chibon |
6aa385 |
assignee_obj = get_user(session, assignee)
|
|
Pierre-Yves Chibon |
4c8e72 |
|
|
Pierre-Yves Chibon |
4c8e72 |
if request.assignee_id != assignee_obj.id:
|
|
Pierre-Yves Chibon |
4c8e72 |
request.assignee_id = assignee_obj.id
|
|
Pierre-Yves Chibon |
4c8e72 |
session.add(request)
|
|
Pierre-Yves Chibon |
4c8e72 |
session.flush()
|
|
Pierre-Yves Chibon |
4c8e72 |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
4c8e72 |
request, repo=request.project, repofolder=requestfolder)
|
|
Pierre-Yves Chibon |
4c8e72 |
|
|
Pierre-Yves Chibon |
4c8e72 |
pagure.lib.notify.notify_assigned_request(
|
|
Pierre-Yves Chibon |
4c8e72 |
request, assignee_obj, user_obj)
|
|
Pierre-Yves Chibon |
4c8e72 |
|
|
Pierre-Yves Chibon |
c898e5 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
c898e5 |
request.project,
|
|
Pierre-Yves Chibon |
c898e5 |
topic='request.assigned.added',
|
|
Pierre-Yves Chibon |
c898e5 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
request=request.to_json(public=True),
|
|
Pierre-Yves Chibon |
972598 |
project=request.project.to_json(public=True),
|
|
Pierre-Yves Chibon |
4c8e72 |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
4c8e72 |
)
|
|
Pierre-Yves Chibon |
4c8e72 |
|
|
Pierre-Yves Chibon |
4c8e72 |
return 'Request assigned'
|
|
Pierre-Yves Chibon |
cdaaf3 |
|
|
Pierre-Yves Chibon |
723e4a |
|
|
Pierre-Yves Chibon |
85ee44 |
def add_issue_dependency(
|
|
Pierre-Yves Chibon |
2e464a |
session, issue, issue_blocked, user, ticketfolder):
|
|
Pierre-Yves Chibon |
e523bf |
''' Add a dependency between two issues. '''
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
ad1385 |
|
|
Pierre-Yves Chibon |
ed19c4 |
if issue.uid == issue_blocked.uid:
|
|
Pierre-Yves Chibon |
fe5017 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
ed19c4 |
'An issue cannot depend on itself'
|
|
Pierre-Yves Chibon |
ed19c4 |
)
|
|
Pierre-Yves Chibon |
ed19c4 |
|
|
Pierre-Yves Chibon |
ad1385 |
if issue_blocked not in issue.children:
|
|
Pierre-Yves Chibon |
ad1385 |
i2i = model.IssueToIssue(
|
|
Pierre-Yves Chibon |
ad1385 |
parent_issue_id=issue_blocked.uid,
|
|
Pierre-Yves Chibon |
ad1385 |
child_issue_id=issue.uid
|
|
Pierre-Yves Chibon |
ad1385 |
)
|
|
Pierre-Yves Chibon |
ad1385 |
session.add(i2i)
|
|
Pierre-Yves Chibon |
db8de8 |
# Make sure we won't have SQLAlchemy error before we continue
|
|
Pierre-Yves Chibon |
ad1385 |
session.flush()
|
|
Pierre-Yves Chibon |
fe5017 |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
2da35f |
issue,
|
|
Pierre-Yves Chibon |
2da35f |
repo=issue.project,
|
|
Pierre-Yves Chibon |
2da35f |
repofolder=ticketfolder)
|
|
Pierre-Yves Chibon |
fe5017 |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
ad1385 |
issue_blocked,
|
|
Pierre-Yves Chibon |
ad1385 |
repo=issue_blocked.project,
|
|
Pierre-Yves Chibon |
2da35f |
repofolder=ticketfolder)
|
|
Pierre-Yves Chibon |
ad1385 |
|
|
Pierre-Yves Chibon |
fe5017 |
#pagure.lib.notify.notify_assigned_issue(issue, user_obj)
|
|
Pierre-Yves Chibon |
fe5017 |
#pagure.lib.notify.notify_assigned_issue(issue_blocked, user_obj)
|
|
Pierre-Yves Chibon |
ad1385 |
|
|
Pierre-Yves Chibon |
09dfdc |
if not issue.private:
|
|
Pierre-Yves Chibon |
c898e5 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
c898e5 |
issue.project,
|
|
Pierre-Yves Chibon |
c898e5 |
topic='issue.dependency.added',
|
|
Pierre-Yves Chibon |
c898e5 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
issue=issue.to_json(public=True),
|
|
Pierre-Yves Chibon |
972598 |
project=issue.project.to_json(public=True),
|
|
Pierre-Yves Chibon |
f66b1e |
added_dependency=issue_blocked.id,
|
|
Pierre-Yves Chibon |
09dfdc |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
0ce3a2 |
)
|
|
Pierre-Yves Chibon |
0ce3a2 |
|
|
Pierre-Yves Chibon |
482d84 |
# Send notification for the event-source server
|
|
Pierre-Yves Chibon |
2e464a |
if REDIS:
|
|
Pierre-Yves Chibon |
8e41fb |
REDIS.publish('pagure.%s' % issue.uid, json.dumps({
|
|
Pierre-Yves Chibon |
85ee44 |
'added_dependency': issue_blocked.id,
|
|
Pierre-Yves Chibon |
85ee44 |
'issue_uid': issue.uid,
|
|
Pierre-Yves Chibon |
85ee44 |
'type': 'children',
|
|
Pierre-Yves Chibon |
85ee44 |
}))
|
|
Pierre-Yves Chibon |
8e41fb |
REDIS.publish('pagure.%s' % issue_blocked.uid, json.dumps({
|
|
Pierre-Yves Chibon |
85ee44 |
'added_dependency': issue.id,
|
|
Pierre-Yves Chibon |
85ee44 |
'issue_uid': issue_blocked.uid,
|
|
Pierre-Yves Chibon |
85ee44 |
'type': 'parent',
|
|
Pierre-Yves Chibon |
85ee44 |
}))
|
|
Pierre-Yves Chibon |
85ee44 |
|
|
Pierre-Yves Chibon |
7e765d |
return 'Dependency added'
|
|
Pierre-Yves Chibon |
ad1385 |
|
|
Pierre-Yves Chibon |
ad1385 |
|
|
Pierre-Yves Chibon |
85ee44 |
def remove_issue_dependency(
|
|
Pierre-Yves Chibon |
2e464a |
session, issue, issue_blocked, user, ticketfolder):
|
|
Pierre-Yves Chibon |
b49ea7 |
''' Remove a dependency between two issues. '''
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
b49ea7 |
|
|
Pierre-Yves Chibon |
b49ea7 |
if issue.uid == issue_blocked.uid:
|
|
Pierre-Yves Chibon |
fe5017 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
b49ea7 |
'An issue cannot depend on itself'
|
|
Pierre-Yves Chibon |
b49ea7 |
)
|
|
Pierre-Yves Chibon |
b49ea7 |
|
|
Pierre-Yves Chibon |
b49ea7 |
if issue_blocked in issue.children:
|
|
Pierre-Yves Chibon |
b8c7ae |
child_del = []
|
|
Pierre-Yves Chibon |
b49ea7 |
for child in issue.children:
|
|
Pierre-Yves Chibon |
b49ea7 |
if child.uid == issue_blocked.uid:
|
|
Pierre-Yves Chibon |
b8c7ae |
child_del.append(child.id)
|
|
Pierre-Yves Chibon |
b49ea7 |
issue.children.remove(child)
|
|
Pierre-Yves Chibon |
b49ea7 |
|
|
Pierre-Yves Chibon |
db8de8 |
# Make sure we won't have SQLAlchemy error before we continue
|
|
Pierre-Yves Chibon |
b49ea7 |
session.flush()
|
|
Pierre-Yves Chibon |
fe5017 |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
2da35f |
issue,
|
|
Pierre-Yves Chibon |
2da35f |
repo=issue.project,
|
|
Pierre-Yves Chibon |
2da35f |
repofolder=ticketfolder)
|
|
Pierre-Yves Chibon |
fe5017 |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
b49ea7 |
issue_blocked,
|
|
Pierre-Yves Chibon |
b49ea7 |
repo=issue_blocked.project,
|
|
Pierre-Yves Chibon |
2da35f |
repofolder=ticketfolder)
|
|
Pierre-Yves Chibon |
b49ea7 |
|
|
Pierre-Yves Chibon |
fe5017 |
#pagure.lib.notify.notify_assigned_issue(issue, user_obj)
|
|
Pierre-Yves Chibon |
fe5017 |
#pagure.lib.notify.notify_assigned_issue(issue_blocked, user_obj)
|
|
Pierre-Yves Chibon |
b49ea7 |
|
|
Pierre-Yves Chibon |
09dfdc |
if not issue.private:
|
|
Pierre-Yves Chibon |
c898e5 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
c898e5 |
issue.project,
|
|
Pierre-Yves Chibon |
c898e5 |
topic='issue.dependency.removed',
|
|
Pierre-Yves Chibon |
c898e5 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
issue=issue.to_json(public=True),
|
|
Pierre-Yves Chibon |
972598 |
project=issue.project.to_json(public=True),
|
|
Pierre-Yves Chibon |
b8c7ae |
removed_dependency=child_del,
|
|
Pierre-Yves Chibon |
09dfdc |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
0ce3a2 |
)
|
|
Pierre-Yves Chibon |
0ce3a2 |
|
|
Pierre-Yves Chibon |
482d84 |
# Send notification for the event-source server
|
|
Pierre-Yves Chibon |
2e464a |
if REDIS:
|
|
Pierre-Yves Chibon |
8e41fb |
REDIS.publish('pagure.%s' % issue.uid, json.dumps({
|
|
Pierre-Yves Chibon |
85ee44 |
'removed_dependency': child_del,
|
|
Pierre-Yves Chibon |
85ee44 |
'issue_uid': issue.uid,
|
|
Pierre-Yves Chibon |
85ee44 |
'type': 'children',
|
|
Pierre-Yves Chibon |
85ee44 |
}))
|
|
Pierre-Yves Chibon |
8e41fb |
REDIS.publish('pagure.%s' % issue_blocked.uid, json.dumps({
|
|
Pierre-Yves Chibon |
85ee44 |
'removed_dependency': issue.id,
|
|
Pierre-Yves Chibon |
85ee44 |
'issue_uid': issue_blocked.uid,
|
|
Pierre-Yves Chibon |
85ee44 |
'type': 'parent',
|
|
Pierre-Yves Chibon |
85ee44 |
}))
|
|
Pierre-Yves Chibon |
85ee44 |
|
|
Pierre-Yves Chibon |
b49ea7 |
return 'Dependency removed'
|
|
Pierre-Yves Chibon |
b49ea7 |
|
|
Pierre-Yves Chibon |
b49ea7 |
|
|
Pierre-Yves Chibon |
2e464a |
def remove_tags(session, project, tags, ticketfolder, user):
|
|
Pierre-Yves Chibon |
83cba8 |
''' Removes the specified tag of a project. '''
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
83cba8 |
|
|
Pierre-Yves Chibon |
83cba8 |
if not isinstance(tags, list):
|
|
Pierre-Yves Chibon |
83cba8 |
tags = [tags]
|
|
Pierre-Yves Chibon |
83cba8 |
|
|
Pierre-Yves Chibon |
3b7b2b |
issues = search_issues(session, project, closed=False, tags=tags)
|
|
Pierre-Yves Chibon |
3b7b2b |
issues.extend(search_issues(session, project, closed=True, tags=tags))
|
|
Pierre-Yves Chibon |
83cba8 |
|
|
Pierre-Yves Chibon |
83cba8 |
msgs = []
|
|
Pierre-Yves Chibon |
ba0f71 |
removed_tags = []
|
|
Pierre-Yves Chibon |
83cba8 |
if not issues:
|
|
Pierre-Yves Chibon |
fe5017 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
782b9c |
'No issue found with the tags: %s' % ', '.join(tags))
|
|
Pierre-Yves Chibon |
83cba8 |
else:
|
|
Pierre-Yves Chibon |
83cba8 |
for issue in issues:
|
|
Pierre-Yves Chibon |
782b9c |
for issue_tag in issue.tags:
|
|
Pierre-Yves Chibon |
83cba8 |
if issue_tag.tag in tags:
|
|
Pierre-Yves Chibon |
83cba8 |
tag = issue_tag.tag
|
|
Pierre-Yves Chibon |
ba0f71 |
removed_tags.append(tag)
|
|
Pierre-Yves Chibon |
83cba8 |
session.delete(issue_tag)
|
|
Pierre-Yves Chibon |
83cba8 |
msgs.append('Removed tag: %s' % tag)
|
|
Pierre-Yves Chibon |
fe5017 |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
2da35f |
issue, repo=issue.project, repofolder=ticketfolder)
|
|
Pierre-Yves Chibon |
b4ce96 |
|
|
Pierre-Yves Chibon |
c898e5 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
c898e5 |
project,
|
|
Pierre-Yves Chibon |
c898e5 |
topic='project.tag.removed',
|
|
Pierre-Yves Chibon |
c898e5 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
project=project.to_json(public=True),
|
|
Pierre-Yves Chibon |
0ce3a2 |
tags=removed_tags,
|
|
Pierre-Yves Chibon |
0ce3a2 |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
0ce3a2 |
)
|
|
Pierre-Yves Chibon |
0ce3a2 |
|
|
Pierre-Yves Chibon |
83cba8 |
return msgs
|
|
Pierre-Yves Chibon |
83cba8 |
|
|
Pierre-Yves Chibon |
83cba8 |
|
|
Pierre-Yves Chibon |
931b1d |
def remove_tags_obj(
|
|
Pierre-Yves Chibon |
2e464a |
session, obj, tags, ticketfolder, user):
|
|
Pierre-Yves Chibon |
931b1d |
''' Removes the specified tag(s) of a given object. '''
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
b2497a |
|
|
Pierre-Yves Chibon |
b2497a |
if isinstance(tags, basestring):
|
|
Pierre-Yves Chibon |
b2497a |
tags = [tags]
|
|
Pierre-Yves Chibon |
b2497a |
|
|
Pierre-Yves Chibon |
2d821e |
removed_tags = []
|
|
Pierre-Yves Chibon |
931b1d |
for objtag in obj.tags:
|
|
Pierre-Yves Chibon |
931b1d |
if objtag.tag in tags:
|
|
Pierre-Yves Chibon |
931b1d |
tag = objtag.tag
|
|
Pierre-Yves Chibon |
2d821e |
removed_tags.append(tag)
|
|
Pierre-Yves Chibon |
931b1d |
session.delete(objtag)
|
|
Pierre-Yves Chibon |
b2497a |
|
|
Pierre-Yves Chibon |
b0ba8a |
if isinstance(obj, model.Issue):
|
|
Pierre-Yves Chibon |
931b1d |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
292bbc |
obj, repo=obj.project, repofolder=ticketfolder)
|
|
Pierre-Yves Chibon |
b2497a |
|
|
Pierre-Yves Chibon |
931b1d |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
292bbc |
obj.project,
|
|
Pierre-Yves Chibon |
931b1d |
topic='issue.tag.removed',
|
|
Pierre-Yves Chibon |
931b1d |
msg=dict(
|
|
Pierre-Yves Chibon |
292bbc |
issue=obj.to_json(public=True),
|
|
Pierre-Yves Chibon |
292bbc |
project=obj.project.to_json(public=True),
|
|
Pierre-Yves Chibon |
931b1d |
tags=removed_tags,
|
|
Pierre-Yves Chibon |
931b1d |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
0ce3a2 |
)
|
|
Pierre-Yves Chibon |
0ce3a2 |
|
|
Pierre-Yves Chibon |
482d84 |
# Send notification for the event-source server
|
|
Pierre-Yves Chibon |
2e464a |
if REDIS:
|
|
Pierre-Yves Chibon |
8e41fb |
REDIS.publish('pagure.%s' % obj.uid, json.dumps(
|
|
Pierre-Yves Chibon |
931b1d |
{'removed_tags': removed_tags}))
|
|
Pierre-Yves Chibon |
9f629a |
|
|
Pierre-Yves Chibon |
a152f2 |
return 'Removed tag: %s' % ', '.join(removed_tags)
|
|
Pierre-Yves Chibon |
b2497a |
|
|
Pierre-Yves Chibon |
b2497a |
|
|
Pierre-Yves Chibon |
2e464a |
def edit_issue_tags(session, project, old_tag, new_tag, ticketfolder, user):
|
|
Pierre-Yves Chibon |
9d0844 |
''' Removes the specified tag of a project. '''
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
9d0844 |
|
|
Pierre-Yves Chibon |
58adfc |
if old_tag == new_tag:
|
|
Pierre-Yves Chibon |
fe5017 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
58adfc |
'Old tag: "%s" is the same as new tag "%s", nothing to change'
|
|
Pierre-Yves Chibon |
58adfc |
% (old_tag, new_tag))
|
|
Pierre-Yves Chibon |
9d0844 |
|
|
Pierre-Yves Chibon |
58adfc |
issues = search_issues(session, project, closed=False, tags=old_tag)
|
|
Pierre-Yves Chibon |
58adfc |
issues.extend(search_issues(session, project, closed=True, tags=old_tag))
|
|
Pierre-Yves Chibon |
9d0844 |
|
|
Pierre-Yves Chibon |
9d0844 |
msgs = []
|
|
Pierre-Yves Chibon |
9d0844 |
if not issues:
|
|
Pierre-Yves Chibon |
fe5017 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
9d0844 |
'No issue found with the tags: %s' % old_tag)
|
|
Pierre-Yves Chibon |
9d0844 |
else:
|
|
Pierre-Yves Chibon |
9d0844 |
tagobj = get_tag(session, new_tag)
|
|
Pierre-Yves Chibon |
9d0844 |
if not tagobj:
|
|
Pierre-Yves Chibon |
9d0844 |
tagobj = model.Tag(tag=new_tag)
|
|
Pierre-Yves Chibon |
9d0844 |
session.add(tagobj)
|
|
Pierre-Yves Chibon |
fb91fb |
session.flush()
|
|
Pierre-Yves Chibon |
9d0844 |
|
|
Pierre-Yves Chibon |
fb91fb |
for issue in set(issues):
|
|
Pierre-Yves Chibon |
333cb7 |
add = True
|
|
Pierre-Yves Chibon |
9d0844 |
# Drop the old tag
|
|
Pierre-Yves Chibon |
7d6d1f |
cnt = 0
|
|
Pierre-Yves Chibon |
7d6d1f |
while cnt < len(issue.tags):
|
|
Pierre-Yves Chibon |
7d6d1f |
issue_tag = issue.tags[cnt]
|
|
Pierre-Yves Chibon |
58adfc |
if issue_tag.tag == old_tag:
|
|
Pierre-Yves Chibon |
fb91fb |
issue.tags.remove(issue_tag)
|
|
Pierre-Yves Chibon |
7d6d1f |
cnt -= 1
|
|
Pierre-Yves Chibon |
fb91fb |
if issue_tag.tag == new_tag:
|
|
Pierre-Yves Chibon |
fb91fb |
add = False
|
|
Pierre-Yves Chibon |
7d6d1f |
cnt += 1
|
|
Pierre-Yves Chibon |
fb91fb |
session.flush()
|
|
Pierre-Yves Chibon |
333cb7 |
|
|
Pierre-Yves Chibon |
fb91fb |
# Add the new one
|
|
Pierre-Yves Chibon |
333cb7 |
if add:
|
|
Pierre-Yves Chibon |
333cb7 |
issue_tag = model.TagIssue(
|
|
Pierre-Yves Chibon |
58adfc |
issue_uid=issue.uid,
|
|
Pierre-Yves Chibon |
fb91fb |
tag=tagobj.tag
|
|
Pierre-Yves Chibon |
333cb7 |
)
|
|
Pierre-Yves Chibon |
333cb7 |
session.add(issue_tag)
|
|
Pierre-Yves Chibon |
fb91fb |
session.flush()
|
|
Pierre-Yves Chibon |
fb91fb |
|
|
Pierre-Yves Chibon |
b8c7ae |
# Update the git version
|
|
Pierre-Yves Chibon |
b8c7ae |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
b8c7ae |
issue, repo=issue.project, repofolder=ticketfolder)
|
|
Pierre-Yves Chibon |
b8c7ae |
|
|
Pierre-Yves Chibon |
fb91fb |
msgs.append('Edited tag: %s to %s' % (old_tag, new_tag))
|
|
Pierre-Yves Chibon |
c898e5 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
c898e5 |
project,
|
|
Pierre-Yves Chibon |
c898e5 |
topic='project.tag.edited',
|
|
Pierre-Yves Chibon |
c898e5 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
project=project.to_json(public=True),
|
|
Pierre-Yves Chibon |
fb91fb |
old_tag=old_tag,
|
|
Pierre-Yves Chibon |
fb91fb |
new_tag=new_tag,
|
|
Pierre-Yves Chibon |
fb91fb |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
fb91fb |
)
|
|
Pierre-Yves Chibon |
9d0844 |
|
|
Pierre-Yves Chibon |
9d0844 |
return msgs
|
|
Pierre-Yves Chibon |
9d0844 |
|
|
Pierre-Yves Chibon |
08c7a3 |
|
|
Pierre-Yves Chibon |
2e464a |
def add_user_to_project(session, project, new_user, user):
|
|
Pierre-Yves Chibon |
b9cb1e |
''' Add a specified user to a specified project. '''
|
|
Pierre-Yves Chibon |
6aa385 |
new_user_obj = get_user(session, new_user)
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
b9cb1e |
|
|
Pierre-Yves Chibon |
9ef892 |
users = set([user.user for user in project.users])
|
|
Pierre-Yves Chibon |
9ef892 |
users.add(project.user.user)
|
|
Pierre-Yves Chibon |
9ef892 |
if new_user in users:
|
|
Pierre-Yves Chibon |
9ef892 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
9ef892 |
'This user is already listed on this project.'
|
|
Pierre-Yves Chibon |
9ef892 |
)
|
|
Pierre-Yves Chibon |
9ef892 |
|
|
Pierre-Yves Chibon |
b9cb1e |
project_user = model.ProjectUser(
|
|
Pierre-Yves Chibon |
b9cb1e |
project_id=project.id,
|
|
Pierre-Yves Chibon |
c900bd |
user_id=new_user_obj.id,
|
|
Pierre-Yves Chibon |
b9cb1e |
)
|
|
Pierre-Yves Chibon |
b9cb1e |
session.add(project_user)
|
|
Pierre-Yves Chibon |
db8de8 |
# Make sure we won't have SQLAlchemy error before we continue
|
|
Pierre-Yves Chibon |
b9cb1e |
session.flush()
|
|
Pierre-Yves Chibon |
b9cb1e |
|
|
Pierre-Yves Chibon |
c898e5 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
c898e5 |
project,
|
|
Pierre-Yves Chibon |
c898e5 |
topic='project.user.added',
|
|
Pierre-Yves Chibon |
c898e5 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
project=project.to_json(public=True),
|
|
Pierre-Yves Chibon |
0ce3a2 |
new_user=new_user_obj.username,
|
|
Pierre-Yves Chibon |
0ce3a2 |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
0ce3a2 |
)
|
|
Pierre-Yves Chibon |
0ce3a2 |
|
|
Pierre-Yves Chibon |
c4933c |
return 'User added'
|
|
Pierre-Yves Chibon |
b9cb1e |
|
|
Pierre-Yves Chibon |
a8a719 |
|
|
Pierre-Yves Chibon |
754b1d |
def add_group_to_project(
|
|
Pierre-Yves Chibon |
754b1d |
session, project, new_group, user, create=False, is_admin=False):
|
|
Pierre-Yves Chibon |
41ae55 |
''' Add a specified group to a specified project. '''
|
|
Pierre-Yves Chibon |
8e5afe |
user_obj = search_user(session, username=user)
|
|
Pierre-Yves Chibon |
8e5afe |
if not user_obj:
|
|
Pierre-Yves Chibon |
8e5afe |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
8e5afe |
'No user %s found.' % user
|
|
Pierre-Yves Chibon |
8e5afe |
)
|
|
Pierre-Yves Chibon |
8e5afe |
|
|
Pierre-Yves Chibon |
754b1d |
group_obj = search_groups(session, group_name=new_group)
|
|
Pierre-Yves Chibon |
754b1d |
|
|
Pierre-Yves Chibon |
754b1d |
if not group_obj:
|
|
Pierre-Yves Chibon |
754b1d |
if create:
|
|
Pierre-Yves Chibon |
754b1d |
group_obj = pagure.lib.model.PagureGroup(
|
|
Pierre-Yves Chibon |
754b1d |
group_name=new_group,
|
|
Pierre-Yves Chibon |
754b1d |
group_type='user',
|
|
Pierre-Yves Chibon |
754b1d |
user_id=user_obj.id,
|
|
Pierre-Yves Chibon |
754b1d |
)
|
|
Pierre-Yves Chibon |
754b1d |
session.add(group_obj)
|
|
Pierre-Yves Chibon |
754b1d |
session.flush()
|
|
Pierre-Yves Chibon |
754b1d |
else:
|
|
Pierre-Yves Chibon |
754b1d |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
754b1d |
'No group %s found.' % new_group
|
|
Pierre-Yves Chibon |
754b1d |
)
|
|
Pierre-Yves Chibon |
754b1d |
|
|
Pierre-Yves Chibon |
754b1d |
if user_obj not in project.users \
|
|
Pierre-Yves Chibon |
754b1d |
and user_obj != project.user \
|
|
Pierre-Yves Chibon |
754b1d |
and not is_admin:
|
|
Pierre-Yves Chibon |
8e5afe |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
8e5afe |
'You are not allowed to add a group of users to this project'
|
|
Pierre-Yves Chibon |
8e5afe |
)
|
|
Pierre-Yves Chibon |
8e5afe |
|
|
Pierre-Yves Chibon |
41ae55 |
groups = set([group.group_name for group in project.groups])
|
|
Pierre-Yves Chibon |
41ae55 |
if new_group in groups:
|
|
Pierre-Yves Chibon |
41ae55 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
41ae55 |
'This group is already associated to this project.'
|
|
Pierre-Yves Chibon |
41ae55 |
)
|
|
Pierre-Yves Chibon |
41ae55 |
|
|
Pierre-Yves Chibon |
41ae55 |
project_group = model.ProjectGroup(
|
|
Pierre-Yves Chibon |
41ae55 |
project_id=project.id,
|
|
Pierre-Yves Chibon |
41ae55 |
group_id=group_obj.id,
|
|
Pierre-Yves Chibon |
41ae55 |
)
|
|
Pierre-Yves Chibon |
41ae55 |
session.add(project_group)
|
|
Pierre-Yves Chibon |
db8de8 |
# Make sure we won't have SQLAlchemy error before we continue
|
|
Pierre-Yves Chibon |
41ae55 |
session.flush()
|
|
Pierre-Yves Chibon |
41ae55 |
|
|
Pierre-Yves Chibon |
41ae55 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
41ae55 |
project,
|
|
Pierre-Yves Chibon |
41ae55 |
topic='project.group.added',
|
|
Pierre-Yves Chibon |
41ae55 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
project=project.to_json(public=True),
|
|
Pierre-Yves Chibon |
41ae55 |
new_group=group_obj.group_name,
|
|
Pierre-Yves Chibon |
41ae55 |
agent=user,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
41ae55 |
)
|
|
Pierre-Yves Chibon |
41ae55 |
|
|
Pierre-Yves Chibon |
41ae55 |
return 'Group added'
|
|
Pierre-Yves Chibon |
41ae55 |
|
|
Pierre-Yves Chibon |
41ae55 |
|
|
Pierre-Yves Chibon |
4fa09b |
def add_pull_request_comment(session, request, commit, tree_id, filename,
|
|
Pierre-Yves Chibon |
4fa09b |
row, comment, user, requestfolder,
|
|
Pierre-Yves Chibon |
4fa09b |
notify=True, notification=False):
|
|
Pierre-Yves Chibon |
2c11b4 |
''' Add a comment to a pull-request. '''
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
2c11b4 |
|
|
Pierre-Yves Chibon |
2c11b4 |
pr_comment = model.PullRequestComment(
|
|
Pierre-Yves Chibon |
446c3d |
pull_request_uid=request.uid,
|
|
Pierre-Yves Chibon |
2c11b4 |
commit_id=commit,
|
|
Pierre-Yves Chibon |
4fa09b |
tree_id=tree_id,
|
|
Pierre-Yves Chibon |
7df65e |
filename=filename,
|
|
Pierre-Yves Chibon |
2c11b4 |
line=row,
|
|
Pierre-Yves Chibon |
2c11b4 |
comment=comment,
|
|
Pierre-Yves Chibon |
2c11b4 |
user_id=user_obj.id,
|
|
Pierre-Yves Chibon |
81cbe0 |
notification=notification,
|
|
Pierre-Yves Chibon |
2c11b4 |
)
|
|
Pierre-Yves Chibon |
2c11b4 |
session.add(pr_comment)
|
|
Pierre-Yves Chibon |
db8de8 |
# Make sure we won't have SQLAlchemy error before we continue
|
|
Pierre-Yves Chibon |
2c11b4 |
session.flush()
|
|
Pierre-Yves Chibon |
2c11b4 |
|
|
Pierre-Yves Chibon |
fe5017 |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
a482cb |
request, repo=request.project, repofolder=requestfolder)
|
|
Pierre-Yves Chibon |
a1280f |
|
|
Pierre-Yves Chibon |
5f751f |
if notify:
|
|
Pierre-Yves Chibon |
5f751f |
pagure.lib.notify.notify_pull_request_comment(pr_comment, user_obj)
|
|
Pierre-Yves Chibon |
5f751f |
|
|
Pierre-Yves Chibon |
482d84 |
# Send notification for the event-source server
|
|
Pierre-Yves Chibon |
2e464a |
if REDIS:
|
|
Pierre-Yves Chibon |
50f9a3 |
comment_text = pr_comment.comment
|
|
Pierre-Yves Chibon |
50f9a3 |
if not notification:
|
|
Pierre-Yves Chibon |
50f9a3 |
comment_text = text2markdown(pr_comment.comment)
|
|
Pierre-Yves Chibon |
50f9a3 |
|
|
Pierre-Yves Chibon |
8e41fb |
REDIS.publish('pagure.%s' % request.uid, json.dumps({
|
|
Pierre-Yves Chibon |
3d167a |
'request_id': request.id,
|
|
Pierre-Yves Chibon |
50f9a3 |
'comment_added': comment_text,
|
|
Pierre-Yves Chibon |
62cec4 |
'comment_user': pr_comment.user.user,
|
|
Pierre-Yves Chibon |
3d167a |
'comment_id': pr_comment.id,
|
|
Pierre-Yves Chibon |
0ee9f8 |
'avatar_url': avatar_url_from_openid(
|
|
Pierre-Yves Chibon |
0ee9f8 |
pr_comment.user.default_email, size=16),
|
|
Pierre-Yves Chibon |
b13b92 |
'comment_date': pr_comment.date_created.strftime(
|
|
Pierre-Yves Chibon |
b13b92 |
'%Y-%m-%d %H:%M:%S'),
|
|
Pierre-Yves Chibon |
62cec4 |
'commit_id': commit,
|
|
Pierre-Yves Chibon |
62cec4 |
'filename': filename,
|
|
Pierre-Yves Chibon |
62cec4 |
'line': row,
|
|
Pierre-Yves Chibon |
50f9a3 |
'notification': notification,
|
|
Pierre-Yves Chibon |
62cec4 |
}))
|
|
Pierre-Yves Chibon |
62cec4 |
|
|
Pierre-Yves Chibon |
b65483 |
# Send notification to the CI server, if the comment added was a
|
|
Pierre-Yves Chibon |
b65483 |
# notification and the PR is still open
|
|
Pierre-Yves Chibon |
b65483 |
if notification and request.status == 'Open' \
|
|
Pierre-Yves Chibon |
b65483 |
and request.project.ci_hook and PAGURE_CI:
|
|
Pierre-Yves Chibon |
b65483 |
REDIS.publish('pagure.ci', json.dumps({
|
|
Pierre-Yves Chibon |
dcbd99 |
'ci_type': request.project.ci_hook.ci_type,
|
|
Pierre-Yves Chibon |
b65483 |
'pr': request.to_json(public=True, with_comments=False)
|
|
Pierre-Yves Chibon |
b65483 |
}))
|
|
Pierre-Yves Chibon |
b65483 |
|
|
Pierre-Yves Chibon |
c898e5 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
c898e5 |
request.project,
|
|
Pierre-Yves Chibon |
c898e5 |
topic='pull-request.comment.added',
|
|
Pierre-Yves Chibon |
c898e5 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
pullrequest=request.to_json(public=True),
|
|
Pierre-Yves Chibon |
0ce3a2 |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
0ce3a2 |
)
|
|
Pierre-Yves Chibon |
0ce3a2 |
|
|
Pierre-Yves Chibon |
2c11b4 |
return 'Comment added'
|
|
Pierre-Yves Chibon |
2c11b4 |
|
|
Pierre-Yves Chibon |
2c11b4 |
|
|
Pierre-Yves Chibon |
cb9dd7 |
def edit_comment(session, parent, comment, user,
|
|
Pierre-Yves Chibon |
9fd2e5 |
updated_comment, folder):
|
|
Pierre-Yves Chibon |
cb9dd7 |
''' Edit a comment. '''
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
farhaanbukhsh |
a04e02 |
comment.comment = updated_comment
|
|
farhaanbukhsh |
a04e02 |
comment.edited_on = datetime.datetime.utcnow()
|
|
farhaanbukhsh |
a04e02 |
comment.editor = user_obj
|
|
farhaanbukhsh |
a04e02 |
|
|
farhaanbukhsh |
a04e02 |
session.add(comment)
|
|
farhaanbukhsh |
a04e02 |
# Make sure we won't have SQLAlchemy error before we continue
|
|
farhaanbukhsh |
a04e02 |
session.flush()
|
|
farhaanbukhsh |
a04e02 |
|
|
farhaanbukhsh |
a04e02 |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
cb9dd7 |
parent, repo=parent.project, repofolder=folder)
|
|
Pierre-Yves Chibon |
cb9dd7 |
|
|
Pierre-Yves Chibon |
4a97e9 |
topic = 'unknown'
|
|
Pierre-Yves Chibon |
4a97e9 |
key = 'unknown'
|
|
Pierre-Yves Chibon |
4a97e9 |
id_ = 'unknown'
|
|
Pierre-Yves Chibon |
cb9dd7 |
if parent.isa == 'pull-request':
|
|
Pierre-Yves Chibon |
cb9dd7 |
topic = 'pull-request.comment.edited'
|
|
Pierre-Yves Chibon |
cb9dd7 |
key = 'pullrequest'
|
|
Pierre-Yves Chibon |
cb9dd7 |
id_ = 'request_id'
|
|
Pierre-Yves Chibon |
4a97e9 |
elif parent.isa == 'issue':
|
|
Pierre-Yves Chibon |
4a97e9 |
topic = 'issue.comment.edited'
|
|
Pierre-Yves Chibon |
4a97e9 |
key = 'issue'
|
|
Pierre-Yves Chibon |
4a97e9 |
id_ = 'issue_id'
|
|
farhaanbukhsh |
a04e02 |
|
|
farhaanbukhsh |
a04e02 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
cb9dd7 |
parent.project,
|
|
Pierre-Yves Chibon |
cb9dd7 |
topic=topic,
|
|
Pierre-Yves Chibon |
cb9dd7 |
msg={
|
|
Pierre-Yves Chibon |
799766 |
key: parent.to_json(public=True, with_comments=False),
|
|
Pierre-Yves Chibon |
9d71a7 |
'project': parent.project.to_json(public=True),
|
|
Pierre-Yves Chibon |
799766 |
'comment': comment.to_json(public=True),
|
|
Pierre-Yves Chibon |
cb9dd7 |
'agent': user_obj.username,
|
|
Pierre-Yves Chibon |
9fd2e5 |
},
|
|
Pierre-Yves Chibon |
9fd2e5 |
redis=REDIS,
|
|
farhaanbukhsh |
a04e02 |
)
|
|
farhaanbukhsh |
a04e02 |
|
|
Pierre-Yves Chibon |
9fd2e5 |
if REDIS:
|
|
Pierre-Yves Chibon |
1fc23f |
if parent.isa == 'issue' and comment.parent.private:
|
|
Pierre-Yves Chibon |
1fe5e5 |
REDIS.publish('pagure.%s' % comment.parent.uid, json.dumps({
|
|
Pierre-Yves Chibon |
798259 |
'comment_updated': 'private',
|
|
Pierre-Yves Chibon |
798259 |
'comment_id': comment.id,
|
|
Pierre-Yves Chibon |
798259 |
}))
|
|
Pierre-Yves Chibon |
798259 |
else:
|
|
Pierre-Yves Chibon |
798259 |
REDIS.publish('pagure.%s' % parent.uid, json.dumps({
|
|
Pierre-Yves Chibon |
798259 |
id_: len(parent.comments),
|
|
Pierre-Yves Chibon |
798259 |
'comment_updated': text2markdown(comment.comment),
|
|
Pierre-Yves Chibon |
798259 |
'comment_id': comment.id,
|
|
Pierre-Yves Chibon |
3d167a |
'parent_id': comment.parent.id,
|
|
Pierre-Yves Chibon |
798259 |
'comment_editor': user_obj.user,
|
|
Pierre-Yves Chibon |
0ee9f8 |
'avatar_url': avatar_url_from_openid(
|
|
Pierre-Yves Chibon |
0ee9f8 |
comment.user.default_email, size=16),
|
|
Pierre-Yves Chibon |
b13b92 |
'comment_date': comment.edited_on.strftime(
|
|
Pierre-Yves Chibon |
b13b92 |
'%Y-%m-%d %H:%M:%S'),
|
|
Pierre-Yves Chibon |
798259 |
}))
|
|
farhaanbukhsh |
a04e02 |
|
|
farhaanbukhsh |
a04e02 |
return "Comment updated"
|
|
farhaanbukhsh |
a04e02 |
|
|
farhaanbukhsh |
a04e02 |
|
|
Pierre-Yves Chibon |
393541 |
def add_pull_request_flag(session, request, username, percent, comment, url,
|
|
Pierre-Yves Chibon |
2e464a |
uid, user, requestfolder):
|
|
Pierre-Yves Chibon |
393541 |
''' Add a flag to a pull-request. '''
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
393541 |
|
|
Pierre-Yves Chibon |
032826 |
action = 'added'
|
|
Pierre-Yves Chibon |
032826 |
pr_flag = get_pull_request_flag_by_uid(session, uid)
|
|
Pierre-Yves Chibon |
032826 |
if pr_flag:
|
|
Pierre-Yves Chibon |
032826 |
action = 'updated'
|
|
Pierre-Yves Chibon |
032826 |
pr_flag.comment = comment
|
|
Pierre-Yves Chibon |
032826 |
pr_flag.percent = percent
|
|
Pierre-Yves Chibon |
032826 |
pr_flag.url = url
|
|
Pierre-Yves Chibon |
032826 |
else:
|
|
Pierre-Yves Chibon |
032826 |
pr_flag = model.PullRequestFlag(
|
|
Pierre-Yves Chibon |
032826 |
pull_request_uid=request.uid,
|
|
Pierre-Yves Chibon |
032826 |
uid=uid or uuid.uuid4().hex,
|
|
Pierre-Yves Chibon |
032826 |
username=username,
|
|
Pierre-Yves Chibon |
032826 |
percent=percent,
|
|
Pierre-Yves Chibon |
032826 |
comment=comment,
|
|
Pierre-Yves Chibon |
032826 |
url=url,
|
|
Pierre-Yves Chibon |
032826 |
user_id=user_obj.id,
|
|
Pierre-Yves Chibon |
032826 |
)
|
|
Pierre-Yves Chibon |
393541 |
session.add(pr_flag)
|
|
Pierre-Yves Chibon |
db8de8 |
# Make sure we won't have SQLAlchemy error before we continue
|
|
Pierre-Yves Chibon |
393541 |
session.flush()
|
|
Pierre-Yves Chibon |
393541 |
|
|
Pierre-Yves Chibon |
393541 |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
393541 |
request, repo=request.project, repofolder=requestfolder)
|
|
Pierre-Yves Chibon |
393541 |
|
|
Pierre-Yves Chibon |
393541 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
393541 |
request.project,
|
|
Pierre-Yves Chibon |
032826 |
topic='pull-request.flag.%s' % action,
|
|
Pierre-Yves Chibon |
393541 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
pullrequest=request.to_json(public=True),
|
|
Pierre-Yves Chibon |
972598 |
flag=pr_flag.to_json(public=True),
|
|
Pierre-Yves Chibon |
393541 |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
393541 |
)
|
|
Pierre-Yves Chibon |
393541 |
|
|
Pierre-Yves Chibon |
032826 |
return 'Flag %s' % action
|
|
Pierre-Yves Chibon |
393541 |
|
|
Pierre-Yves Chibon |
393541 |
|
|
Pierre-Yves Chibon |
cf78d3 |
def new_project(session, user, name, blacklist, allowed_prefix,
|
|
Pierre-Yves Chibon |
11c405 |
gitfolder, docfolder, ticketfolder, requestfolder,
|
|
Pierre-Yves Chibon |
164a57 |
description=None, url=None, avatar_email=None,
|
|
Pierre-Yves Chibon |
74baff |
parent_id=None, add_readme=False, userobj=None,
|
|
Pierre-Yves Chibon |
d3b817 |
prevent_40_chars=False, namespace=None):
|
|
Pierre-Yves Chibon |
d8110b |
''' Create a new project based on the information provided.
|
|
Pierre-Yves Chibon |
d8110b |
'''
|
|
Pierre-Yves Chibon |
d3b817 |
if name in blacklist or (
|
|
Pierre-Yves Chibon |
d3b817 |
namespace and '%s/%s' % (namespace, name) in blacklist):
|
|
Pierre-Yves Chibon |
29f5ac |
raise pagure.exceptions.RepoExistsException(
|
|
Pierre-Yves Chibon |
29f5ac |
'No project "%s" are allowed to be created due to potential '
|
|
Pierre-Yves Chibon |
29f5ac |
'conflicts in URLs with pagure itself' % name
|
|
Pierre-Yves Chibon |
29f5ac |
)
|
|
Pierre-Yves Chibon |
29f5ac |
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
cbe451 |
allowed_prefix = allowed_prefix + [grp for grp in user_obj.groups]
|
|
Pierre-Yves Chibon |
cf78d3 |
|
|
Pierre-Yves Chibon |
d3b817 |
if namespace and namespace not in allowed_prefix:
|
|
Pierre-Yves Chibon |
cf78d3 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
d3b817 |
'The namespace of your project must be in the list of allowed '
|
|
Pierre-Yves Chibon |
d3b817 |
'namespaces set by the admins of this pagure instance, or the '
|
|
Pierre-Yves Chibon |
d3b817 |
'name of a group of which you are a member.'
|
|
Pierre-Yves Chibon |
cf78d3 |
)
|
|
Pierre-Yves Chibon |
74baff |
|
|
Pierre-Yves Chibon |
d3b817 |
if len(name) == 40 and prevent_40_chars:
|
|
Pierre-Yves Chibon |
81d698 |
# We must block project with a name <foo>/<bar> where the length</bar></foo>
|
|
Pierre-Yves Chibon |
81d698 |
# of <bar> is exactly 40 characters long as this would otherwise</bar>
|
|
Pierre-Yves Chibon |
81d698 |
# conflict with the old URL schema used for commit that was
|
|
Pierre-Yves Chibon |
81d698 |
# <foo>/<commit hash="">. To keep backward compatibility, we have an</commit></foo>
|
|
Pierre-Yves Chibon |
81d698 |
# endpoint redirecting <foo>/<commit hash=""> to <foo>/c/<commit hash=""></commit></foo></commit></foo>
|
|
Pierre-Yves Chibon |
81d698 |
# available as an option.
|
|
Pierre-Yves Chibon |
18c7f9 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
18c7f9 |
'Your project name cannot have exactly 40 characters after '
|
|
Pierre-Yves Chibon |
18c7f9 |
'the `/`'
|
|
Pierre-Yves Chibon |
18c7f9 |
)
|
|
Pierre-Yves Chibon |
18c7f9 |
|
|
Pierre-Yves Chibon |
622d94 |
path = name
|
|
Pierre-Yves Chibon |
622d94 |
if namespace:
|
|
Pierre-Yves Chibon |
622d94 |
path = '%s/%s' % (namespace, name)
|
|
Pierre-Yves Chibon |
622d94 |
|
|
Pierre-Yves Chibon |
622d94 |
gitrepo = os.path.join(gitfolder, '%s.git' % path)
|
|
Pierre-Yves Chibon |
d8110b |
if os.path.exists(gitrepo):
|
|
Pierre-Yves Chibon |
fe5017 |
raise pagure.exceptions.RepoExistsException(
|
|
Pierre-Yves Chibon |
622d94 |
'The project repo "%s" already exists' % path
|
|
Pierre-Yves Chibon |
d8110b |
)
|
|
Pierre-Yves Chibon |
d8110b |
|
|
Pierre-Yves Chibon |
d8110b |
project = model.Project(
|
|
Pierre-Yves Chibon |
d8110b |
name=name,
|
|
Pierre-Yves Chibon |
d3b817 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
608900 |
description=description if description else None,
|
|
Pierre-Yves Chibon |
3fe3ff |
url=url if url else None,
|
|
Pierre-Yves Chibon |
3fe3ff |
avatar_email=avatar_email if avatar_email else None,
|
|
Pierre-Yves Chibon |
e1372f |
user_id=user_obj.id,
|
|
Pierre-Yves Chibon |
1cc0de |
parent_id=parent_id,
|
|
Pierre-Yves Chibon |
1cc0de |
hook_token=pagure.lib.login.id_generator(40)
|
|
Pierre-Yves Chibon |
d8110b |
)
|
|
Pierre-Yves Chibon |
d8110b |
session.add(project)
|
|
Pierre-Yves Chibon |
d8110b |
# Make sure we won't have SQLAlchemy error before we create the repo
|
|
Vivek Anand |
5ba62d |
session.flush()
|
|
Pierre-Yves Chibon |
d8110b |
|
|
Pierre-Yves Chibon |
afcf11 |
# Add the readme file if it was asked
|
|
Ryan Lerch |
743aca |
if not add_readme:
|
|
Ryan Lerch |
743aca |
pygit2.init_repository(gitrepo, bare=True)
|
|
Ryan Lerch |
743aca |
else:
|
|
Ryan Lerch |
348bee |
temp_gitrepo_path = tempfile.mkdtemp(prefix='pagure-')
|
|
Ryan Lerch |
743aca |
temp_gitrepo = pygit2.init_repository(temp_gitrepo_path, bare=False)
|
|
Vivek Anand |
97c5c3 |
author = userobj.fullname or userobj.user
|
|
Vivek Anand |
97c5c3 |
author_email = userobj.default_email
|
|
Vivek Anand |
97c5c3 |
if six.PY2:
|
|
Vivek Anand |
97c5c3 |
author = author.encode('utf-8')
|
|
Vivek Anand |
97c5c3 |
author_email = author_email.encode('utf-8')
|
|
Vivek Anand |
97c5c3 |
author = pygit2.Signature(author, author_email)
|
|
Pierre-Yves Chibon |
1c9f01 |
content = u"# %s\n\n%s" % (name, description)
|
|
Pierre-Yves Chibon |
f9f132 |
readme_file = os.path.join(temp_gitrepo.workdir, "README.md")
|
|
Pierre-Yves Chibon |
f9f132 |
with open(readme_file, 'wb') as stream:
|
|
Pierre-Yves Chibon |
d1e053 |
stream.write(content.encode('utf-8'))
|
|
Ryan Lerch |
743aca |
temp_gitrepo.index.add_all()
|
|
Ryan Lerch |
743aca |
temp_gitrepo.index.write()
|
|
Ryan Lerch |
743aca |
tree = temp_gitrepo.index.write_tree()
|
|
Pierre-Yves Chibon |
d1e053 |
temp_gitrepo.create_commit(
|
|
Pierre-Yves Chibon |
f9f132 |
'HEAD', author, author, 'Added the README', tree, [])
|
|
Ryan Lerch |
743aca |
pygit2.clone_repository(temp_gitrepo_path, gitrepo, bare=True)
|
|
Ryan Lerch |
743aca |
shutil.rmtree(temp_gitrepo_path)
|
|
Ryan Lerch |
743aca |
|
|
Pierre-Yves Chibon |
afcf11 |
# Make the repo exportable via apache
|
|
Pierre-Yves Chibon |
7546bb |
http_clone_file = os.path.join(gitrepo, 'git-daemon-export-ok')
|
|
Pierre-Yves Chibon |
7546bb |
if not os.path.exists(http_clone_file):
|
|
Pierre-Yves Chibon |
7546bb |
with open(http_clone_file, 'w') as stream:
|
|
Pierre-Yves Chibon |
7546bb |
pass
|
|
Pierre-Yves Chibon |
d8110b |
|
|
Pierre-Yves Chibon |
18042a |
docrepo = os.path.join(docfolder, project.path)
|
|
Pierre-Yves Chibon |
18042a |
if os.path.exists(docrepo):
|
|
Pierre-Yves Chibon |
18042a |
shutil.rmtree(gitrepo)
|
|
Pierre-Yves Chibon |
fe5017 |
raise pagure.exceptions.RepoExistsException(
|
|
Pierre-Yves Chibon |
ca47fa |
'The docs repo "%s" already exists' % project.path
|
|
Pierre-Yves Chibon |
6160b6 |
)
|
|
Pierre-Yves Chibon |
18042a |
pygit2.init_repository(docrepo, bare=True)
|
|
Pierre-Yves Chibon |
6160b6 |
|
|
Pierre-Yves Chibon |
18042a |
ticketrepo = os.path.join(ticketfolder, project.path)
|
|
Pierre-Yves Chibon |
18042a |
if os.path.exists(ticketrepo):
|
|
Pierre-Yves Chibon |
18042a |
shutil.rmtree(gitrepo)
|
|
Pierre-Yves Chibon |
18042a |
shutil.rmtree(docrepo)
|
|
Pierre-Yves Chibon |
fe5017 |
raise pagure.exceptions.RepoExistsException(
|
|
Pierre-Yves Chibon |
49b899 |
'The tickets repo "%s" already exists' % project.path
|
|
Pierre-Yves Chibon |
49b899 |
)
|
|
Pierre-Yves Chibon |
f43a32 |
pygit2.init_repository(
|
|
Pierre-Yves Chibon |
a0c6e1 |
ticketrepo, bare=True,
|
|
Pierre-Yves Chibon |
a0c6e1 |
mode=pygit2.C.GIT_REPOSITORY_INIT_SHARED_GROUP)
|
|
Pierre-Yves Chibon |
49b899 |
|
|
Pierre-Yves Chibon |
11c405 |
requestrepo = os.path.join(requestfolder, project.path)
|
|
Pierre-Yves Chibon |
11c405 |
if os.path.exists(requestrepo):
|
|
Pierre-Yves Chibon |
11c405 |
shutil.rmtree(gitrepo)
|
|
Pierre-Yves Chibon |
11c405 |
shutil.rmtree(docrepo)
|
|
Pierre-Yves Chibon |
11c405 |
shutil.rmtree(ticketrepo)
|
|
Pierre-Yves Chibon |
fe5017 |
raise pagure.exceptions.RepoExistsException(
|
|
Pierre-Yves Chibon |
11c405 |
'The requests repo "%s" already exists' % project.path
|
|
Pierre-Yves Chibon |
11c405 |
)
|
|
Pierre-Yves Chibon |
f43a32 |
pygit2.init_repository(
|
|
Pierre-Yves Chibon |
a0c6e1 |
requestrepo, bare=True,
|
|
Pierre-Yves Chibon |
a0c6e1 |
mode=pygit2.C.GIT_REPOSITORY_INIT_SHARED_GROUP)
|
|
Pierre-Yves Chibon |
11c405 |
|
|
Pierre-Yves Chibon |
afcf11 |
# Install the default hook
|
|
Pierre-Yves Chibon |
afcf11 |
plugin = pagure.lib.plugins.get_plugin('default')
|
|
Pierre-Yves Chibon |
afcf11 |
dbobj = plugin.db_object()
|
|
Pierre-Yves Chibon |
afcf11 |
dbobj.active = True
|
|
Pierre-Yves Chibon |
afcf11 |
dbobj.project_id = project.id
|
|
Pierre-Yves Chibon |
afcf11 |
session.add(dbobj)
|
|
Pierre-Yves Chibon |
afcf11 |
session.flush()
|
|
Pierre-Yves Chibon |
afcf11 |
plugin.set_up(project)
|
|
Pierre-Yves Chibon |
afcf11 |
plugin.install(project, dbobj)
|
|
Pierre-Yves Chibon |
afcf11 |
|
|
vanzhiganov |
f88b67 |
# create the project in the db
|
|
Vivek Anand |
5ba62d |
session.commit()
|
|
Vivek Anand |
5ba62d |
|
|
Pierre-Yves Chibon |
c898e5 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
c898e5 |
project,
|
|
Pierre-Yves Chibon |
c898e5 |
topic='project.new',
|
|
Pierre-Yves Chibon |
c898e5 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
project=project.to_json(public=True),
|
|
Pierre-Yves Chibon |
0ce3a2 |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
0ce3a2 |
)
|
|
Pierre-Yves Chibon |
0ce3a2 |
|
|
Pierre-Yves Chibon |
d8110b |
return 'Project "%s" created' % name
|
|
Mathieu Bridon |
eb729c |
|
|
Pierre-Yves Chibon |
f74093 |
|
|
Pierre-Yves Chibon |
60e0e5 |
def new_issue(session, repo, title, content, user, ticketfolder,
|
|
Pierre-Yves Chibon |
23b63c |
issue_id=None, issue_uid=None, private=False, status=None,
|
|
Pierre-Yves Chibon |
07bd83 |
close_status=None, notify=True, date_created=None):
|
|
Pierre-Yves Chibon |
33ff2c |
''' Create a new issue for the specified repo. '''
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
e1372f |
|
|
Pierre-Yves Chibon |
33ff2c |
issue = model.Issue(
|
|
Pierre-Yves Chibon |
1d8ce3 |
id=issue_id or get_next_id(session, repo.id),
|
|
Pierre-Yves Chibon |
33ff2c |
project_id=repo.id,
|
|
Pierre-Yves Chibon |
33ff2c |
title=title,
|
|
Pierre-Yves Chibon |
33ff2c |
content=content,
|
|
Pierre-Yves Chibon |
e1372f |
user_id=user_obj.id,
|
|
Pierre-Yves Chibon |
0be51b |
uid=issue_uid or uuid.uuid4().hex,
|
|
Pierre-Yves Chibon |
60e0e5 |
private=private,
|
|
Clement Verna |
f45e89 |
date_created=date_created,
|
|
Pierre-Yves Chibon |
33ff2c |
)
|
|
Pierre-Yves Chibon |
0be51b |
|
|
Pierre-Yves Chibon |
0be51b |
if status is not None:
|
|
Pierre-Yves Chibon |
0be51b |
issue.status = status
|
|
Pierre-Yves Chibon |
07bd83 |
if close_status is not None:
|
|
Pierre-Yves Chibon |
07bd83 |
issue.close_status = close_status
|
|
Pierre-Yves Chibon |
0be51b |
|
|
Pierre-Yves Chibon |
33ff2c |
session.add(issue)
|
|
Pierre-Yves Chibon |
057ee1 |
# Make sure we won't have SQLAlchemy error before we create the issue
|
|
Pierre-Yves Chibon |
33ff2c |
session.flush()
|
|
Pierre-Yves Chibon |
33ff2c |
|
|
Pierre-Yves Chibon |
fe5017 |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
f7d56f |
issue, repo=repo, repofolder=ticketfolder)
|
|
Pierre-Yves Chibon |
a34835 |
|
|
Pierre-Yves Chibon |
27fdde |
if notify:
|
|
Pierre-Yves Chibon |
fe5017 |
pagure.lib.notify.notify_new_issue(issue, user=user_obj)
|
|
Pierre-Yves Chibon |
142bae |
|
|
Pierre-Yves Chibon |
b38c20 |
if not private:
|
|
Pierre-Yves Chibon |
c898e5 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
c898e5 |
issue.project,
|
|
Pierre-Yves Chibon |
c898e5 |
topic='issue.new',
|
|
Pierre-Yves Chibon |
c898e5 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
issue=issue.to_json(public=True),
|
|
Pierre-Yves Chibon |
972598 |
project=issue.project.to_json(public=True),
|
|
Pierre-Yves Chibon |
b38c20 |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
0ce3a2 |
)
|
|
Pierre-Yves Chibon |
0ce3a2 |
|
|
Pierre-Yves Chibon |
f1a75b |
return issue
|
|
Pierre-Yves Chibon |
33ff2c |
|
|
Pierre-Yves Chibon |
33ff2c |
|
|
Pierre-Yves Chibon |
2e464a |
def drop_issue(session, issue, user, ticketfolder):
|
|
Pierre-Yves Chibon |
1714a1 |
''' Delete a specified issue. '''
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
1714a1 |
|
|
Pierre-Yves Chibon |
1714a1 |
private = issue.private
|
|
Pierre-Yves Chibon |
1714a1 |
session.delete(issue)
|
|
Pierre-Yves Chibon |
1714a1 |
|
|
Pierre-Yves Chibon |
1714a1 |
# Make sure we won't have SQLAlchemy error before we create the issue
|
|
Pierre-Yves Chibon |
1714a1 |
session.flush()
|
|
Pierre-Yves Chibon |
1714a1 |
|
|
Pierre-Yves Chibon |
1714a1 |
pagure.lib.git.clean_git(
|
|
Pierre-Yves Chibon |
1714a1 |
issue, repo=issue.project, repofolder=ticketfolder)
|
|
Pierre-Yves Chibon |
1714a1 |
|
|
Pierre-Yves Chibon |
1714a1 |
if not private:
|
|
Pierre-Yves Chibon |
1714a1 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
1714a1 |
issue.project,
|
|
Pierre-Yves Chibon |
1714a1 |
topic='issue.drop',
|
|
Pierre-Yves Chibon |
1714a1 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
issue=issue.to_json(public=True),
|
|
Pierre-Yves Chibon |
972598 |
project=issue.project.to_json(public=True),
|
|
Pierre-Yves Chibon |
1714a1 |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
1714a1 |
)
|
|
Pierre-Yves Chibon |
1714a1 |
|
|
Pierre-Yves Chibon |
1714a1 |
return issue
|
|
Pierre-Yves Chibon |
1714a1 |
|
|
Pierre-Yves Chibon |
1714a1 |
|
|
Pierre-Yves Chibon |
09cda5 |
def new_pull_request(session, branch_from,
|
|
Pierre-Yves Chibon |
851174 |
repo_to, branch_to, title, user,
|
|
Pierre-Yves Chibon |
47947e |
requestfolder, initial_comment=None,
|
|
Pierre-Yves Chibon |
47947e |
repo_from=None, remote_git=None,
|
|
Pierre-Yves Chibon |
09cda5 |
requestuid=None, requestid=None,
|
|
Pierre-Yves Chibon |
2e464a |
status='Open', notify=True):
|
|
Pierre-Yves Chibon |
472a61 |
''' Create a new pull request on the specified repo. '''
|
|
Pierre-Yves Chibon |
09cda5 |
if not repo_from and not remote_git:
|
|
Pierre-Yves Chibon |
4ff493 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
09cda5 |
'Invalid input, you must specify either a local repo or a '
|
|
Pierre-Yves Chibon |
09cda5 |
'remote one')
|
|
Pierre-Yves Chibon |
09cda5 |
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
7d23c0 |
|
|
Pierre-Yves Chibon |
472a61 |
request = model.PullRequest(
|
|
Pierre-Yves Chibon |
851174 |
id=requestid or get_next_id(session, repo_to.id),
|
|
Pierre-Yves Chibon |
851174 |
uid=requestuid or uuid.uuid4().hex,
|
|
Pierre-Yves Chibon |
aa5fb9 |
project_id=repo_to.id,
|
|
Pierre-Yves Chibon |
09cda5 |
project_id_from=repo_from.id if repo_from else None,
|
|
Pierre-Yves Chibon |
09cda5 |
remote_git=remote_git if remote_git else None,
|
|
Pierre-Yves Chibon |
aa5fb9 |
branch=branch_to,
|
|
Pierre-Yves Chibon |
aa5fb9 |
branch_from=branch_from,
|
|
Pierre-Yves Chibon |
472a61 |
title=title,
|
|
Pierre-Yves Chibon |
47947e |
initial_comment=initial_comment or None,
|
|
Pierre-Yves Chibon |
7d23c0 |
user_id=user_obj.id,
|
|
Pierre-Yves Chibon |
851174 |
status=status,
|
|
Pierre-Yves Chibon |
472a61 |
)
|
|
Pierre-Yves Chibon |
472a61 |
session.add(request)
|
|
Pierre-Yves Chibon |
472a61 |
# Make sure we won't have SQLAlchemy error before we create the request
|
|
Pierre-Yves Chibon |
472a61 |
session.flush()
|
|
Pierre-Yves Chibon |
472a61 |
|
|
Pierre-Yves Chibon |
fe5017 |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
a482cb |
request, repo=request.project, repofolder=requestfolder)
|
|
Pierre-Yves Chibon |
a1280f |
|
|
Pierre-Yves Chibon |
27fdde |
if notify:
|
|
Pierre-Yves Chibon |
fe5017 |
pagure.lib.notify.notify_new_pull_request(request)
|
|
Pierre-Yves Chibon |
e0589f |
|
|
Pierre-Yves Chibon |
c898e5 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
c898e5 |
request.project,
|
|
Pierre-Yves Chibon |
c898e5 |
topic='pull-request.new',
|
|
Pierre-Yves Chibon |
c898e5 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
pullrequest=request.to_json(public=True),
|
|
Pierre-Yves Chibon |
0ce3a2 |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
0ce3a2 |
)
|
|
Pierre-Yves Chibon |
0ce3a2 |
|
|
Pierre-Yves Chibon |
b65483 |
# Send notification to the CI server
|
|
Pierre-Yves Chibon |
af2692 |
if REDIS and request.project.ci_hook and PAGURE_CI:
|
|
Pierre-Yves Chibon |
b65483 |
REDIS.publish('pagure.ci', json.dumps({
|
|
Pierre-Yves Chibon |
dcbd99 |
'ci_type': request.project.ci_hook.ci_type,
|
|
Pierre-Yves Chibon |
b65483 |
'pr': request.to_json(public=True, with_comments=False)
|
|
Pierre-Yves Chibon |
b65483 |
}))
|
|
Pierre-Yves Chibon |
b65483 |
|
|
Pierre-Yves Chibon |
573769 |
return request
|
|
Pierre-Yves Chibon |
472a61 |
|
|
Pierre-Yves Chibon |
472a61 |
|
|
Pierre-Yves Chibon |
5a326c |
def edit_issue(session, issue, ticketfolder, user,
|
|
Pierre-Yves Chibon |
05fc3c |
title=None, content=None, status=None, close_status=None,
|
|
Pierre-Yves Chibon |
8a9c7e |
priority=None, milestone=None, private=False):
|
|
Pierre-Yves Chibon |
c71370 |
''' Edit the specified issue.
|
|
Pierre-Yves Chibon |
c71370 |
'''
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
5a326c |
|
|
Pierre-Yves Chibon |
05fc3c |
if status != 'Open' and issue.parents:
|
|
Pierre-Yves Chibon |
4713b8 |
for parent in issue.parents:
|
|
Pierre-Yves Chibon |
4713b8 |
if parent.status == 'Open':
|
|
Pierre-Yves Chibon |
fe5017 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
4713b8 |
'You cannot close a ticket that has ticket '
|
|
Pierre-Yves Chibon |
4713b8 |
'depending that are still open.')
|
|
Pierre-Yves Chibon |
4713b8 |
|
|
Pierre-Yves Chibon |
c71370 |
edit = []
|
|
Pierre-Yves Chibon |
fb8b6c |
if title and title != issue.title:
|
|
Pierre-Yves Chibon |
c71370 |
issue.title = title
|
|
Pierre-Yves Chibon |
c71370 |
edit.append('title')
|
|
Pierre-Yves Chibon |
fb8b6c |
if content and content != issue.content:
|
|
Pierre-Yves Chibon |
c71370 |
issue.content = content
|
|
Pierre-Yves Chibon |
c71370 |
edit.append('content')
|
|
Pierre-Yves Chibon |
fb8b6c |
if status and status != issue.status:
|
|
Pierre-Yves Chibon |
4d1cbe |
issue.status = status
|
|
Vivek Anand |
c25f97 |
if status.lower() != 'open':
|
|
Vivek Anand |
c25f97 |
issue.closed_at = datetime.datetime.utcnow()
|
|
Pierre-Yves Chibon |
4d1cbe |
edit.append('status')
|
|
Pierre-Yves Chibon |
05fc3c |
if close_status and close_status != issue.close_status:
|
|
Pierre-Yves Chibon |
05fc3c |
issue.close_status = close_status
|
|
Pierre-Yves Chibon |
05fc3c |
edit.append('close_status')
|
|
Pierre-Yves Chibon |
f8505e |
if priority:
|
|
Pierre-Yves Chibon |
f8505e |
try:
|
|
Pierre-Yves Chibon |
f8505e |
priority = int(priority)
|
|
Pierre-Yves Chibon |
f8505e |
except:
|
|
Pierre-Yves Chibon |
f8505e |
priority = None
|
|
Pierre-Yves Chibon |
f8505e |
if priority != issue.priority:
|
|
Pierre-Yves Chibon |
f8505e |
issue.priority = priority
|
|
Pierre-Yves Chibon |
f8505e |
edit.append('priority')
|
|
Pierre-Yves Chibon |
3b17c8 |
if private in [True, False] and private != issue.private:
|
|
Pierre-Yves Chibon |
3b17c8 |
issue.private = private
|
|
Pierre-Yves Chibon |
3b17c8 |
edit.append('private')
|
|
Pierre-Yves Chibon |
8a9c7e |
if milestone != issue.milestone:
|
|
Pierre-Yves Chibon |
8a9c7e |
issue.milestone = milestone
|
|
Pierre-Yves Chibon |
8a9c7e |
edit.append('milestone')
|
|
Pierre-Yves Chibon |
c71370 |
|
|
Pierre-Yves Chibon |
fe5017 |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
2da35f |
issue, repo=issue.project, repofolder=ticketfolder)
|
|
Pierre-Yves Chibon |
a34835 |
|
|
Pierre-Yves Chibon |
c077f3 |
if 'status' in edit:
|
|
Pierre-Yves Chibon |
c077f3 |
add_issue_comment(
|
|
Pierre-Yves Chibon |
c077f3 |
session,
|
|
Pierre-Yves Chibon |
c077f3 |
issue,
|
|
Pierre-Yves Chibon |
976a0e |
comment='@%s changed the status to ``%s``' % (
|
|
Pierre-Yves Chibon |
976a0e |
user_obj.username, status),
|
|
Pierre-Yves Chibon |
c077f3 |
user=user,
|
|
Pierre-Yves Chibon |
c077f3 |
ticketfolder=ticketfolder,
|
|
Pierre-Yves Chibon |
c077f3 |
notify=False,
|
|
Pierre-Yves Chibon |
c077f3 |
notification=True,
|
|
Pierre-Yves Chibon |
c077f3 |
)
|
|
Pierre-Yves Chibon |
c077f3 |
|
|
Pierre-Yves Chibon |
be8acf |
if not issue.private and edit:
|
|
Pierre-Yves Chibon |
c898e5 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
c898e5 |
issue.project,
|
|
Pierre-Yves Chibon |
c898e5 |
topic='issue.edit',
|
|
Pierre-Yves Chibon |
c898e5 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
issue=issue.to_json(public=True),
|
|
Pierre-Yves Chibon |
972598 |
project=issue.project.to_json(public=True),
|
|
Pierre-Yves Chibon |
a57ad3 |
fields=edit,
|
|
Pierre-Yves Chibon |
a57ad3 |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
0ce3a2 |
)
|
|
Pierre-Yves Chibon |
0ce3a2 |
|
|
Pierre-Yves Chibon |
2e464a |
if REDIS and edit:
|
|
Pierre-Yves Chibon |
b7e379 |
if issue.private:
|
|
Pierre-Yves Chibon |
8e41fb |
REDIS.publish('pagure.%s' % issue.uid, json.dumps({
|
|
Pierre-Yves Chibon |
ff274a |
'issue': 'private',
|
|
Pierre-Yves Chibon |
ff274a |
'fields': edit,
|
|
Pierre-Yves Chibon |
ff274a |
}))
|
|
Pierre-Yves Chibon |
b7e379 |
else:
|
|
Pierre-Yves Chibon |
8e41fb |
REDIS.publish('pagure.%s' % issue.uid, json.dumps({
|
|
Pierre-Yves Chibon |
b7e379 |
'fields': edit,
|
|
Pierre-Yves Chibon |
b7e379 |
'issue': issue.to_json(public=True, with_comments=False),
|
|
Pierre-Yves Chibon |
b7e379 |
}))
|
|
Pierre-Yves Chibon |
68664f |
|
|
Pierre-Yves Chibon |
cb9c01 |
if edit:
|
|
Pierre-Yves Chibon |
c71370 |
session.add(issue)
|
|
Pierre-Yves Chibon |
c71370 |
session.flush()
|
|
Pierre-Yves Chibon |
754e40 |
return 'Successfully edited issue #%s' % issue.id
|
|
Pierre-Yves Chibon |
c71370 |
|
|
Pierre-Yves Chibon |
c71370 |
|
|
Pierre-Yves Chibon |
2e464a |
def update_project_settings(session, repo, settings, user):
|
|
Pierre-Yves Chibon |
b39aa4 |
''' Update the settings of a project. '''
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
997e82 |
|
|
Pierre-Yves Chibon |
b39aa4 |
update = []
|
|
Pierre-Yves Chibon |
385746 |
new_settings = repo.settings
|
|
Pierre-Yves Chibon |
385746 |
for key in new_settings:
|
|
Pierre-Yves Chibon |
385746 |
if key in settings:
|
|
Pierre-Yves Chibon |
385746 |
if new_settings[key] != settings[key]:
|
|
Pierre-Yves Chibon |
385746 |
update.append(key)
|
|
Pierre-Yves Chibon |
3ebdd9 |
if key == 'Minimum_score_to_merge_pull-request':
|
|
Ricky Elrod |
0bd55b |
try:
|
|
Pierre-Yves Chibon |
27549e |
settings[key] = int(settings[key]) \
|
|
Pierre-Yves Chibon |
27549e |
if settings[key] else -1
|
|
Ricky Elrod |
0bd55b |
except ValueError:
|
|
Ricky Elrod |
0bd55b |
raise pagure.exceptions.PagureException(
|
|
Ricky Elrod |
0bd55b |
"Please enter a numeric value for the 'minimum "
|
|
Ricky Elrod |
0bd55b |
"score to merge pull request' field.")
|
|
Pierre-Yves Chibon |
8e57b2 |
elif key == 'Web-hooks':
|
|
Pierre-Yves Chibon |
8e57b2 |
settings[key] = settings[key] or None
|
|
Pierre-Yves Chibon |
385746 |
new_settings[key] = settings[key]
|
|
Pierre-Yves Chibon |
385746 |
else:
|
|
Pierre-Yves Chibon |
385746 |
update.append(key)
|
|
Pierre-Yves Chibon |
492752 |
val = False
|
|
Pierre-Yves Chibon |
492752 |
if key == 'Web-hooks':
|
|
Pierre-Yves Chibon |
492752 |
val = None
|
|
Pierre-Yves Chibon |
492752 |
new_settings[key] = val
|
|
Pierre-Yves Chibon |
b39aa4 |
|
|
Pierre-Yves Chibon |
b39aa4 |
if not update:
|
|
Pierre-Yves Chibon |
b39aa4 |
return 'No settings to change'
|
|
Pierre-Yves Chibon |
b39aa4 |
else:
|
|
Pierre-Yves Chibon |
932d90 |
repo.settings = new_settings
|
|
Pierre-Yves Chibon |
b39aa4 |
session.add(repo)
|
|
Pierre-Yves Chibon |
b39aa4 |
session.flush()
|
|
Pierre-Yves Chibon |
c898e5 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
c898e5 |
repo,
|
|
Pierre-Yves Chibon |
c898e5 |
topic='project.edit',
|
|
Pierre-Yves Chibon |
c898e5 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
project=repo.to_json(public=True),
|
|
Pierre-Yves Chibon |
0ce3a2 |
fields=update,
|
|
Pierre-Yves Chibon |
0ce3a2 |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
0ce3a2 |
)
|
|
Pierre-Yves Chibon |
0ce3a2 |
|
|
Pierre-Yves Chibon |
511a11 |
return 'Edited successfully settings of repo: %s' % repo.fullname
|
|
Pierre-Yves Chibon |
b39aa4 |
|
|
Pierre-Yves Chibon |
b39aa4 |
|
|
Pierre-Yves Chibon |
b933a2 |
def update_user_settings(session, settings, user):
|
|
Pierre-Yves Chibon |
b933a2 |
''' Update the settings of a project. '''
|
|
Pierre-Yves Chibon |
b933a2 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
b933a2 |
|
|
Pierre-Yves Chibon |
b933a2 |
update = []
|
|
Pierre-Yves Chibon |
b933a2 |
new_settings = user_obj.settings
|
|
Pierre-Yves Chibon |
b933a2 |
for key in new_settings:
|
|
Pierre-Yves Chibon |
b933a2 |
if key in settings:
|
|
Pierre-Yves Chibon |
b933a2 |
if new_settings[key] != settings[key]:
|
|
Pierre-Yves Chibon |
b933a2 |
update.append(key)
|
|
Pierre-Yves Chibon |
b933a2 |
new_settings[key] = settings[key]
|
|
Pierre-Yves Chibon |
b933a2 |
else:
|
|
Pierre-Yves Chibon |
b933a2 |
update.append(key)
|
|
Pierre-Yves Chibon |
711d5c |
new_settings[key] = False
|
|
Pierre-Yves Chibon |
b933a2 |
|
|
Pierre-Yves Chibon |
b933a2 |
if not update:
|
|
Pierre-Yves Chibon |
b933a2 |
return 'No settings to change'
|
|
Pierre-Yves Chibon |
b933a2 |
else:
|
|
Pierre-Yves Chibon |
b933a2 |
user_obj.settings = new_settings
|
|
Pierre-Yves Chibon |
b933a2 |
session.add(user_obj)
|
|
Pierre-Yves Chibon |
b933a2 |
session.flush()
|
|
Pierre-Yves Chibon |
b933a2 |
|
|
Pierre-Yves Chibon |
b933a2 |
return 'Successfully edited your settings'
|
|
Pierre-Yves Chibon |
b933a2 |
|
|
Pierre-Yves Chibon |
b933a2 |
|
|
Pierre-Yves Chibon |
a33978 |
def fork_project(session, user, repo, gitfolder,
|
|
Pierre-Yves Chibon |
4fcac8 |
docfolder, ticketfolder, requestfolder):
|
|
Pierre-Yves Chibon |
652c2c |
''' Fork a given project into the user's forks. '''
|
|
Pierre-Yves Chibon |
4fcac8 |
reponame = os.path.join(gitfolder, repo.path)
|
|
Pierre-Yves Chibon |
4fcac8 |
forkreponame = '%s.git' % os.path.join(
|
|
Pierre-Yves Chibon |
4fcac8 |
gitfolder, 'forks', user, repo.name)
|
|
Pierre-Yves Chibon |
652c2c |
|
|
Pierre-Yves Chibon |
652c2c |
if os.path.exists(forkreponame):
|
|
Pierre-Yves Chibon |
fe5017 |
raise pagure.exceptions.RepoExistsException(
|
|
Pierre-Yves Chibon |
4fcac8 |
'Repo "forks/%s/%s" already exists' % (user, repo.name))
|
|
Pierre-Yves Chibon |
652c2c |
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
e1372f |
|
|
Pierre-Yves Chibon |
652c2c |
project = model.Project(
|
|
Pierre-Yves Chibon |
652c2c |
name=repo.name,
|
|
Pierre-Yves Chibon |
652c2c |
description=repo.description,
|
|
Pierre-Yves Chibon |
e1372f |
user_id=user_obj.id,
|
|
Pierre-Yves Chibon |
b0ebc2 |
parent_id=repo.id,
|
|
farhaanbukhsh |
778e69 |
is_fork=True,
|
|
Pierre-Yves Chibon |
b0ebc2 |
hook_token=pagure.lib.login.id_generator(40)
|
|
Pierre-Yves Chibon |
652c2c |
)
|
|
Vivek Anand |
591f1a |
|
|
Pierre-Yves Chibon |
b13b92 |
# disable issues, PRs in the fork by default
|
|
Vivek Anand |
591f1a |
default_repo_settings = project.settings
|
|
Vivek Anand |
591f1a |
default_repo_settings['issue_tracker'] = False
|
|
Vivek Anand |
591f1a |
default_repo_settings['pull_requests'] = False
|
|
Vivek Anand |
591f1a |
project.settings = default_repo_settings
|
|
Vivek Anand |
591f1a |
|
|
Pierre-Yves Chibon |
652c2c |
session.add(project)
|
|
Pierre-Yves Chibon |
652c2c |
# Make sure we won't have SQLAlchemy error before we create the repo
|
|
Pierre-Yves Chibon |
652c2c |
session.flush()
|
|
Pierre-Yves Chibon |
652c2c |
|
|
Pierre-Yves Chibon |
aaf0c5 |
frepo = pygit2.clone_repository(reponame, forkreponame, bare=True)
|
|
Pierre-Yves Chibon |
aaf0c5 |
# Clone all the branches as well
|
|
Pierre-Yves Chibon |
e1497f |
for branch in frepo.listall_branches(pygit2.GIT_BRANCH_REMOTE):
|
|
Pierre-Yves Chibon |
f9f132 |
branch_obj = frepo.lookup_branch(branch, pygit2.GIT_BRANCH_REMOTE)
|
|
Pierre-Yves Chibon |
f9f132 |
name = branch_obj.branch_name.replace(
|
|
Pierre-Yves Chibon |
c36800 |
branch_obj.remote_name, '', 1)[1:]
|
|
Pierre-Yves Chibon |
36c1c9 |
if name in frepo.listall_branches(pygit2.GIT_BRANCH_LOCAL):
|
|
Pierre-Yves Chibon |
36c1c9 |
continue
|
|
Pierre-Yves Chibon |
f9f132 |
frepo.create_branch(name, frepo.get(branch_obj.target.hex))
|
|
Pierre-Yves Chibon |
652c2c |
|
|
Pierre-Yves Chibon |
901806 |
# Create the git-daemin-export-ok file on the clone
|
|
Pierre-Yves Chibon |
901806 |
http_clone_file = os.path.join(forkreponame, 'git-daemon-export-ok')
|
|
Pierre-Yves Chibon |
901806 |
if not os.path.exists(http_clone_file):
|
|
Pierre-Yves Chibon |
d1e053 |
with open(http_clone_file, 'w'):
|
|
Pierre-Yves Chibon |
901806 |
pass
|
|
Pierre-Yves Chibon |
901806 |
|
|
Pierre-Yves Chibon |
b09b48 |
docrepo = os.path.join(docfolder, project.path)
|
|
Pierre-Yves Chibon |
b09b48 |
if os.path.exists(docrepo):
|
|
Pierre-Yves Chibon |
b09b48 |
shutil.rmtree(forkreponame)
|
|
Pierre-Yves Chibon |
fe5017 |
raise pagure.exceptions.RepoExistsException(
|
|
Pierre-Yves Chibon |
4b7a7d |
'The docs "%s" already exists' % project.path
|
|
Pierre-Yves Chibon |
6160b6 |
)
|
|
Pierre-Yves Chibon |
b09b48 |
pygit2.init_repository(docrepo, bare=True)
|
|
Pierre-Yves Chibon |
a33978 |
|
|
Pierre-Yves Chibon |
b09b48 |
ticketrepo = os.path.join(ticketfolder, project.path)
|
|
Pierre-Yves Chibon |
b09b48 |
if os.path.exists(ticketrepo):
|
|
Pierre-Yves Chibon |
b09b48 |
shutil.rmtree(forkreponame)
|
|
Pierre-Yves Chibon |
b09b48 |
shutil.rmtree(docrepo)
|
|
Pierre-Yves Chibon |
fe5017 |
raise pagure.exceptions.RepoExistsException(
|
|
Pierre-Yves Chibon |
a33978 |
'The tickets repo "%s" already exists' % project.path
|
|
Pierre-Yves Chibon |
a33978 |
)
|
|
Pierre-Yves Chibon |
f43a32 |
pygit2.init_repository(
|
|
Pierre-Yves Chibon |
a0c6e1 |
ticketrepo, bare=True,
|
|
Pierre-Yves Chibon |
a0c6e1 |
mode=pygit2.C.GIT_REPOSITORY_INIT_SHARED_GROUP)
|
|
Pierre-Yves Chibon |
6160b6 |
|
|
Pierre-Yves Chibon |
e74f1e |
requestrepo = os.path.join(requestfolder, project.path)
|
|
Pierre-Yves Chibon |
e74f1e |
if os.path.exists(requestrepo):
|
|
Pierre-Yves Chibon |
e74f1e |
shutil.rmtree(forkreponame)
|
|
Pierre-Yves Chibon |
e74f1e |
shutil.rmtree(docrepo)
|
|
Pierre-Yves Chibon |
e74f1e |
shutil.rmtree(ticketrepo)
|
|
Pierre-Yves Chibon |
fe5017 |
raise pagure.exceptions.RepoExistsException(
|
|
Pierre-Yves Chibon |
e74f1e |
'The requests repo "%s" already exists' % project.path
|
|
Pierre-Yves Chibon |
e74f1e |
)
|
|
Pierre-Yves Chibon |
f43a32 |
pygit2.init_repository(
|
|
Pierre-Yves Chibon |
a0c6e1 |
requestrepo, bare=True,
|
|
Pierre-Yves Chibon |
a0c6e1 |
mode=pygit2.C.GIT_REPOSITORY_INIT_SHARED_GROUP)
|
|
Pierre-Yves Chibon |
e74f1e |
|
|
Pierre-Yves Chibon |
c898e5 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
c898e5 |
project,
|
|
Pierre-Yves Chibon |
c898e5 |
topic='project.forked',
|
|
Pierre-Yves Chibon |
c898e5 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
project=project.to_json(public=True),
|
|
Pierre-Yves Chibon |
0ce3a2 |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
0ce3a2 |
)
|
|
Pierre-Yves Chibon |
0ce3a2 |
|
|
Pierre-Yves Chibon |
652c2c |
return 'Repo "%s" cloned to "%s/%s"' % (repo.name, user, repo.name)
|
|
Pierre-Yves Chibon |
652c2c |
|
|
Pierre-Yves Chibon |
652c2c |
|
|
Pierre-Yves Chibon |
7ece2d |
def search_projects(
|
|
Pierre-Yves Chibon |
d3b817 |
session, username=None,
|
|
Pierre-Yves Chibon |
d3b817 |
fork=None, tags=None, namespace=None, pattern=None,
|
|
Ryan Lerch |
770112 |
start=None, limit=None, count=False, sort=None):
|
|
Pierre-Yves Chibon |
695ef6 |
'''List existing projects
|
|
Pierre-Yves Chibon |
695ef6 |
'''
|
|
Pierre-Yves Chibon |
0b9290 |
projects = session.query(
|
|
Pierre-Yves Chibon |
394a13 |
sqlalchemy.distinct(model.Project.id)
|
|
Pierre-Yves Chibon |
0b9290 |
)
|
|
Mathieu Bridon |
eb729c |
|
|
Pierre-Yves Chibon |
ea0ee1 |
if username is not None:
|
|
Pierre-Yves Chibon |
e1372f |
projects = projects.filter(
|
|
Pierre-Yves Chibon |
394a13 |
# User created the project
|
|
Pierre-Yves Chibon |
394a13 |
sqlalchemy.and_(
|
|
Pierre-Yves Chibon |
394a13 |
model.User.user == username,
|
|
Pierre-Yves Chibon |
394a13 |
model.User.id == model.Project.user_id,
|
|
Pierre-Yves Chibon |
394a13 |
)
|
|
Pierre-Yves Chibon |
394a13 |
)
|
|
Pierre-Yves Chibon |
f9f132 |
sub_q2 = session.query(
|
|
Pierre-Yves Chibon |
394a13 |
model.Project.id
|
|
Pierre-Yves Chibon |
e1372f |
).filter(
|
|
Pierre-Yves Chibon |
394a13 |
# User got commit right
|
|
Pierre-Yves Chibon |
394a13 |
sqlalchemy.and_(
|
|
Pierre-Yves Chibon |
394a13 |
model.User.user == username,
|
|
Pierre-Yves Chibon |
394a13 |
model.User.id == model.ProjectUser.user_id,
|
|
Pierre-Yves Chibon |
394a13 |
model.ProjectUser.project_id == model.Project.id
|
|
Pierre-Yves Chibon |
394a13 |
)
|
|
Pierre-Yves Chibon |
ea0ee1 |
)
|
|
Pierre-Yves Chibon |
f9f132 |
sub_q3 = session.query(
|
|
Pierre-Yves Chibon |
394a13 |
model.Project.id
|
|
Pierre-Yves Chibon |
394a13 |
).filter(
|
|
Pierre-Yves Chibon |
394a13 |
# User created a group that has commit right
|
|
Pierre-Yves Chibon |
394a13 |
sqlalchemy.and_(
|
|
Pierre-Yves Chibon |
394a13 |
model.User.user == username,
|
|
Pierre-Yves Chibon |
394a13 |
model.PagureGroup.user_id == model.User.id,
|
|
Pierre-Yves Chibon |
394a13 |
model.PagureGroup.group_type == 'user',
|
|
Pierre-Yves Chibon |
394a13 |
model.PagureGroup.id == model.ProjectGroup.group_id,
|
|
Pierre-Yves Chibon |
394a13 |
model.Project.id == model.ProjectGroup.project_id,
|
|
Pierre-Yves Chibon |
394a13 |
)
|
|
Pierre-Yves Chibon |
394a13 |
)
|
|
Pierre-Yves Chibon |
f9f132 |
sub_q4 = session.query(
|
|
Pierre-Yves Chibon |
394a13 |
model.Project.id
|
|
Pierre-Yves Chibon |
394a13 |
).filter(
|
|
Pierre-Yves Chibon |
394a13 |
# User is part of a group that has commit right
|
|
Pierre-Yves Chibon |
394a13 |
sqlalchemy.and_(
|
|
Pierre-Yves Chibon |
394a13 |
model.User.user == username,
|
|
Pierre-Yves Chibon |
394a13 |
model.PagureUserGroup.user_id == model.User.id,
|
|
Pierre-Yves Chibon |
394a13 |
model.PagureUserGroup.group_id == model.PagureGroup.id,
|
|
Pierre-Yves Chibon |
394a13 |
model.PagureGroup.group_type == 'user',
|
|
Pierre-Yves Chibon |
394a13 |
model.PagureGroup.id == model.ProjectGroup.group_id,
|
|
Pierre-Yves Chibon |
394a13 |
model.Project.id == model.ProjectGroup.project_id,
|
|
Pierre-Yves Chibon |
394a13 |
)
|
|
Pierre-Yves Chibon |
394a13 |
)
|
|
Pierre-Yves Chibon |
394a13 |
|
|
Pierre-Yves Chibon |
f9f132 |
projects = projects.union(sub_q2).union(sub_q3).union(sub_q4)
|
|
Pierre-Yves Chibon |
ea0ee1 |
|
|
Pierre-Yves Chibon |
7752a8 |
if fork is not None:
|
|
Pierre-Yves Chibon |
7752a8 |
if fork is True:
|
|
Pierre-Yves Chibon |
7752a8 |
projects = projects.filter(
|
|
farhaanbukhsh |
3e1439 |
model.Project.is_fork == True
|
|
Pierre-Yves Chibon |
7752a8 |
)
|
|
Pierre-Yves Chibon |
7752a8 |
elif fork is False:
|
|
Pierre-Yves Chibon |
2f8732 |
projects = projects.filter(
|
|
farhaanbukhsh |
3e1439 |
model.Project.is_fork == False
|
|
Pierre-Yves Chibon |
7752a8 |
)
|
|
Pierre-Yves Chibon |
7752a8 |
|
|
Pierre-Yves Chibon |
1942c1 |
if tags:
|
|
Pierre-Yves Chibon |
995375 |
if not isinstance(tags, (list, tuple)):
|
|
Pierre-Yves Chibon |
995375 |
tags = [tags]
|
|
Pierre-Yves Chibon |
995375 |
|
|
Pierre-Yves Chibon |
995375 |
projects = projects.filter(
|
|
Pierre-Yves Chibon |
995375 |
model.Project.id == model.TagProject.project_id
|
|
Pierre-Yves Chibon |
995375 |
).filter(
|
|
Pierre-Yves Chibon |
995375 |
model.TagProject.tag.in_(tags)
|
|
Pierre-Yves Chibon |
995375 |
)
|
|
Pierre-Yves Chibon |
995375 |
|
|
Pierre-Yves Chibon |
70be16 |
if pattern:
|
|
Pierre-Yves Chibon |
70be16 |
pattern = pattern.replace('*', '%')
|
|
Pierre-Yves Chibon |
2ccd5c |
if '%' in pattern:
|
|
Pierre-Yves Chibon |
2ccd5c |
projects = projects.filter(
|
|
Pierre-Yves Chibon |
2ccd5c |
model.Project.name.like(pattern)
|
|
Pierre-Yves Chibon |
2ccd5c |
)
|
|
Pierre-Yves Chibon |
2ccd5c |
else:
|
|
Pierre-Yves Chibon |
2ccd5c |
projects = projects.filter(
|
|
Pierre-Yves Chibon |
2ccd5c |
model.Project.name == pattern
|
|
Pierre-Yves Chibon |
2ccd5c |
)
|
|
Pierre-Yves Chibon |
d3b817 |
|
|
Pierre-Yves Chibon |
d3b817 |
if namespace:
|
|
Vivek Anand |
0ba2b9 |
projects = projects.filter(
|
|
Pierre-Yves Chibon |
d3b817 |
model.Project.namespace == namespace
|
|
Pierre-Yves Chibon |
d3b817 |
)
|
|
Pierre-Yves Chibon |
d3b817 |
|
|
Pierre-Yves Chibon |
f6ea15 |
query = session.query(
|
|
Pierre-Yves Chibon |
f6ea15 |
model.Project
|
|
Pierre-Yves Chibon |
f6ea15 |
).filter(
|
|
Pierre-Yves Chibon |
f6ea15 |
model.Project.id.in_(projects.subquery())
|
|
Pierre-Yves Chibon |
f6ea15 |
)
|
|
Pierre-Yves Chibon |
f6ea15 |
|
|
Pierre-Yves Chibon |
60d820 |
if sort == 'latest':
|
|
Pierre-Yves Chibon |
f6ea15 |
query = query.order_by(
|
|
Pierre-Yves Chibon |
60d820 |
model.Project.date_created.desc()
|
|
Pierre-Yves Chibon |
f6ea15 |
)
|
|
Pierre-Yves Chibon |
60d820 |
elif sort == 'oldest':
|
|
Pierre-Yves Chibon |
f6ea15 |
query = query.order_by(
|
|
Pierre-Yves Chibon |
60d820 |
model.Project.date_created.asc()
|
|
Pierre-Yves Chibon |
60d820 |
)
|
|
Pierre-Yves Chibon |
60d820 |
else:
|
|
Pierre-Yves Chibon |
60d820 |
query = query.order_by(
|
|
Pierre-Yves Chibon |
60d820 |
asc(func.lower(model.Project.name))
|
|
Pierre-Yves Chibon |
f6ea15 |
)
|
|
Pierre-Yves Chibon |
394a13 |
|
|
Mathieu Bridon |
eb729c |
if start is not None:
|
|
Pierre-Yves Chibon |
394a13 |
query = query.offset(start)
|
|
Mathieu Bridon |
eb729c |
|
|
Mathieu Bridon |
eb729c |
if limit is not None:
|
|
Pierre-Yves Chibon |
394a13 |
query = query.limit(limit)
|
|
Mathieu Bridon |
eb729c |
|
|
Pierre-Yves Chibon |
f74093 |
if count:
|
|
Pierre-Yves Chibon |
394a13 |
return query.count()
|
|
Pierre-Yves Chibon |
f74093 |
else:
|
|
Pierre-Yves Chibon |
394a13 |
return query.all()
|
|
Mathieu Bridon |
eb729c |
|
|
Mathieu Bridon |
998605 |
|
|
Pierre-Yves Chibon |
d3b817 |
def get_project(session, name, user=None, namespace=None):
|
|
Pierre-Yves Chibon |
695ef6 |
'''Get a project from the database
|
|
Pierre-Yves Chibon |
695ef6 |
'''
|
|
Pierre-Yves Chibon |
929595 |
query = session.query(
|
|
Pierre-Yves Chibon |
f74093 |
model.Project
|
|
Pierre-Yves Chibon |
178d6f |
).filter(
|
|
Pierre-Yves Chibon |
178d6f |
model.Project.name == name
|
|
Pierre-Yves Chibon |
d3b817 |
).filter(
|
|
Pierre-Yves Chibon |
d3b817 |
model.Project.namespace == namespace
|
|
Pierre-Yves Chibon |
929595 |
)
|
|
Pierre-Yves Chibon |
1ac00b |
|
|
Pierre-Yves Chibon |
929595 |
if user is not None:
|
|
Pierre-Yves Chibon |
929595 |
query = query.filter(
|
|
Pierre-Yves Chibon |
e1372f |
model.User.user == user
|
|
Pierre-Yves Chibon |
e1372f |
).filter(
|
|
Pierre-Yves Chibon |
e1372f |
model.User.id == model.Project.user_id
|
|
Pierre-Yves Chibon |
1ac00b |
).filter(
|
|
farhaanbukhsh |
3e1439 |
model.Project.is_fork == True
|
|
Pierre-Yves Chibon |
929595 |
)
|
|
Pierre-Yves Chibon |
1ac00b |
else:
|
|
Pierre-Yves Chibon |
1ac00b |
query = query.filter(
|
|
farhaanbukhsh |
3e1439 |
model.Project.is_fork == False
|
|
Pierre-Yves Chibon |
1ac00b |
)
|
|
Pierre-Yves Chibon |
1ac00b |
|
|
Pierre-Yves Chibon |
929595 |
return query.first()
|
|
Pierre-Yves Chibon |
562d75 |
|
|
Pierre-Yves Chibon |
5ffcae |
def search_issues(
|
|
Pierre-Yves Chibon |
b585e1 |
session, repo, issueid=None, issueuid=None, status=None,
|
|
Pierre-Yves Chibon |
b585e1 |
closed=False, tags=None, assignee=None, author=None, private=None,
|
|
“AnjaliPardeshi” |
fa7e4c |
priority=None, milestones=None, count=False, offset=None,
|
|
Pierre-Yves Chibon |
b4970f |
limit=None, search_pattern=None, custom_search=None):
|
|
Pierre-Yves Chibon |
5b2947 |
''' Retrieve one or more issues associated to a project with the given
|
|
Pierre-Yves Chibon |
5b2947 |
criterias.
|
|
Pierre-Yves Chibon |
b6df7d |
|
|
Pierre-Yves Chibon |
b6df7d |
Watch out that the closed argument is incompatible with the status
|
|
Pierre-Yves Chibon |
b6df7d |
argument. The closed argument will return all the issues whose status
|
|
Pierre-Yves Chibon |
b6df7d |
is not 'Open', otherwise it will return the issues having the specified
|
|
Pierre-Yves Chibon |
b6df7d |
status.
|
|
Pierre-Yves Chibon |
bc60cc |
The `tags` argument can be used to filter the issues returned based on
|
|
Pierre-Yves Chibon |
bc60cc |
a certain tag.
|
|
Pierre-Yves Chibon |
5b2947 |
If the `issueid` argument is specified a single Issue object (or None)
|
|
Pierre-Yves Chibon |
5b2947 |
will be returned instead of a list of Issue objects.
|
|
Pierre-Yves Chibon |
5b2947 |
|
|
Pierre-Yves Chibon |
5b2947 |
:arg session: the session to use to connect to the database.
|
|
Pierre-Yves Chibon |
5b2947 |
:arg repo: a Project object to which the issues should be associated
|
|
Pierre-Yves Chibon |
fe5017 |
:type repo: pagure.lib.model.Project
|
|
Pierre-Yves Chibon |
5b2947 |
:kwarg issueid: the identifier of the issue to look for
|
|
Pierre-Yves Chibon |
5b2947 |
:type issueid: int or None
|
|
Pierre-Yves Chibon |
b585e1 |
:kwarg issueuid: the unique identifier of the issue to look for
|
|
Pierre-Yves Chibon |
b585e1 |
:type issueuid: str or None
|
|
Pierre-Yves Chibon |
5b2947 |
:kwarg status: the status of the issue to look for (incompatible with
|
|
Pierre-Yves Chibon |
5b2947 |
the `closed` argument).
|
|
Pierre-Yves Chibon |
5b2947 |
:type status: str or None
|
|
Pierre-Yves Chibon |
5b2947 |
:kwarg closed: a boolean indicating whether the issue to retrieve are
|
|
Pierre-Yves Chibon |
5b2947 |
closed or open (incompatible with the `status` argument).
|
|
Pierre-Yves Chibon |
5b2947 |
:type closed: bool or None
|
|
Pierre-Yves Chibon |
5b2947 |
:kwarg tags: a tag the issue(s) returned should be associated with
|
|
Pierre-Yves Chibon |
5b2947 |
:type tags: str or list(str) or None
|
|
Pierre-Yves Chibon |
60bca7 |
:kwarg assignee: the name of the user assigned to the issues to search
|
|
Pierre-Yves Chibon |
60bca7 |
:type assignee: str or None
|
|
Pierre-Yves Chibon |
60bca7 |
:kwarg author: the name of the user who created the issues to search
|
|
Pierre-Yves Chibon |
60bca7 |
:type author: str or None
|
|
Pierre-Yves Chibon |
73a5b8 |
:kwarg private: boolean or string to use to include or exclude private
|
|
Pierre-Yves Chibon |
73a5b8 |
tickets. Defaults to False.
|
|
Pierre-Yves Chibon |
73a5b8 |
If False: private tickets are excluded
|
|
Pierre-Yves Chibon |
73a5b8 |
If None: private tickets are included
|
|
Pierre-Yves Chibon |
73a5b8 |
If user name is specified: private tickets reported by that user
|
|
Pierre-Yves Chibon |
73a5b8 |
are included.
|
|
Pierre-Yves Chibon |
73a5b8 |
:type private: False, None or str
|
|
Pierre-Yves Chibon |
8d019f |
:kwarg priority: the priority of the issues to search
|
|
Pierre-Yves Chibon |
8d019f |
:type priority: int or None
|
|
Pierre-Yves Chibon |
7e8958 |
:kwarg milestones: a milestone the issue(s) returned should be
|
|
Pierre-Yves Chibon |
7e8958 |
associated with.
|
|
Pierre-Yves Chibon |
7e8958 |
:type milestones: str or list(str) or None
|
|
Pierre-Yves Chibon |
e69252 |
:kwarg count: a boolean to specify if the method should return the list
|
|
Pierre-Yves Chibon |
e69252 |
of Issues or just do a COUNT query.
|
|
Pierre-Yves Chibon |
e69252 |
:type count: boolean
|
|
“AnjaliPardeshi” |
fa7e4c |
:kwarg search_pattern: a string to search in issues title
|
|
“AnjaliPardeshi” |
fa7e4c |
:type search_pattern: str or None
|
|
Pierre-Yves Chibon |
b4970f |
:kwarg custom_search: a dictionary of key/values to be used when
|
|
Pierre-Yves Chibon |
b4970f |
searching issues with a custom key constraint
|
|
Pierre-Yves Chibon |
b4970f |
:type custom_search: dict or None
|
|
Pierre-Yves Chibon |
60bca7 |
|
|
Pierre-Yves Chibon |
5b2947 |
:return: A single Issue object if issueid is specified, a list of Project
|
|
Pierre-Yves Chibon |
5b2947 |
objects otherwise.
|
|
Pierre-Yves Chibon |
5b2947 |
:rtype: Project or [Project]
|
|
Pierre-Yves Chibon |
bc60cc |
|
|
Pierre-Yves Chibon |
562d75 |
'''
|
|
Pierre-Yves Chibon |
562d75 |
query = session.query(
|
|
Pierre-Yves Chibon |
af678e |
sqlalchemy.distinct(model.Issue.uid)
|
|
Pierre-Yves Chibon |
95f042 |
).filter(
|
|
Pierre-Yves Chibon |
95f042 |
model.Issue.project_id == repo.id
|
|
Pierre-Yves Chibon |
562d75 |
)
|
|
Pierre-Yves Chibon |
562d75 |
|
|
Pierre-Yves Chibon |
5b2947 |
if issueid is not None:
|
|
Pierre-Yves Chibon |
5b2947 |
query = query.filter(
|
|
Pierre-Yves Chibon |
5b2947 |
model.Issue.id == issueid
|
|
Pierre-Yves Chibon |
5b2947 |
)
|
|
Pierre-Yves Chibon |
5b2947 |
|
|
Pierre-Yves Chibon |
b585e1 |
if issueuid is not None:
|
|
Pierre-Yves Chibon |
b585e1 |
query = query.filter(
|
|
Pierre-Yves Chibon |
b585e1 |
model.Issue.uid == issueuid
|
|
Pierre-Yves Chibon |
b585e1 |
)
|
|
Pierre-Yves Chibon |
b585e1 |
|
|
Pierre-Yves Chibon |
a61250 |
if status is not None:
|
|
Pierre-Yves Chibon |
725259 |
if status in ['Open', 'Closed']:
|
|
Pierre-Yves Chibon |
cfd95d |
query = query.filter(
|
|
Pierre-Yves Chibon |
cfd95d |
model.Issue.status == status
|
|
Pierre-Yves Chibon |
cfd95d |
)
|
|
Pierre-Yves Chibon |
cfd95d |
else:
|
|
Pierre-Yves Chibon |
cfd95d |
query = query.filter(
|
|
Pierre-Yves Chibon |
cfd95d |
model.Issue.close_status == status
|
|
Pierre-Yves Chibon |
cfd95d |
)
|
|
Pierre-Yves Chibon |
b6df7d |
if closed:
|
|
Pierre-Yves Chibon |
b6df7d |
query = query.filter(
|
|
Pierre-Yves Chibon |
b6df7d |
model.Issue.status != 'Open'
|
|
Pierre-Yves Chibon |
b6df7d |
)
|
|
Pierre-Yves Chibon |
8d019f |
if priority:
|
|
Pierre-Yves Chibon |
8d019f |
query = query.filter(
|
|
Pierre-Yves Chibon |
8d019f |
model.Issue.priority == priority
|
|
Pierre-Yves Chibon |
8d019f |
)
|
|
Pierre-Yves Chibon |
d01150 |
if tags is not None and tags != []:
|
|
Pierre-Yves Chibon |
5b2947 |
if isinstance(tags, basestring):
|
|
Pierre-Yves Chibon |
5b2947 |
tags = [tags]
|
|
Pierre-Yves Chibon |
6cd6a9 |
notags = []
|
|
Pierre-Yves Chibon |
6cd6a9 |
ytags = []
|
|
Pierre-Yves Chibon |
6cd6a9 |
for tag in tags:
|
|
Pierre-Yves Chibon |
6cd6a9 |
if tag.startswith('!'):
|
|
Pierre-Yves Chibon |
6cd6a9 |
notags.append(tag[1:])
|
|
Pierre-Yves Chibon |
6cd6a9 |
else:
|
|
Pierre-Yves Chibon |
6cd6a9 |
ytags.append(tag)
|
|
Pierre-Yves Chibon |
6cd6a9 |
|
|
Pierre-Yves Chibon |
6cd6a9 |
if ytags:
|
|
Pierre-Yves Chibon |
f9f132 |
sub_q2 = session.query(
|
|
Pierre-Yves Chibon |
e79148 |
sqlalchemy.distinct(model.Issue.uid)
|
|
Pierre-Yves Chibon |
e79148 |
).filter(
|
|
Pierre-Yves Chibon |
e79148 |
model.Issue.project_id == repo.id
|
|
Pierre-Yves Chibon |
e79148 |
).filter(
|
|
Pierre-Yves Chibon |
6cd6a9 |
model.Issue.uid == model.TagIssue.issue_uid
|
|
Pierre-Yves Chibon |
6cd6a9 |
).filter(
|
|
Pierre-Yves Chibon |
6cd6a9 |
model.TagIssue.tag.in_(ytags)
|
|
Pierre-Yves Chibon |
6cd6a9 |
)
|
|
Pierre-Yves Chibon |
6cd6a9 |
if notags:
|
|
Pierre-Yves Chibon |
f9f132 |
sub_q3 = session.query(
|
|
Pierre-Yves Chibon |
e79148 |
sqlalchemy.distinct(model.Issue.uid)
|
|
Pierre-Yves Chibon |
e79148 |
).filter(
|
|
Pierre-Yves Chibon |
e79148 |
model.Issue.project_id == repo.id
|
|
Pierre-Yves Chibon |
6cd6a9 |
).filter(
|
|
Pierre-Yves Chibon |
b53eb8 |
model.Issue.uid == model.TagIssue.issue_uid
|
|
Pierre-Yves Chibon |
6cd6a9 |
).filter(
|
|
Pierre-Yves Chibon |
b53eb8 |
model.TagIssue.tag.in_(notags)
|
|
Pierre-Yves Chibon |
6cd6a9 |
)
|
|
Pierre-Yves Chibon |
e79148 |
# Adjust the main query based on the parameters specified
|
|
Pierre-Yves Chibon |
e79148 |
if ytags and not notags:
|
|
Pierre-Yves Chibon |
f9f132 |
query = query.filter(model.Issue.uid.in_(sub_q2))
|
|
Pierre-Yves Chibon |
e79148 |
elif not ytags and notags:
|
|
Pierre-Yves Chibon |
f9f132 |
query = query.filter(~model.Issue.uid.in_(sub_q3))
|
|
Pierre-Yves Chibon |
e79148 |
elif ytags and notags:
|
|
Pierre-Yves Chibon |
f9f132 |
final_set = set(sub_q2.all()) - set(sub_q3.all())
|
|
Pierre-Yves Chibon |
e79148 |
if final_set:
|
|
Pierre-Yves Chibon |
e79148 |
query = query.filter(model.Issue.uid.in_(list(final_set)))
|
|
Pierre-Yves Chibon |
5b2947 |
|
|
Pierre-Yves Chibon |
a10ca7 |
if assignee is not None:
|
|
Pierre-Yves Chibon |
ba4b04 |
if str(assignee).lower() not in ['false', '0', 'true', '1']:
|
|
Pierre-Yves Chibon |
ed38ee |
user2 = aliased(model.User)
|
|
Pierre-Yves Chibon |
571a45 |
if assignee.startswith('!'):
|
|
Pierre-Yves Chibon |
571a45 |
sub = session.query(
|
|
Pierre-Yves Chibon |
571a45 |
model.Issue.uid
|
|
Pierre-Yves Chibon |
571a45 |
).filter(
|
|
Pierre-Yves Chibon |
571a45 |
model.Issue.assignee_id == user2.id
|
|
Pierre-Yves Chibon |
571a45 |
).filter(
|
|
Pierre-Yves Chibon |
571a45 |
user2.user == assignee[1:]
|
|
Pierre-Yves Chibon |
571a45 |
)
|
|
Pierre-Yves Chibon |
571a45 |
|
|
Pierre-Yves Chibon |
571a45 |
query = query.filter(
|
|
Pierre-Yves Chibon |
571a45 |
~model.Issue.uid.in_(sub)
|
|
Pierre-Yves Chibon |
571a45 |
)
|
|
Pierre-Yves Chibon |
571a45 |
else:
|
|
Pierre-Yves Chibon |
571a45 |
query = query.filter(
|
|
Pierre-Yves Chibon |
571a45 |
model.Issue.assignee_id == user2.id
|
|
Pierre-Yves Chibon |
571a45 |
).filter(
|
|
Pierre-Yves Chibon |
571a45 |
user2.user == assignee
|
|
Pierre-Yves Chibon |
571a45 |
)
|
|
Pierre-Yves Chibon |
ba4b04 |
elif str(assignee).lower() in ['true', '1']:
|
|
Pierre-Yves Chibon |
ba4b04 |
query = query.filter(
|
|
Pierre-Yves Chibon |
ba4b04 |
model.Issue.assignee_id != None
|
|
Pierre-Yves Chibon |
ba4b04 |
)
|
|
Pierre-Yves Chibon |
685db8 |
else:
|
|
Pierre-Yves Chibon |
685db8 |
query = query.filter(
|
|
Pierre-Yves Chibon |
685db8 |
model.Issue.assignee_id == None
|
|
Pierre-Yves Chibon |
685db8 |
)
|
|
Pierre-Yves Chibon |
02e68a |
if author is not None:
|
|
Pierre-Yves Chibon |
02e68a |
query = query.filter(
|
|
Pierre-Yves Chibon |
7407c0 |
model.Issue.user_id == model.User.id
|
|
Pierre-Yves Chibon |
7407c0 |
).filter(
|
|
Pierre-Yves Chibon |
7407c0 |
model.User.user == author
|
|
Pierre-Yves Chibon |
7407c0 |
)
|
|
Pierre-Yves Chibon |
4d1cbe |
|
|
Pierre-Yves Chibon |
73a5b8 |
if private is False:
|
|
Pierre-Yves Chibon |
73a5b8 |
query = query.filter(
|
|
Pierre-Yves Chibon |
73a5b8 |
model.Issue.private == False
|
|
Pierre-Yves Chibon |
73a5b8 |
)
|
|
Pierre-Yves Chibon |
73a5b8 |
elif isinstance(private, basestring):
|
|
Pierre-Yves Chibon |
1d9d7d |
user2 = aliased(model.User)
|
|
Pierre-Yves Chibon |
73a5b8 |
query = query.filter(
|
|
Pierre-Yves Chibon |
e93c34 |
sqlalchemy.or_(
|
|
Pierre-Yves Chibon |
73a5b8 |
model.Issue.private == False,
|
|
Pierre-Yves Chibon |
e93c34 |
sqlalchemy.and_(
|
|
Pierre-Yves Chibon |
73a5b8 |
model.Issue.private == True,
|
|
Pierre-Yves Chibon |
1d9d7d |
model.Issue.user_id == user2.id,
|
|
Pierre-Yves Chibon |
1d9d7d |
user2.user == private,
|
|
Pierre-Yves Chibon |
73a5b8 |
)
|
|
Pierre-Yves Chibon |
73a5b8 |
)
|
|
Pierre-Yves Chibon |
73a5b8 |
)
|
|
Pierre-Yves Chibon |
73a5b8 |
|
|
Pierre-Yves Chibon |
7e8958 |
if milestones is not None and milestones != []:
|
|
Pierre-Yves Chibon |
7e8958 |
if isinstance(milestones, basestring):
|
|
Pierre-Yves Chibon |
7e8958 |
milestones = [milestones]
|
|
Pierre-Yves Chibon |
7e8958 |
|
|
Pierre-Yves Chibon |
7e8958 |
query = query.filter(
|
|
Pierre-Yves Chibon |
7e8958 |
model.Issue.milestone.in_(milestones)
|
|
Pierre-Yves Chibon |
7e8958 |
)
|
|
Pierre-Yves Chibon |
7e8958 |
|
|
Pierre-Yves Chibon |
b4970f |
if custom_search:
|
|
Pierre-Yves Chibon |
b4970f |
constraints = []
|
|
Pierre-Yves Chibon |
b4970f |
for key in custom_search:
|
|
Pierre-Yves Chibon |
b4970f |
value = custom_search[key]
|
|
Pierre-Yves Chibon |
b4970f |
if '*' in value:
|
|
Pierre-Yves Chibon |
b4970f |
value = value.replace('*', '%')
|
|
Pierre-Yves Chibon |
b4970f |
constraints.append(
|
|
Pierre-Yves Chibon |
b4970f |
sqlalchemy.and_(
|
|
Pierre-Yves Chibon |
b4970f |
model.IssueKeys.name == key,
|
|
Pierre-Yves Chibon |
b4970f |
model.IssueValues.value.ilike(value)
|
|
Pierre-Yves Chibon |
b4970f |
)
|
|
Pierre-Yves Chibon |
b4970f |
)
|
|
Pierre-Yves Chibon |
b4970f |
else:
|
|
Pierre-Yves Chibon |
b4970f |
constraints.append(
|
|
Pierre-Yves Chibon |
b4970f |
sqlalchemy.and_(
|
|
Pierre-Yves Chibon |
b4970f |
model.IssueKeys.name == key,
|
|
Pierre-Yves Chibon |
b4970f |
model.IssueValues.value == value
|
|
Pierre-Yves Chibon |
b4970f |
)
|
|
Pierre-Yves Chibon |
b4970f |
)
|
|
Pierre-Yves Chibon |
b4970f |
if constraints:
|
|
Pierre-Yves Chibon |
b4970f |
query = query.filter(
|
|
Pierre-Yves Chibon |
b4970f |
model.Issue.uid == model.IssueValues.issue_uid
|
|
Pierre-Yves Chibon |
b4970f |
).filter(
|
|
Pierre-Yves Chibon |
b4970f |
model.IssueValues.key_id == model.IssueKeys.id
|
|
Pierre-Yves Chibon |
b4970f |
)
|
|
Pierre-Yves Chibon |
b4970f |
query = query.filter(
|
|
Pierre-Yves Chibon |
b4970f |
sqlalchemy.or_(
|
|
Pierre-Yves Chibon |
b4970f |
(const for const in constraints)
|
|
Pierre-Yves Chibon |
b4970f |
)
|
|
Pierre-Yves Chibon |
b4970f |
)
|
|
Pierre-Yves Chibon |
b4970f |
|
|
Pierre-Yves Chibon |
1d9d7d |
query = session.query(
|
|
Pierre-Yves Chibon |
1d9d7d |
model.Issue
|
|
Pierre-Yves Chibon |
1d9d7d |
).filter(
|
|
Pierre-Yves Chibon |
af678e |
model.Issue.uid.in_(query.subquery())
|
|
Pierre-Yves Chibon |
af678e |
).filter(
|
|
Pierre-Yves Chibon |
af678e |
model.Issue.project_id == repo.id
|
|
Pierre-Yves Chibon |
1d9d7d |
)
|
|
Pierre-Yves Chibon |
1d9d7d |
|
|
“AnjaliPardeshi” |
fa7e4c |
if search_pattern is not None:
|
|
Pierre-Yves Chibon |
130ecb |
query = query.filter(
|
|
“AnjaliPardeshi” |
fa7e4c |
model.Issue.title.like('%' + str(search_pattern) + '%')
|
|
“AnjaliPardeshi” |
fa7e4c |
)
|
|
“AnjaliPardeshi” |
fa7e4c |
|
|
Pierre-Yves Chibon |
5657d2 |
query = query.order_by(
|
|
Pierre-Yves Chibon |
5657d2 |
model.Issue.date_created.desc()
|
|
Pierre-Yves Chibon |
5657d2 |
)
|
|
Anthony Lackey |
78e2eb |
|
|
Pierre-Yves Chibon |
b585e1 |
if issueid is not None or issueuid is not None:
|
|
Pierre-Yves Chibon |
5b2947 |
output = query.first()
|
|
Pierre-Yves Chibon |
e69252 |
elif count:
|
|
Pierre-Yves Chibon |
e69252 |
output = query.count()
|
|
Pierre-Yves Chibon |
5b2947 |
else:
|
|
Pierre-Yves Chibon |
f7bee3 |
if offset:
|
|
Pierre-Yves Chibon |
f7bee3 |
query = query.offset(offset)
|
|
Pierre-Yves Chibon |
f7bee3 |
if limit:
|
|
Pierre-Yves Chibon |
f7bee3 |
query = query.limit(limit)
|
|
Pierre-Yves Chibon |
5b2947 |
output = query.all()
|
|
Pierre-Yves Chibon |
562d75 |
|
|
Pierre-Yves Chibon |
5b2947 |
return output
|
|
Pierre-Yves Chibon |
562d75 |
|
|
Pierre-Yves Chibon |
35112d |
|
|
Pierre-Yves Chibon |
64b484 |
def get_tags_of_project(session, project, pattern=None):
|
|
Pierre-Yves Chibon |
8efc30 |
''' Returns the list of tags associated with the issues of a project.
|
|
Pierre-Yves Chibon |
8efc30 |
'''
|
|
Pierre-Yves Chibon |
8efc30 |
query = session.query(
|
|
Pierre-Yves Chibon |
8efc30 |
model.Tag
|
|
Pierre-Yves Chibon |
8efc30 |
).filter(
|
|
Pierre-Yves Chibon |
8efc30 |
model.Tag.tag == model.TagIssue.tag
|
|
Pierre-Yves Chibon |
8efc30 |
).filter(
|
|
Pierre-Yves Chibon |
4aca3b |
model.TagIssue.issue_uid == model.Issue.uid
|
|
Pierre-Yves Chibon |
8efc30 |
).filter(
|
|
Pierre-Yves Chibon |
8efc30 |
model.Issue.project_id == project.id
|
|
Pierre-Yves Chibon |
8efc30 |
).order_by(
|
|
Pierre-Yves Chibon |
8efc30 |
model.Tag.tag
|
|
Pierre-Yves Chibon |
8efc30 |
)
|
|
Pierre-Yves Chibon |
8efc30 |
|
|
Pierre-Yves Chibon |
64b484 |
if pattern:
|
|
Pierre-Yves Chibon |
64b484 |
query = query.filter(
|
|
Pierre-Yves Chibon |
64b484 |
model.Tag.tag.ilike(pattern.replace('*', '%'))
|
|
Pierre-Yves Chibon |
64b484 |
)
|
|
Pierre-Yves Chibon |
64b484 |
|
|
Pierre-Yves Chibon |
8efc30 |
return query.all()
|
|
Pierre-Yves Chibon |
8efc30 |
|
|
Pierre-Yves Chibon |
8efc30 |
|
|
Pierre-Yves Chibon |
2e810e |
def get_tag(session, tag):
|
|
Pierre-Yves Chibon |
2e810e |
''' Returns a Tag object for the given tag text.
|
|
Pierre-Yves Chibon |
2e810e |
'''
|
|
Pierre-Yves Chibon |
2e810e |
query = session.query(
|
|
Pierre-Yves Chibon |
2e810e |
model.Tag
|
|
Pierre-Yves Chibon |
2e810e |
).filter(
|
|
Pierre-Yves Chibon |
2e810e |
model.Tag.tag == tag
|
|
Pierre-Yves Chibon |
2e810e |
)
|
|
Pierre-Yves Chibon |
2e810e |
|
|
Pierre-Yves Chibon |
2e810e |
return query.first()
|
|
Pierre-Yves Chibon |
2e810e |
|
|
Pierre-Yves Chibon |
35112d |
|
|
Pierre-Yves Chibon |
08dd17 |
def search_pull_requests(
|
|
Pierre-Yves Chibon |
a2002e |
session, requestid=None, project_id=None, project_id_from=None,
|
|
Pierre-Yves Chibon |
f7bee3 |
status=None, author=None, assignee=None, count=False,
|
|
Pierre-Yves Chibon |
f7bee3 |
offset=None, limit=None):
|
|
Pierre-Yves Chibon |
b0265c |
''' Retrieve the specified issue
|
|
Pierre-Yves Chibon |
b0265c |
'''
|
|
Pierre-Yves Chibon |
33e9fc |
|
|
Pierre-Yves Chibon |
b0265c |
query = session.query(
|
|
Pierre-Yves Chibon |
35a3e4 |
model.PullRequest
|
|
Pierre-Yves Chibon |
3a2a1c |
).order_by(
|
|
Pierre-Yves Chibon |
f1f6ba |
model.PullRequest.id.desc()
|
|
Pierre-Yves Chibon |
b0265c |
)
|
|
Pierre-Yves Chibon |
b0265c |
|
|
Pierre-Yves Chibon |
a2002e |
if requestid:
|
|
Pierre-Yves Chibon |
a2002e |
query = query.filter(
|
|
Pierre-Yves Chibon |
a2002e |
model.PullRequest.id == requestid
|
|
Pierre-Yves Chibon |
a2002e |
)
|
|
Pierre-Yves Chibon |
a2002e |
|
|
Pierre-Yves Chibon |
b0265c |
if project_id:
|
|
Pierre-Yves Chibon |
b0265c |
query = query.filter(
|
|
Pierre-Yves Chibon |
b0265c |
model.PullRequest.project_id == project_id
|
|
Pierre-Yves Chibon |
b0265c |
)
|
|
Pierre-Yves Chibon |
b0265c |
|
|
Pierre-Yves Chibon |
b0265c |
if project_id_from:
|
|
Pierre-Yves Chibon |
b0265c |
query = query.filter(
|
|
Pierre-Yves Chibon |
b0265c |
model.PullRequest.project_id_from == project_id_from
|
|
Pierre-Yves Chibon |
b0265c |
)
|
|
Pierre-Yves Chibon |
b0265c |
|
|
Pierre-Yves Chibon |
b0265c |
if status is not None:
|
|
Pierre-Yves Chibon |
c0f8df |
if isinstance(status, bool):
|
|
Pierre-Yves Chibon |
c0f8df |
if status:
|
|
Pierre-Yves Chibon |
c0f8df |
query = query.filter(
|
|
Pierre-Yves Chibon |
c0f8df |
model.PullRequest.status == 'Open'
|
|
Pierre-Yves Chibon |
c0f8df |
)
|
|
Pierre-Yves Chibon |
c0f8df |
else:
|
|
Pierre-Yves Chibon |
c0f8df |
query = query.filter(
|
|
Pierre-Yves Chibon |
c0f8df |
model.PullRequest.status != 'Open'
|
|
Pierre-Yves Chibon |
c0f8df |
)
|
|
Pierre-Yves Chibon |
c0f8df |
else:
|
|
Pierre-Yves Chibon |
c0f8df |
query = query.filter(
|
|
Pierre-Yves Chibon |
c0f8df |
model.PullRequest.status == status
|
|
Pierre-Yves Chibon |
c0f8df |
)
|
|
Pierre-Yves Chibon |
b0265c |
|
|
Pierre-Yves Chibon |
dcfb16 |
if assignee is not None:
|
|
Pierre-Yves Chibon |
dcfb16 |
if str(assignee).lower() not in ['false', '0', 'true', '1']:
|
|
Pierre-Yves Chibon |
dcfb16 |
user2 = aliased(model.User)
|
|
Pierre-Yves Chibon |
dcfb16 |
if assignee.startswith('!'):
|
|
Pierre-Yves Chibon |
dcfb16 |
sub = session.query(
|
|
Pierre-Yves Chibon |
dcfb16 |
model.PullRequest.uid
|
|
Pierre-Yves Chibon |
dcfb16 |
).filter(
|
|
Pierre-Yves Chibon |
dcfb16 |
model.PullRequest.assignee_id == user2.id
|
|
Pierre-Yves Chibon |
dcfb16 |
).filter(
|
|
Pierre-Yves Chibon |
dcfb16 |
user2.user == assignee[1:]
|
|
Pierre-Yves Chibon |
dcfb16 |
)
|
|
Pierre-Yves Chibon |
dcfb16 |
|
|
Pierre-Yves Chibon |
dcfb16 |
query = query.filter(
|
|
Pierre-Yves Chibon |
dcfb16 |
~model.PullRequest.uid.in_(sub)
|
|
Pierre-Yves Chibon |
dcfb16 |
)
|
|
Pierre-Yves Chibon |
dcfb16 |
else:
|
|
Pierre-Yves Chibon |
dcfb16 |
query = query.filter(
|
|
Pierre-Yves Chibon |
dcfb16 |
model.PullRequest.assignee_id == user2.id
|
|
Pierre-Yves Chibon |
dcfb16 |
).filter(
|
|
Pierre-Yves Chibon |
dcfb16 |
user2.user == assignee
|
|
Pierre-Yves Chibon |
dcfb16 |
)
|
|
Pierre-Yves Chibon |
dcfb16 |
elif str(assignee).lower() in ['true', '1']:
|
|
Pierre-Yves Chibon |
dcfb16 |
query = query.filter(
|
|
Pierre-Yves Chibon |
dcfb16 |
model.PullRequest.assignee_id != None
|
|
Pierre-Yves Chibon |
dcfb16 |
)
|
|
Pierre-Yves Chibon |
dcfb16 |
else:
|
|
Pierre-Yves Chibon |
dcfb16 |
query = query.filter(
|
|
Pierre-Yves Chibon |
dcfb16 |
model.PullRequest.assignee_id == None
|
|
Pierre-Yves Chibon |
dcfb16 |
)
|
|
Pierre-Yves Chibon |
dcfb16 |
|
|
Pierre-Yves Chibon |
dcfb16 |
if author is not None:
|
|
Pierre-Yves Chibon |
dcfb16 |
query = query.filter(
|
|
Pierre-Yves Chibon |
dcfb16 |
model.PullRequest.user_id == model.User.id
|
|
Pierre-Yves Chibon |
dcfb16 |
).filter(
|
|
Pierre-Yves Chibon |
dcfb16 |
model.User.user == author
|
|
Pierre-Yves Chibon |
dcfb16 |
)
|
|
Pierre-Yves Chibon |
dcfb16 |
|
|
Pierre-Yves Chibon |
a2002e |
if requestid:
|
|
Pierre-Yves Chibon |
a2002e |
output = query.first()
|
|
Pierre-Yves Chibon |
6f3845 |
elif count:
|
|
Pierre-Yves Chibon |
6f3845 |
output = query.count()
|
|
Pierre-Yves Chibon |
a2002e |
else:
|
|
Pierre-Yves Chibon |
f7bee3 |
if offset:
|
|
Pierre-Yves Chibon |
f7bee3 |
query = query.offset(offset)
|
|
Pierre-Yves Chibon |
f7bee3 |
if limit:
|
|
Pierre-Yves Chibon |
f7bee3 |
query = query.limit(limit)
|
|
Pierre-Yves Chibon |
a2002e |
output = query.all()
|
|
Pierre-Yves Chibon |
35112d |
|
|
Pierre-Yves Chibon |
a2002e |
return output
|
|
Pierre-Yves Chibon |
42a02c |
|
|
Pierre-Yves Chibon |
42a02c |
|
|
Pierre-Yves Chibon |
2e464a |
def close_pull_request(session, request, user, requestfolder, merged=True):
|
|
Pierre-Yves Chibon |
42a02c |
''' Close the provided pull-request.
|
|
Pierre-Yves Chibon |
42a02c |
'''
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Pierre-Yves Chibon |
1e978e |
|
|
Pierre-Yves Chibon |
f86685 |
if merged is True:
|
|
Pierre-Yves Chibon |
f86685 |
request.status = 'Merged'
|
|
Pierre-Yves Chibon |
f86685 |
else:
|
|
Pierre-Yves Chibon |
f86685 |
request.status = 'Closed'
|
|
Pierre-Yves Chibon |
50644e |
request.closed_by_id = user_obj.id
|
|
Pierre-Yves Chibon |
e8692f |
request.closed_at = datetime.datetime.utcnow()
|
|
Pierre-Yves Chibon |
42a02c |
session.add(request)
|
|
Pierre-Yves Chibon |
42a02c |
session.flush()
|
|
Pierre-Yves Chibon |
4d1cbe |
|
|
Pierre-Yves Chibon |
b53eb8 |
if merged is True:
|
|
Pierre-Yves Chibon |
1e978e |
pagure.lib.notify.notify_merge_pull_request(request, user_obj)
|
|
Johan Cwiklinski |
86d9c4 |
else:
|
|
Pierre-Yves Chibon |
1e978e |
pagure.lib.notify.notify_cancelled_pull_request(request, user_obj)
|
|
Pierre-Yves Chibon |
5fdf85 |
|
|
Pierre-Yves Chibon |
fe5017 |
pagure.lib.git.update_git(
|
|
Pierre-Yves Chibon |
a482cb |
request, repo=request.project, repofolder=requestfolder)
|
|
Pierre-Yves Chibon |
a1280f |
|
|
Pierre-Yves Chibon |
9af6f1 |
pagure.lib.add_pull_request_comment(
|
|
Pierre-Yves Chibon |
9af6f1 |
session, request,
|
|
Pierre-Yves Chibon |
0a0445 |
commit=None, tree_id=None, filename=None, row=None,
|
|
Pierre-Yves Chibon |
9af6f1 |
comment='Pull-Request has been %s by %s' % (
|
|
Pierre-Yves Chibon |
9af6f1 |
request.status.lower(), user),
|
|
Pierre-Yves Chibon |
9af6f1 |
user=user,
|
|
Pierre-Yves Chibon |
9af6f1 |
requestfolder=requestfolder,
|
|
Pierre-Yves Chibon |
9af6f1 |
notify=False, notification=True
|
|
Pierre-Yves Chibon |
9af6f1 |
)
|
|
Pierre-Yves Chibon |
9af6f1 |
|
|
Pierre-Yves Chibon |
c898e5 |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
c898e5 |
request.project,
|
|
Pierre-Yves Chibon |
c898e5 |
topic='pull-request.closed',
|
|
Pierre-Yves Chibon |
c898e5 |
msg=dict(
|
|
Pierre-Yves Chibon |
972598 |
pullrequest=request.to_json(public=True),
|
|
Pierre-Yves Chibon |
0ce3a2 |
merged=merged,
|
|
Pierre-Yves Chibon |
0ce3a2 |
agent=user_obj.username,
|
|
Pierre-Yves Chibon |
482d84 |
),
|
|
Pierre-Yves Chibon |
2e464a |
redis=REDIS,
|
|
Pierre-Yves Chibon |
0ce3a2 |
)
|
|
Pierre-Yves Chibon |
0ce3a2 |
|
|
Pierre-Yves Chibon |
e1497f |
|
|
Pierre-Yves Chibon |
06785e |
def reset_status_pull_request(session, project):
|
|
Pierre-Yves Chibon |
06785e |
''' Reset the status of all opened Pull-Requests of a project.
|
|
Pierre-Yves Chibon |
06785e |
'''
|
|
Pierre-Yves Chibon |
06785e |
requests = search_pull_requests(
|
|
Pierre-Yves Chibon |
06785e |
session, project_id=project.id, status='Open')
|
|
Pierre-Yves Chibon |
06785e |
|
|
Pierre-Yves Chibon |
06785e |
for request in requests:
|
|
Pierre-Yves Chibon |
06785e |
request.merge_status = None
|
|
Pierre-Yves Chibon |
06785e |
session.add(request)
|
|
Pierre-Yves Chibon |
06785e |
|
|
Pierre-Yves Chibon |
06785e |
session.commit()
|
|
Pierre-Yves Chibon |
06785e |
|
|
Pierre-Yves Chibon |
4d1cbe |
|
|
Pierre-Yves Chibon |
4d1cbe |
def get_issue_statuses(session):
|
|
Pierre-Yves Chibon |
4d1cbe |
''' Return the complete list of status an issue can have.
|
|
Pierre-Yves Chibon |
4d1cbe |
'''
|
|
Pierre-Yves Chibon |
4d1cbe |
output = []
|
|
Pierre-Yves Chibon |
4d1cbe |
statuses = session.query(model.StatusIssue).all()
|
|
Pierre-Yves Chibon |
4d1cbe |
for status in statuses:
|
|
Pierre-Yves Chibon |
4d1cbe |
output.append(status.status)
|
|
Pierre-Yves Chibon |
4d1cbe |
return output
|
|
Pierre-Yves Chibon |
7c47d2 |
|
|
Pierre-Yves Chibon |
7c47d2 |
|
|
Pierre-Yves Chibon |
4a2966 |
def get_issue_comment(session, issue_uid, comment_id):
|
|
Pierre-Yves Chibon |
4a2966 |
''' Return a specific comment of a specified issue.
|
|
Pierre-Yves Chibon |
4a2966 |
'''
|
|
Pierre-Yves Chibon |
4a2966 |
query = session.query(
|
|
Pierre-Yves Chibon |
4a2966 |
model.IssueComment
|
|
Pierre-Yves Chibon |
4a2966 |
).filter(
|
|
Pierre-Yves Chibon |
4a2966 |
model.IssueComment.issue_uid == issue_uid
|
|
Pierre-Yves Chibon |
4a2966 |
).filter(
|
|
Pierre-Yves Chibon |
4a2966 |
model.IssueComment.id == comment_id
|
|
Pierre-Yves Chibon |
4a2966 |
)
|
|
Pierre-Yves Chibon |
4a2966 |
|
|
Pierre-Yves Chibon |
4a2966 |
return query.first()
|
|
Pierre-Yves Chibon |
4a2966 |
|
|
Pierre-Yves Chibon |
1d9d7d |
|
|
Pierre-Yves Chibon |
83791f |
def get_request_comment(session, request_uid, comment_id):
|
|
Pierre-Yves Chibon |
cb9dd7 |
''' Return a specific comment of a specified request.
|
|
Pierre-Yves Chibon |
83791f |
'''
|
|
Pierre-Yves Chibon |
83791f |
query = session.query(
|
|
Pierre-Yves Chibon |
83791f |
model.PullRequestComment
|
|
Pierre-Yves Chibon |
83791f |
).filter(
|
|
Pierre-Yves Chibon |
83791f |
model.PullRequestComment.pull_request_uid == request_uid
|
|
Pierre-Yves Chibon |
83791f |
).filter(
|
|
Pierre-Yves Chibon |
83791f |
model.PullRequestComment.id == comment_id
|
|
Pierre-Yves Chibon |
83791f |
)
|
|
Pierre-Yves Chibon |
83791f |
|
|
Pierre-Yves Chibon |
83791f |
return query.first()
|
|
Pierre-Yves Chibon |
83791f |
|
|
Pierre-Yves Chibon |
4a2966 |
|
|
Pierre-Yves Chibon |
bdd624 |
def get_issue_by_uid(session, issue_uid):
|
|
Pierre-Yves Chibon |
bdd624 |
''' Return the issue corresponding to the specified unique identifier.
|
|
Pierre-Yves Chibon |
bdd624 |
|
|
Pierre-Yves Chibon |
bdd624 |
:arg session: the session to use to connect to the database.
|
|
Pierre-Yves Chibon |
bdd624 |
:arg issue_uid: the unique identifier of an issue. This identifier is
|
|
Pierre-Yves Chibon |
fe5017 |
unique accross all projects on this pagure instance and should be
|
|
Pierre-Yves Chibon |
fe5017 |
unique accross multiple pagure instances as well
|
|
Pierre-Yves Chibon |
bdd624 |
:type issue_uid: str or None
|
|
Pierre-Yves Chibon |
bdd624 |
|
|
Pierre-Yves Chibon |
bdd624 |
:return: A single Issue object.
|
|
Pierre-Yves Chibon |
fe5017 |
:rtype: pagure.lib.model.Issue
|
|
Pierre-Yves Chibon |
bdd624 |
|
|
Pierre-Yves Chibon |
bdd624 |
'''
|
|
Pierre-Yves Chibon |
bdd624 |
query = session.query(
|
|
Pierre-Yves Chibon |
bdd624 |
model.Issue
|
|
Pierre-Yves Chibon |
bdd624 |
).filter(
|
|
Pierre-Yves Chibon |
bdd624 |
model.Issue.uid == issue_uid
|
|
Pierre-Yves Chibon |
bdd624 |
)
|
|
Pierre-Yves Chibon |
bdd624 |
return query.first()
|
|
Pierre-Yves Chibon |
bdd624 |
|
|
Pierre-Yves Chibon |
bdd624 |
|
|
Pierre-Yves Chibon |
9c5f7f |
def get_request_by_uid(session, request_uid):
|
|
Pierre-Yves Chibon |
9c5f7f |
''' Return the request corresponding to the specified unique identifier.
|
|
Pierre-Yves Chibon |
9c5f7f |
|
|
Pierre-Yves Chibon |
9c5f7f |
:arg session: the session to use to connect to the database.
|
|
Pierre-Yves Chibon |
9c5f7f |
:arg request_uid: the unique identifier of a request. This identifier is
|
|
Pierre-Yves Chibon |
fe5017 |
unique accross all projects on this pagure instance and should be
|
|
Pierre-Yves Chibon |
fe5017 |
unique accross multiple pagure instances as well
|
|
Pierre-Yves Chibon |
9c5f7f |
:type request_uid: str or None
|
|
Pierre-Yves Chibon |
9c5f7f |
|
|
Pierre-Yves Chibon |
9c5f7f |
:return: A single Issue object.
|
|
Pierre-Yves Chibon |
fe5017 |
:rtype: pagure.lib.model.PullRequest
|
|
Pierre-Yves Chibon |
9c5f7f |
|
|
Pierre-Yves Chibon |
9c5f7f |
'''
|
|
Pierre-Yves Chibon |
9c5f7f |
query = session.query(
|
|
Pierre-Yves Chibon |
9c5f7f |
model.PullRequest
|
|
Pierre-Yves Chibon |
9c5f7f |
).filter(
|
|
Pierre-Yves Chibon |
9c5f7f |
model.PullRequest.uid == request_uid
|
|
Pierre-Yves Chibon |
9c5f7f |
)
|
|
Pierre-Yves Chibon |
9c5f7f |
return query.first()
|
|
Pierre-Yves Chibon |
9c5f7f |
|
|
Pierre-Yves Chibon |
9c5f7f |
|
|
Pierre-Yves Chibon |
d236dc |
def get_pull_request_flag_by_uid(session, flag_uid):
|
|
Pierre-Yves Chibon |
d236dc |
''' Return the flag corresponding to the specified unique identifier.
|
|
Pierre-Yves Chibon |
d236dc |
|
|
Pierre-Yves Chibon |
d236dc |
:arg session: the session to use to connect to the database.
|
|
Pierre-Yves Chibon |
d236dc |
:arg flag_uid: the unique identifier of a request. This identifier is
|
|
Pierre-Yves Chibon |
d236dc |
unique accross all flags on this pagure instance and should be
|
|
Pierre-Yves Chibon |
d236dc |
unique accross multiple pagure instances as well
|
|
Pierre-Yves Chibon |
d236dc |
:type request_uid: str or None
|
|
Pierre-Yves Chibon |
d236dc |
|
|
Pierre-Yves Chibon |
d236dc |
:return: A single Issue object.
|
|
Pierre-Yves Chibon |
d236dc |
:rtype: pagure.lib.model.PullRequestFlag
|
|
Pierre-Yves Chibon |
d236dc |
|
|
Pierre-Yves Chibon |
d236dc |
'''
|
|
Pierre-Yves Chibon |
d236dc |
query = session.query(
|
|
Pierre-Yves Chibon |
d236dc |
model.PullRequestFlag
|
|
Pierre-Yves Chibon |
d236dc |
).filter(
|
|
Pierre-Yves Chibon |
d236dc |
model.PullRequestFlag.uid == flag_uid.strip() if flag_uid else None
|
|
Pierre-Yves Chibon |
d236dc |
)
|
|
Pierre-Yves Chibon |
d236dc |
return query.first()
|
|
Pierre-Yves Chibon |
d236dc |
|
|
Pierre-Yves Chibon |
d236dc |
|
|
Pierre-Yves Chibon |
b69b5c |
def set_up_user(session, username, fullname, default_email,
|
|
Patrick Uiterwijk |
0e5f4a |
emails=None, ssh_key=None, keydir=None):
|
|
Pierre-Yves Chibon |
c2aa0d |
''' Set up a new user into the database or update its information. '''
|
|
Pierre-Yves Chibon |
f05535 |
user = search_user(session, username=username)
|
|
Pierre-Yves Chibon |
c2aa0d |
if not user:
|
|
Pierre-Yves Chibon |
c2aa0d |
user = model.User(
|
|
Pierre-Yves Chibon |
c2aa0d |
user=username,
|
|
Pierre-Yves Chibon |
71ee98 |
fullname=fullname,
|
|
Pierre-Yves Chibon |
96eb13 |
default_email=default_email
|
|
Pierre-Yves Chibon |
71ee98 |
)
|
|
Pierre-Yves Chibon |
c2aa0d |
session.add(user)
|
|
Pierre-Yves Chibon |
c2aa0d |
session.flush()
|
|
Pierre-Yves Chibon |
c2aa0d |
|
|
Pierre-Yves Chibon |
c2aa0d |
if user.fullname != fullname:
|
|
Pierre-Yves Chibon |
c2aa0d |
user.fullname = fullname
|
|
Pierre-Yves Chibon |
c2aa0d |
session.add(user)
|
|
Pierre-Yves Chibon |
c2aa0d |
session.flush()
|
|
Pierre-Yves Chibon |
c2aa0d |
|
|
Pierre-Yves Chibon |
96eb13 |
if emails:
|
|
Pierre-Yves Chibon |
96eb13 |
emails = set(emails)
|
|
Pierre-Yves Chibon |
96eb13 |
else:
|
|
Pierre-Yves Chibon |
96eb13 |
emails = set()
|
|
Pierre-Yves Chibon |
96eb13 |
emails.add(default_email)
|
|
Pierre-Yves Chibon |
96eb13 |
for email in emails:
|
|
Pierre-Yves Chibon |
96eb13 |
add_email_to_user(session, user, email)
|
|
Pierre-Yves Chibon |
5ccd12 |
|
|
Pierre-Yves Chibon |
b69b5c |
if ssh_key and not user.public_ssh_key:
|
|
Patrick Uiterwijk |
0e5f4a |
update_user_ssh(session, user, ssh_key, keydir)
|
|
Pierre-Yves Chibon |
b69b5c |
|
|
Pierre-Yves Chibon |
5ccd12 |
return user
|
|
Pierre-Yves Chibon |
5ccd12 |
|
|
Pierre-Yves Chibon |
5ccd12 |
|
|
Pierre-Yves Chibon |
5ccd12 |
def add_email_to_user(session, user, user_email):
|
|
Pierre-Yves Chibon |
5ccd12 |
''' Add the provided email to the specified user. '''
|
|
Pierre-Yves Chibon |
8b2894 |
emails = [email.email for email in user.emails]
|
|
Pierre-Yves Chibon |
8b2894 |
if user_email not in emails:
|
|
Pierre-Yves Chibon |
c2aa0d |
useremail = model.UserEmail(
|
|
Pierre-Yves Chibon |
c2aa0d |
user_id=user.id,
|
|
Pierre-Yves Chibon |
c2aa0d |
email=user_email)
|
|
Pierre-Yves Chibon |
c2aa0d |
session.add(useremail)
|
|
Pierre-Yves Chibon |
c2aa0d |
session.flush()
|
|
Pierre-Yves Chibon |
8f25f2 |
|
|
Pierre-Yves Chibon |
8f25f2 |
|
|
Patrick Uiterwijk |
0e5f4a |
def update_user_ssh(session, user, ssh_key, keydir):
|
|
Pierre-Yves Chibon |
8f25f2 |
''' Set up a new user into the database or update its information. '''
|
|
Pierre-Yves Chibon |
8f25f2 |
if isinstance(user, basestring):
|
|
Pierre-Yves Chibon |
6aa385 |
user = get_user(session, user)
|
|
Pierre-Yves Chibon |
8f25f2 |
|
|
Pierre-Yves Chibon |
eb310a |
user.public_ssh_key = ssh_key
|
|
Pierre-Yves Chibon |
eb310a |
if keydir and user.public_ssh_key:
|
|
Pierre-Yves Chibon |
eb310a |
create_user_ssh_keys_on_disk(user, keydir)
|
|
Patrick Uiterwijk |
5c8d02 |
pagure.lib.git.generate_gitolite_acls()
|
|
Pierre-Yves Chibon |
eb310a |
session.add(user)
|
|
Pierre-Yves Chibon |
eb310a |
session.flush()
|
|
Pierre-Yves Chibon |
f7d963 |
|
|
Pierre-Yves Chibon |
f7d963 |
|
|
Pierre-Yves Chibon |
95245b |
def avatar_url_from_openid(openid, size=64, default='retro', dns=False):
|
|
Pierre-Yves Chibon |
95245b |
"""
|
|
Pierre-Yves Chibon |
95245b |
Our own implementation since fas doesn't support this nicely yet.
|
|
Pierre-Yves Chibon |
95245b |
"""
|
|
Pierre-Yves Chibon |
95245b |
|
|
Pierre-Yves Chibon |
95245b |
if dns: # pragma: no cover
|
|
Pierre-Yves Chibon |
95245b |
# This makes an extra DNS SRV query, which can slow down our webapps.
|
|
Pierre-Yves Chibon |
95245b |
# It is necessary for libravatar federation, though.
|
|
Pierre-Yves Chibon |
95245b |
import libravatar
|
|
Pierre-Yves Chibon |
95245b |
return libravatar.libravatar_url(
|
|
Pierre-Yves Chibon |
95245b |
openid=openid,
|
|
Pierre-Yves Chibon |
95245b |
size=size,
|
|
Pierre-Yves Chibon |
95245b |
default=default,
|
|
Pierre-Yves Chibon |
95245b |
)
|
|
Pierre-Yves Chibon |
95245b |
else:
|
|
Pierre-Yves Chibon |
7407c0 |
import urllib
|
|
Pierre-Yves Chibon |
7407c0 |
import hashlib
|
|
Pierre-Yves Chibon |
95245b |
query = urllib.urlencode({'s': size, 'd': default})
|
|
Pierre-Yves Chibon |
b8c7ae |
hashhex = hashlib.sha256(openid).hexdigest()
|
|
Pierre-Yves Chibon |
b8c7ae |
return "https://seccdn.libravatar.org/avatar/%s?%s" % (
|
|
Pierre-Yves Chibon |
b8c7ae |
hashhex, query)
|
|
Pierre-Yves Chibon |
214a1e |
|
|
Pierre-Yves Chibon |
214a1e |
|
|
Pierre-Yves Chibon |
2e464a |
def update_tags(session, obj, tags, username, ticketfolder):
|
|
Pierre-Yves Chibon |
931b1d |
""" Update the tags of a specified object (adding or removing them).
|
|
Pierre-Yves Chibon |
931b1d |
This object can be either an issue or a project.
|
|
Pierre-Yves Chibon |
214a1e |
|
|
Pierre-Yves Chibon |
214a1e |
"""
|
|
Pierre-Yves Chibon |
214a1e |
if isinstance(tags, basestring):
|
|
Pierre-Yves Chibon |
214a1e |
tags = [tags]
|
|
Pierre-Yves Chibon |
214a1e |
|
|
Pierre-Yves Chibon |
931b1d |
toadd = set(tags) - set(obj.tags_text)
|
|
Pierre-Yves Chibon |
931b1d |
torm = set(obj.tags_text) - set(tags)
|
|
Pierre-Yves Chibon |
214a1e |
messages = []
|
|
Pierre-Yves Chibon |
23368d |
if toadd:
|
|
Pierre-Yves Chibon |
214a1e |
messages.append(
|
|
Pierre-Yves Chibon |
931b1d |
add_tag_obj(
|
|
Pierre-Yves Chibon |
214a1e |
session,
|
|
Pierre-Yves Chibon |
931b1d |
obj=obj,
|
|
Pierre-Yves Chibon |
23368d |
tags=toadd,
|
|
Pierre-Yves Chibon |
214a1e |
user=username,
|
|
Pierre-Yves Chibon |
214a1e |
ticketfolder=ticketfolder,
|
|
Pierre-Yves Chibon |
214a1e |
)
|
|
Pierre-Yves Chibon |
214a1e |
)
|
|
Pierre-Yves Chibon |
214a1e |
|
|
Pierre-Yves Chibon |
214a1e |
if torm:
|
|
Pierre-Yves Chibon |
23368d |
messages.append(
|
|
Pierre-Yves Chibon |
931b1d |
remove_tags_obj(
|
|
Pierre-Yves Chibon |
214a1e |
session,
|
|
Pierre-Yves Chibon |
931b1d |
obj=obj,
|
|
Pierre-Yves Chibon |
214a1e |
tags=torm,
|
|
Pierre-Yves Chibon |
e293ee |
user=username,
|
|
Pierre-Yves Chibon |
214a1e |
ticketfolder=ticketfolder,
|
|
Pierre-Yves Chibon |
214a1e |
)
|
|
Pierre-Yves Chibon |
214a1e |
)
|
|
Pierre-Yves Chibon |
214a1e |
session.commit()
|
|
Pierre-Yves Chibon |
214a1e |
|
|
Pierre-Yves Chibon |
214a1e |
return messages
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
f49685 |
def update_dependency_issue(
|
|
Pierre-Yves Chibon |
2e464a |
session, repo, issue, depends, username, ticketfolder):
|
|
Pierre-Yves Chibon |
a86f36 |
""" Update the dependency of a specified issue (adding or removing them)
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
a86f36 |
"""
|
|
Pierre-Yves Chibon |
a86f36 |
if isinstance(depends, basestring):
|
|
Pierre-Yves Chibon |
a86f36 |
depends = [depends]
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
a86f36 |
toadd = set(depends) - set(issue.depends_text)
|
|
Pierre-Yves Chibon |
a86f36 |
torm = set(issue.depends_text) - set(depends)
|
|
Pierre-Yves Chibon |
a86f36 |
messages = []
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
a86f36 |
# Add issue depending
|
|
Pierre-Yves Chibon |
a86f36 |
for depend in toadd:
|
|
Pierre-Yves Chibon |
a86f36 |
issue_depend = search_issues(session, repo, issueid=depend)
|
|
Pierre-Yves Chibon |
2e498a |
if issue_depend is None:
|
|
Pierre-Yves Chibon |
a86f36 |
continue
|
|
Pierre-Yves Chibon |
2e498a |
if issue_depend.id in issue.depends_text: # pragma: no cover
|
|
Pierre-Yves Chibon |
2e498a |
# we should never be in this case but better safe than sorry...
|
|
Pierre-Yves Chibon |
a86f36 |
continue
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
a86f36 |
messages.append(
|
|
Pierre-Yves Chibon |
a86f36 |
add_issue_dependency(
|
|
Pierre-Yves Chibon |
a86f36 |
session,
|
|
Pierre-Yves Chibon |
a86f36 |
issue=issue_depend,
|
|
Pierre-Yves Chibon |
a86f36 |
issue_blocked=issue,
|
|
Pierre-Yves Chibon |
a86f36 |
user=username,
|
|
Pierre-Yves Chibon |
a86f36 |
ticketfolder=ticketfolder,
|
|
Pierre-Yves Chibon |
a86f36 |
)
|
|
Pierre-Yves Chibon |
a86f36 |
)
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
a86f36 |
# Remove issue depending
|
|
Pierre-Yves Chibon |
a86f36 |
for depend in torm:
|
|
Pierre-Yves Chibon |
a86f36 |
issue_depend = search_issues(session, repo, issueid=depend)
|
|
Pierre-Yves Chibon |
0fae14 |
if issue_depend is None: # pragma: no cover
|
|
Pierre-Yves Chibon |
0fae14 |
# We cannot test this as it would mean we managed to put in an
|
|
Pierre-Yves Chibon |
0fae14 |
# invalid ticket as dependency earlier
|
|
Pierre-Yves Chibon |
a86f36 |
continue
|
|
Pierre-Yves Chibon |
2e498a |
if issue_depend.id not in issue.depends_text: # pragma: no cover
|
|
Pierre-Yves Chibon |
2e498a |
# we should never be in this case but better safe than sorry...
|
|
Pierre-Yves Chibon |
a86f36 |
continue
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
a86f36 |
messages.append(
|
|
Pierre-Yves Chibon |
a86f36 |
remove_issue_dependency(
|
|
Pierre-Yves Chibon |
a86f36 |
session,
|
|
Pierre-Yves Chibon |
a86f36 |
issue=issue,
|
|
Pierre-Yves Chibon |
a86f36 |
issue_blocked=issue_depend,
|
|
Pierre-Yves Chibon |
a86f36 |
user=username,
|
|
Pierre-Yves Chibon |
a86f36 |
ticketfolder=ticketfolder,
|
|
Pierre-Yves Chibon |
a86f36 |
)
|
|
Pierre-Yves Chibon |
a86f36 |
)
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
a86f36 |
session.commit()
|
|
Pierre-Yves Chibon |
a86f36 |
return messages
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
f49685 |
def update_blocked_issue(
|
|
Pierre-Yves Chibon |
2e464a |
session, repo, issue, blocks, username, ticketfolder):
|
|
Pierre-Yves Chibon |
a86f36 |
""" Update the upstream dependency of a specified issue (adding or
|
|
Pierre-Yves Chibon |
a86f36 |
removing them)
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
a86f36 |
"""
|
|
Pierre-Yves Chibon |
a86f36 |
if isinstance(blocks, basestring):
|
|
Pierre-Yves Chibon |
a86f36 |
blocks = [blocks]
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
a86f36 |
toadd = set(blocks) - set(issue.blocks_text)
|
|
Pierre-Yves Chibon |
a86f36 |
torm = set(issue.blocks_text) - set(blocks)
|
|
Pierre-Yves Chibon |
a86f36 |
messages = []
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
a86f36 |
# Add issue blocked
|
|
Pierre-Yves Chibon |
a86f36 |
for block in toadd:
|
|
Pierre-Yves Chibon |
a86f36 |
issue_block = search_issues(session, repo, issueid=block)
|
|
Pierre-Yves Chibon |
a24b70 |
if issue_block is None:
|
|
Pierre-Yves Chibon |
a86f36 |
continue
|
|
Pierre-Yves Chibon |
a24b70 |
if issue_block.id in issue.blocks_text: # pragma: no cover
|
|
Pierre-Yves Chibon |
a24b70 |
# we should never be in this case but better safe than sorry...
|
|
Pierre-Yves Chibon |
a86f36 |
continue
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
a86f36 |
messages.append(
|
|
Pierre-Yves Chibon |
a86f36 |
add_issue_dependency(
|
|
Pierre-Yves Chibon |
a86f36 |
session,
|
|
Pierre-Yves Chibon |
a86f36 |
issue=issue,
|
|
Pierre-Yves Chibon |
a86f36 |
issue_blocked=issue_block,
|
|
Pierre-Yves Chibon |
a86f36 |
user=username,
|
|
Pierre-Yves Chibon |
a86f36 |
ticketfolder=ticketfolder,
|
|
Pierre-Yves Chibon |
a86f36 |
)
|
|
Pierre-Yves Chibon |
a86f36 |
)
|
|
Pierre-Yves Chibon |
a86f36 |
session.commit()
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
a86f36 |
# Remove issue blocked
|
|
Pierre-Yves Chibon |
a86f36 |
for block in torm:
|
|
Pierre-Yves Chibon |
a86f36 |
issue_block = search_issues(session, repo, issueid=block)
|
|
Pierre-Yves Chibon |
a24b70 |
if issue_block is None: # pragma: no cover
|
|
Pierre-Yves Chibon |
a24b70 |
# We cannot test this as it would mean we managed to put in an
|
|
Pierre-Yves Chibon |
a24b70 |
# invalid ticket as dependency earlier
|
|
Pierre-Yves Chibon |
a86f36 |
continue
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
a24b70 |
if issue_block.id not in issue.blocks_text: # pragma: no cover
|
|
Pierre-Yves Chibon |
a24b70 |
# we should never be in this case but better safe than sorry...
|
|
Pierre-Yves Chibon |
a86f36 |
continue
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
a86f36 |
messages.append(
|
|
Pierre-Yves Chibon |
a86f36 |
remove_issue_dependency(
|
|
Pierre-Yves Chibon |
a86f36 |
session,
|
|
Pierre-Yves Chibon |
a86f36 |
issue=issue_block,
|
|
Pierre-Yves Chibon |
a86f36 |
issue_blocked=issue,
|
|
Pierre-Yves Chibon |
a86f36 |
user=username,
|
|
Pierre-Yves Chibon |
a86f36 |
ticketfolder=ticketfolder,
|
|
Pierre-Yves Chibon |
a86f36 |
)
|
|
Pierre-Yves Chibon |
a86f36 |
)
|
|
Pierre-Yves Chibon |
a86f36 |
|
|
Pierre-Yves Chibon |
a86f36 |
session.commit()
|
|
Pierre-Yves Chibon |
a86f36 |
return messages
|
|
Pierre-Yves Chibon |
4fd1f7 |
|
|
Pierre-Yves Chibon |
4fd1f7 |
|
|
Pierre-Yves Chibon |
4fd1f7 |
def add_user_pending_email(session, userobj, email):
|
|
Pierre-Yves Chibon |
4fd1f7 |
''' Add the provided user to the specified user.
|
|
Pierre-Yves Chibon |
4fd1f7 |
'''
|
|
Pierre-Yves Chibon |
4fd1f7 |
other_user = search_user(session, email=email)
|
|
Pierre-Yves Chibon |
4fd1f7 |
if other_user and other_user != userobj:
|
|
Pierre-Yves Chibon |
4fd1f7 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
4fd1f7 |
'Someone else has already registered this email'
|
|
Pierre-Yves Chibon |
4fd1f7 |
)
|
|
Pierre-Yves Chibon |
4fd1f7 |
|
|
Pierre-Yves Chibon |
2a3a0e |
pending_email = search_pending_email(session, email=email)
|
|
Pierre-Yves Chibon |
2a3a0e |
if pending_email:
|
|
Pierre-Yves Chibon |
2a3a0e |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
2a3a0e |
'This email is already pending confirmation'
|
|
Pierre-Yves Chibon |
2a3a0e |
)
|
|
Pierre-Yves Chibon |
2a3a0e |
|
|
Pierre-Yves Chibon |
4fd1f7 |
tmpemail = pagure.lib.model.UserEmailPending(
|
|
Pierre-Yves Chibon |
4fd1f7 |
user_id=userobj.id,
|
|
Pierre-Yves Chibon |
4fd1f7 |
token=pagure.lib.login.id_generator(40),
|
|
Pierre-Yves Chibon |
4fd1f7 |
email=email
|
|
Pierre-Yves Chibon |
4fd1f7 |
)
|
|
Pierre-Yves Chibon |
4fd1f7 |
session.add(tmpemail)
|
|
Pierre-Yves Chibon |
4fd1f7 |
session.flush()
|
|
Pierre-Yves Chibon |
4fd1f7 |
|
|
Pierre-Yves Chibon |
4fd1f7 |
pagure.lib.notify.notify_new_email(tmpemail, user=userobj)
|
|
Pierre-Yves Chibon |
ced619 |
|
|
Pierre-Yves Chibon |
ced619 |
|
|
Pierre-Yves Chibon |
8bd0a9 |
def resend_pending_email(session, userobj, email):
|
|
Pierre-Yves Chibon |
8bd0a9 |
''' Resend to the user the confirmation email for the provided email
|
|
Pierre-Yves Chibon |
8bd0a9 |
address.
|
|
Pierre-Yves Chibon |
8bd0a9 |
'''
|
|
Pierre-Yves Chibon |
8bd0a9 |
other_user = search_user(session, email=email)
|
|
Pierre-Yves Chibon |
8bd0a9 |
if other_user and other_user != userobj:
|
|
Pierre-Yves Chibon |
8bd0a9 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
323250 |
'Someone else has already registered this email address'
|
|
Pierre-Yves Chibon |
8bd0a9 |
)
|
|
Pierre-Yves Chibon |
8bd0a9 |
|
|
Pierre-Yves Chibon |
8bd0a9 |
pending_email = search_pending_email(session, email=email)
|
|
Pierre-Yves Chibon |
8bd0a9 |
if not pending_email:
|
|
Pierre-Yves Chibon |
8bd0a9 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
323250 |
'This email address has already been confirmed'
|
|
Pierre-Yves Chibon |
8bd0a9 |
)
|
|
Pierre-Yves Chibon |
8bd0a9 |
|
|
Pierre-Yves Chibon |
d1e053 |
pending_email.token = pagure.lib.login.id_generator(40)
|
|
Pierre-Yves Chibon |
8bd0a9 |
session.add(pending_email)
|
|
Pierre-Yves Chibon |
8bd0a9 |
session.flush()
|
|
Pierre-Yves Chibon |
8bd0a9 |
|
|
Pierre-Yves Chibon |
8bd0a9 |
pagure.lib.notify.notify_new_email(pending_email, user=userobj)
|
|
Pierre-Yves Chibon |
8bd0a9 |
|
|
Pierre-Yves Chibon |
8bd0a9 |
|
|
Pierre-Yves Chibon |
ced619 |
def search_pending_email(session, email=None, token=None):
|
|
Pierre-Yves Chibon |
ced619 |
''' Searches the database for the pending email matching the given
|
|
Pierre-Yves Chibon |
ced619 |
criterias.
|
|
Pierre-Yves Chibon |
ced619 |
|
|
Pierre-Yves Chibon |
ced619 |
:arg session: the session to use to connect to the database.
|
|
Pierre-Yves Chibon |
ced619 |
:kwarg email: the email to look for
|
|
Pierre-Yves Chibon |
ced619 |
:type email: string or None
|
|
Pierre-Yves Chibon |
ced619 |
:kwarg token: the token of the pending email to look for
|
|
Pierre-Yves Chibon |
ced619 |
:type token: string or None
|
|
Pierre-Yves Chibon |
ced619 |
:return: A single UserEmailPending object
|
|
Pierre-Yves Chibon |
ced619 |
:rtype: UserEmailPending
|
|
Pierre-Yves Chibon |
ced619 |
|
|
Pierre-Yves Chibon |
ced619 |
'''
|
|
Pierre-Yves Chibon |
ced619 |
query = session.query(
|
|
Pierre-Yves Chibon |
ced619 |
model.UserEmailPending
|
|
Pierre-Yves Chibon |
ced619 |
)
|
|
Pierre-Yves Chibon |
ced619 |
|
|
Pierre-Yves Chibon |
ced619 |
if email is not None:
|
|
Pierre-Yves Chibon |
ced619 |
query = query.filter(
|
|
Pierre-Yves Chibon |
ced619 |
model.UserEmailPending.email == email
|
|
Pierre-Yves Chibon |
ced619 |
)
|
|
Pierre-Yves Chibon |
ced619 |
|
|
Pierre-Yves Chibon |
ced619 |
if token is not None:
|
|
Pierre-Yves Chibon |
ced619 |
query = query.filter(
|
|
Pierre-Yves Chibon |
ced619 |
model.UserEmailPending.token == token
|
|
Pierre-Yves Chibon |
ced619 |
)
|
|
Pierre-Yves Chibon |
ced619 |
|
|
Pierre-Yves Chibon |
ced619 |
output = query.first()
|
|
Pierre-Yves Chibon |
ced619 |
|
|
Pierre-Yves Chibon |
ced619 |
return output
|
|
Pierre-Yves Chibon |
623f37 |
|
|
Pierre-Yves Chibon |
623f37 |
|
|
Pierre-Yves Chibon |
623f37 |
def generate_hook_token(session):
|
|
Pierre-Yves Chibon |
623f37 |
''' For each project in the database, re-generate a unique hook_token.
|
|
Pierre-Yves Chibon |
623f37 |
|
|
Pierre-Yves Chibon |
623f37 |
'''
|
|
Pierre-Yves Chibon |
623f37 |
|
|
Pierre-Yves Chibon |
623f37 |
for project in search_projects(session):
|
|
Pierre-Yves Chibon |
623f37 |
project.hook_token = pagure.lib.login.id_generator(40)
|
|
Pierre-Yves Chibon |
623f37 |
session.add(project)
|
|
Pierre-Yves Chibon |
623f37 |
session.commit()
|
|
Pierre-Yves Chibon |
56fa2a |
|
|
Pierre-Yves Chibon |
56fa2a |
|
|
Pierre-Yves Chibon |
c2a75b |
def get_group_types(session, group_type=None):
|
|
Pierre-Yves Chibon |
56fa2a |
''' Return the list of type a group can have.
|
|
Pierre-Yves Chibon |
56fa2a |
|
|
Pierre-Yves Chibon |
56fa2a |
'''
|
|
Pierre-Yves Chibon |
56fa2a |
query = session.query(
|
|
Pierre-Yves Chibon |
56fa2a |
model.PagureGroupType
|
|
Pierre-Yves Chibon |
56fa2a |
).order_by(
|
|
Pierre-Yves Chibon |
c2a75b |
model.PagureGroupType.group_type
|
|
Pierre-Yves Chibon |
56fa2a |
)
|
|
Pierre-Yves Chibon |
56fa2a |
|
|
Pierre-Yves Chibon |
c2a75b |
if group_type:
|
|
Pierre-Yves Chibon |
56fa2a |
query = query.filter(
|
|
Pierre-Yves Chibon |
c2a75b |
model.PagureGroupType.group_type == group_type
|
|
Pierre-Yves Chibon |
56fa2a |
)
|
|
Pierre-Yves Chibon |
56fa2a |
|
|
Pierre-Yves Chibon |
56fa2a |
return query.all()
|
|
Pierre-Yves Chibon |
89b639 |
|
|
Pierre-Yves Chibon |
89b639 |
|
|
Pierre-Yves Chibon |
c2a75b |
def search_groups(session, pattern=None, group_name=None, group_type=None):
|
|
Pierre-Yves Chibon |
89b639 |
''' Return the groups based on the criteria specified.
|
|
Pierre-Yves Chibon |
89b639 |
|
|
Pierre-Yves Chibon |
89b639 |
'''
|
|
Pierre-Yves Chibon |
89b639 |
query = session.query(
|
|
Pierre-Yves Chibon |
89b639 |
model.PagureGroup
|
|
Pierre-Yves Chibon |
89b639 |
).order_by(
|
|
Pierre-Yves Chibon |
c2a75b |
model.PagureGroup.group_type
|
|
Pierre-Yves Chibon |
89b639 |
)
|
|
Pierre-Yves Chibon |
89b639 |
|
|
Pierre-Yves Chibon |
89b639 |
if pattern:
|
|
Pierre-Yves Chibon |
89b639 |
pattern = pattern.replace('*', '%')
|
|
Pierre-Yves Chibon |
89b639 |
query = query.filter(
|
|
Pierre-Yves Chibon |
89b639 |
model.PagureGroup.group_name.like(pattern)
|
|
Pierre-Yves Chibon |
89b639 |
)
|
|
Pierre-Yves Chibon |
89b639 |
|
|
Pierre-Yves Chibon |
b4ec1c |
if group_name:
|
|
Pierre-Yves Chibon |
89b639 |
query = query.filter(
|
|
Pierre-Yves Chibon |
c2a75b |
model.PagureGroup.group_name == group_name
|
|
Pierre-Yves Chibon |
89b639 |
)
|
|
Pierre-Yves Chibon |
89b639 |
|
|
Pierre-Yves Chibon |
c2a75b |
if group_type:
|
|
Pierre-Yves Chibon |
89b639 |
query = query.filter(
|
|
Pierre-Yves Chibon |
c2a75b |
model.PagureGroup.group_type == group_type
|
|
Pierre-Yves Chibon |
89b639 |
)
|
|
Pierre-Yves Chibon |
89b639 |
|
|
Pierre-Yves Chibon |
c2a75b |
if group_name:
|
|
Pierre-Yves Chibon |
89b639 |
return query.first()
|
|
Pierre-Yves Chibon |
89b639 |
else:
|
|
Pierre-Yves Chibon |
89b639 |
return query.all()
|
|
Pierre-Yves Chibon |
739196 |
|
|
Pierre-Yves Chibon |
739196 |
|
|
Pierre-Yves Chibon |
bed068 |
def add_user_to_group(session, username, group, user, is_admin):
|
|
Pierre-Yves Chibon |
759c87 |
''' Add the specified user to the given group.
|
|
Pierre-Yves Chibon |
759c87 |
'''
|
|
Pierre-Yves Chibon |
82b9c8 |
new_user = search_user(session, username=username)
|
|
Pierre-Yves Chibon |
82b9c8 |
if not new_user:
|
|
Pierre-Yves Chibon |
bed068 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
bed068 |
'No user `%s` found' % username)
|
|
Pierre-Yves Chibon |
bed068 |
|
|
Pierre-Yves Chibon |
60ba7f |
action_user = user
|
|
Pierre-Yves Chibon |
bed068 |
user = search_user(session, username=user)
|
|
Pierre-Yves Chibon |
60ba7f |
if not user:
|
|
Pierre-Yves Chibon |
60ba7f |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
60ba7f |
'No user `%s` found' % action_user)
|
|
Pierre-Yves Chibon |
60ba7f |
|
|
Pierre-Yves Chibon |
2a7216 |
if group.group_name not in user.groups and not is_admin\
|
|
Pierre-Yves Chibon |
60ba7f |
and user.username != group.creator.username:
|
|
Pierre-Yves Chibon |
bed068 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
bed068 |
'You are not allowed to add user to this group')
|
|
Pierre-Yves Chibon |
82b9c8 |
|
|
Pierre-Yves Chibon |
759c87 |
for guser in group.users:
|
|
Pierre-Yves Chibon |
e660c6 |
if guser.username == new_user.username:
|
|
Pierre-Yves Chibon |
759c87 |
return 'User `%s` already in the group, nothing to change.' % (
|
|
Pierre-Yves Chibon |
e660c6 |
new_user.username)
|
|
Pierre-Yves Chibon |
759c87 |
|
|
Pierre-Yves Chibon |
759c87 |
grp = model.PagureUserGroup(
|
|
Pierre-Yves Chibon |
759c87 |
group_id=group.id,
|
|
Pierre-Yves Chibon |
e660c6 |
user_id=new_user.id
|
|
Pierre-Yves Chibon |
759c87 |
)
|
|
Pierre-Yves Chibon |
759c87 |
session.add(grp)
|
|
Pierre-Yves Chibon |
759c87 |
session.flush()
|
|
Pierre-Yves Chibon |
60ba7f |
return 'User `%s` added to the group `%s`.' % (
|
|
Pierre-Yves Chibon |
60ba7f |
new_user.username, group.group_name)
|
|
Pierre-Yves Chibon |
759c87 |
|
|
Pierre-Yves Chibon |
759c87 |
|
|
Pierre-Yves Chibon |
42452c |
def edit_group_info(
|
|
Pierre-Yves Chibon |
42452c |
session, group, display_name, description, user, is_admin):
|
|
Pierre-Yves Chibon |
42452c |
''' Edit the information regarding a given group.
|
|
Pierre-Yves Chibon |
42452c |
'''
|
|
Pierre-Yves Chibon |
42452c |
action_user = user
|
|
Pierre-Yves Chibon |
42452c |
user = search_user(session, username=user)
|
|
Pierre-Yves Chibon |
42452c |
if not user:
|
|
Pierre-Yves Chibon |
42452c |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
42452c |
'No user `%s` found' % action_user)
|
|
Pierre-Yves Chibon |
42452c |
|
|
Pierre-Yves Chibon |
42452c |
if group.group_name not in user.groups \
|
|
Pierre-Yves Chibon |
42452c |
and not is_admin \
|
|
Pierre-Yves Chibon |
42452c |
and user.username != group.creator.username:
|
|
Pierre-Yves Chibon |
42452c |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
42452c |
'You are not allowed to edit this group')
|
|
Pierre-Yves Chibon |
42452c |
|
|
Pierre-Yves Chibon |
42452c |
edits = []
|
|
Pierre-Yves Chibon |
42452c |
if display_name and display_name != group.display_name:
|
|
Pierre-Yves Chibon |
42452c |
group.display_name = display_name
|
|
Pierre-Yves Chibon |
42452c |
edits.append('display_name')
|
|
Pierre-Yves Chibon |
42452c |
if description and description != group.description:
|
|
Pierre-Yves Chibon |
42452c |
group.description = description
|
|
Pierre-Yves Chibon |
42452c |
edits.append('description')
|
|
Pierre-Yves Chibon |
42452c |
|
|
Pierre-Yves Chibon |
42452c |
session.add(group)
|
|
Pierre-Yves Chibon |
42452c |
session.flush()
|
|
Pierre-Yves Chibon |
42452c |
|
|
Pierre-Yves Chibon |
42452c |
msg = 'Nothing changed'
|
|
Pierre-Yves Chibon |
42452c |
if edits:
|
|
Pierre-Yves Chibon |
42452c |
pagure.lib.notify.log(
|
|
Pierre-Yves Chibon |
42452c |
None,
|
|
Pierre-Yves Chibon |
42452c |
topic='group.edit',
|
|
Pierre-Yves Chibon |
42452c |
msg=dict(
|
|
Pierre-Yves Chibon |
42452c |
group=group.to_json(public=True),
|
|
Pierre-Yves Chibon |
42452c |
fields=edits,
|
|
Pierre-Yves Chibon |
42452c |
agent=user.username,
|
|
Pierre-Yves Chibon |
42452c |
),
|
|
Pierre-Yves Chibon |
42452c |
redis=REDIS,
|
|
Pierre-Yves Chibon |
42452c |
)
|
|
Pierre-Yves Chibon |
42452c |
msg = 'Group "%s" (%s) edited' % (
|
|
Pierre-Yves Chibon |
42452c |
group.display_name, group.group_name)
|
|
Pierre-Yves Chibon |
42452c |
|
|
Pierre-Yves Chibon |
42452c |
return msg
|
|
Pierre-Yves Chibon |
42452c |
|
|
Pierre-Yves Chibon |
42452c |
|
|
Pierre-Yves Chibon |
d7b5a0 |
def delete_user_of_group(session, username, groupname, user, is_admin,
|
|
Pierre-Yves Chibon |
d7b5a0 |
force=False):
|
|
Pierre-Yves Chibon |
bed068 |
''' Removes the specified user from the given group.
|
|
Pierre-Yves Chibon |
bed068 |
'''
|
|
Pierre-Yves Chibon |
bed068 |
group_obj = search_groups(session, group_name=groupname)
|
|
Pierre-Yves Chibon |
bed068 |
|
|
Pierre-Yves Chibon |
bed068 |
if not group_obj:
|
|
Pierre-Yves Chibon |
bed068 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
bed068 |
'No group `%s` found' % groupname)
|
|
Pierre-Yves Chibon |
bed068 |
|
|
Pierre-Yves Chibon |
bed068 |
drop_user = search_user(session, username=username)
|
|
Pierre-Yves Chibon |
bed068 |
if not drop_user:
|
|
Pierre-Yves Chibon |
bed068 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
bed068 |
'No user `%s` found' % username)
|
|
Pierre-Yves Chibon |
bed068 |
|
|
Pierre-Yves Chibon |
7780e4 |
action_user = user
|
|
Pierre-Yves Chibon |
bed068 |
user = search_user(session, username=user)
|
|
Pierre-Yves Chibon |
7780e4 |
if not user:
|
|
Pierre-Yves Chibon |
7780e4 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
7780e4 |
'Could not find user %s' % action_user)
|
|
Pierre-Yves Chibon |
7780e4 |
|
|
Pierre-Yves Chibon |
2a7216 |
if group_obj.group_name not in user.groups and not is_admin:
|
|
Pierre-Yves Chibon |
bed068 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
bed068 |
'You are not allowed to remove user from this group')
|
|
Pierre-Yves Chibon |
bed068 |
|
|
Pierre-Yves Chibon |
d7b5a0 |
if drop_user.username == group_obj.creator.username and not force:
|
|
Pierre-Yves Chibon |
bed068 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
bed068 |
'The creator of a group cannot be removed')
|
|
Pierre-Yves Chibon |
bed068 |
|
|
Pierre-Yves Chibon |
bed068 |
user_grp = get_user_group(session, drop_user.id, group_obj.id)
|
|
Pierre-Yves Chibon |
7780e4 |
if not user_grp:
|
|
Pierre-Yves Chibon |
7780e4 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
7780e4 |
'User `%s` could not be found in the group `%s`' % (
|
|
Pierre-Yves Chibon |
2a7216 |
username, groupname))
|
|
Pierre-Yves Chibon |
7780e4 |
|
|
Pierre-Yves Chibon |
bed068 |
session.delete(user_grp)
|
|
Pierre-Yves Chibon |
bed068 |
session.flush()
|
|
Pierre-Yves Chibon |
bed068 |
|
|
Pierre-Yves Chibon |
bed068 |
|
|
Pierre-Yves Chibon |
4451bc |
def add_group(
|
|
Pierre-Yves Chibon |
4451bc |
session, group_name, display_name, description,
|
|
Pierre-Yves Chibon |
4451bc |
group_type, user, is_admin, blacklist):
|
|
Pierre-Yves Chibon |
bed068 |
''' Creates a new group with the given information.
|
|
Pierre-Yves Chibon |
bed068 |
'''
|
|
Pierre-Yves Chibon |
250931 |
if ' ' in group_name:
|
|
Pierre-Yves Chibon |
250931 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
250931 |
'Spaces are not allowed in group names: %s' % group_name)
|
|
Pierre-Yves Chibon |
bed068 |
|
|
Pierre-Yves Chibon |
ca10fd |
if group_name in blacklist:
|
|
Pierre-Yves Chibon |
ca10fd |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
165c3e |
'This group name has been blacklisted, '
|
|
Pierre-Yves Chibon |
165c3e |
'please choose another one')
|
|
Pierre-Yves Chibon |
ca10fd |
|
|
Pierre-Yves Chibon |
bed068 |
group_types = ['user']
|
|
Pierre-Yves Chibon |
bed068 |
if is_admin:
|
|
Pierre-Yves Chibon |
bed068 |
group_types = [
|
|
Pierre-Yves Chibon |
bed068 |
grp.group_type
|
|
Pierre-Yves Chibon |
bed068 |
for grp in get_group_types(session)
|
|
Pierre-Yves Chibon |
bed068 |
]
|
|
Pierre-Yves Chibon |
bed068 |
|
|
Pierre-Yves Chibon |
bed068 |
if not is_admin:
|
|
Pierre-Yves Chibon |
bed068 |
group_type = 'user'
|
|
Pierre-Yves Chibon |
bed068 |
|
|
Pierre-Yves Chibon |
bed068 |
if group_type not in group_types:
|
|
Pierre-Yves Chibon |
bed068 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
bed068 |
'Invalide type for this group')
|
|
Pierre-Yves Chibon |
bed068 |
|
|
Pierre-Yves Chibon |
e509f7 |
username = user
|
|
Pierre-Yves Chibon |
bed068 |
user = search_user(session, username=user)
|
|
Pierre-Yves Chibon |
e509f7 |
if not user:
|
|
Pierre-Yves Chibon |
e509f7 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
e509f7 |
'Could not find user %s' % username)
|
|
Pierre-Yves Chibon |
bed068 |
|
|
Pierre-Yves Chibon |
84ac61 |
group = search_groups(session, group_name=group_name)
|
|
Pierre-Yves Chibon |
84ac61 |
if group:
|
|
Pierre-Yves Chibon |
84ac61 |
raise pagure.exceptions.PagureException(
|
|
Pierre-Yves Chibon |
84ac61 |
'There is already a group named %s' % group_name)
|
|
Pierre-Yves Chibon |
84ac61 |
|
|
Pierre-Yves Chibon |
bed068 |
grp = pagure.lib.model.PagureGroup(
|
|
Pierre-Yves Chibon |
bed068 |
group_name=group_name,
|
|
Pierre-Yves Chibon |
4451bc |
display_name=display_name,
|
|
Pierre-Yves Chibon |
4451bc |
description=description,
|
|
Pierre-Yves Chibon |
bed068 |
group_type=group_type,
|
|
Pierre-Yves Chibon |
bed068 |
user_id=user.id,
|
|
Pierre-Yves Chibon |
bed068 |
)
|
|
Pierre-Yves Chibon |
e509f7 |
session.add(grp)
|
|
Pierre-Yves Chibon |
e509f7 |
session.flush()
|
|
Pierre-Yves Chibon |
bed068 |
|
|
Pierre-Yves Chibon |
e509f7 |
return add_user_to_group(
|
|
Pierre-Yves Chibon |
e509f7 |
session, user.username, grp, user.username, is_admin)
|
|
Pierre-Yves Chibon |
bed068 |
|
|
Pierre-Yves Chibon |
bed068 |
|
|
Pierre-Yves Chibon |
739196 |
def get_user_group(session, userid, groupid):
|
|
Pierre-Yves Chibon |
739196 |
''' Return a specific user_group for the specified group and user
|
|
Pierre-Yves Chibon |
739196 |
identifiers.
|
|
Pierre-Yves Chibon |
739196 |
|
|
Pierre-Yves Chibon |
739196 |
:arg session: the session with which to connect to the database.
|
|
Pierre-Yves Chibon |
739196 |
|
|
Pierre-Yves Chibon |
739196 |
'''
|
|
Pierre-Yves Chibon |
739196 |
query = session.query(
|
|
Pierre-Yves Chibon |
739196 |
model.PagureUserGroup
|
|
Pierre-Yves Chibon |
739196 |
).filter(
|
|
Pierre-Yves Chibon |
739196 |
model.PagureUserGroup.user_id == userid
|
|
Pierre-Yves Chibon |
739196 |
).filter(
|
|
Pierre-Yves Chibon |
739196 |
model.PagureUserGroup.group_id == groupid
|
|
Pierre-Yves Chibon |
739196 |
)
|
|
Pierre-Yves Chibon |
739196 |
|
|
Pierre-Yves Chibon |
739196 |
return query.first()
|
|
Pierre-Yves Chibon |
ade106 |
|
|
Pierre-Yves Chibon |
ade106 |
|
|
Pierre-Yves Chibon |
ade106 |
def is_group_member(session, user, groupname):
|
|
Pierre-Yves Chibon |
ade106 |
""" Return whether the user is a member of the specified group. """
|
|
Pierre-Yves Chibon |
ade106 |
if not user:
|
|
Pierre-Yves Chibon |
ade106 |
return False
|
|
Pierre-Yves Chibon |
ade106 |
|
|
Pierre-Yves Chibon |
ade106 |
user = search_user(session, username=user)
|
|
Pierre-Yves Chibon |
ade106 |
if not user:
|
|
Pierre-Yves Chibon |
ade106 |
return False
|
|
Pierre-Yves Chibon |
ade106 |
|
|
Pierre-Yves Chibon |
ade106 |
return groupname in user.groups
|
|
Pierre-Yves Chibon |
6e345c |
|
|
Pierre-Yves Chibon |
6e345c |
|
|
Pierre-Yves Chibon |
6e345c |
def get_api_token(session, token_str):
|
|
Pierre-Yves Chibon |
6e345c |
""" Return the Token object corresponding to the provided token string
|
|
Pierre-Yves Chibon |
6e345c |
if there is any, returns None otherwise.
|
|
Pierre-Yves Chibon |
6e345c |
"""
|
|
Pierre-Yves Chibon |
6e345c |
query = session.query(
|
|
Pierre-Yves Chibon |
6e345c |
model.Token
|
|
Pierre-Yves Chibon |
6e345c |
).filter(
|
|
Pierre-Yves Chibon |
6e345c |
model.Token.id == token_str
|
|
Pierre-Yves Chibon |
6e345c |
)
|
|
Pierre-Yves Chibon |
6e345c |
|
|
Pierre-Yves Chibon |
6e345c |
return query.first()
|
|
Pierre-Yves Chibon |
112bd1 |
|
|
Pierre-Yves Chibon |
112bd1 |
|
|
Pierre-Yves Chibon |
112bd1 |
def get_acls(session):
|
|
Pierre-Yves Chibon |
112bd1 |
""" Returns all the possible ACLs a token can have according to the
|
|
Pierre-Yves Chibon |
112bd1 |
database.
|
|
Pierre-Yves Chibon |
112bd1 |
"""
|
|
Pierre-Yves Chibon |
112bd1 |
query = session.query(
|
|
Pierre-Yves Chibon |
112bd1 |
model.ACL
|
|
Pierre-Yves Chibon |
112bd1 |
).order_by(
|
|
Pierre-Yves Chibon |
112bd1 |
model.ACL.name
|
|
Pierre-Yves Chibon |
112bd1 |
)
|
|
Pierre-Yves Chibon |
112bd1 |
|
|
Pierre-Yves Chibon |
112bd1 |
return query.all()
|
|
Pierre-Yves Chibon |
0b80a3 |
|
|
Pierre-Yves Chibon |
0b80a3 |
|
|
Pierre-Yves Chibon |
0b80a3 |
def add_token_to_user(session, project, acls, username):
|
|
Pierre-Yves Chibon |
0b80a3 |
""" Create a new token for the specified user on the specified project
|
|
Pierre-Yves Chibon |
0b80a3 |
with the given ACLs.
|
|
Pierre-Yves Chibon |
0b80a3 |
"""
|
|
Pierre-Yves Chibon |
0b80a3 |
acls_obj = session.query(
|
|
Pierre-Yves Chibon |
0b80a3 |
model.ACL
|
|
Pierre-Yves Chibon |
0b80a3 |
).filter(
|
|
Pierre-Yves Chibon |
0b80a3 |
model.ACL.name.in_(acls)
|
|
Pierre-Yves Chibon |
0b80a3 |
).all()
|
|
Pierre-Yves Chibon |
0b80a3 |
|
|
Pierre-Yves Chibon |
0b80a3 |
user = search_user(session, username=username)
|
|
Pierre-Yves Chibon |
0b80a3 |
|
|
Pierre-Yves Chibon |
0b80a3 |
token = pagure.lib.model.Token(
|
|
Pierre-Yves Chibon |
0b80a3 |
id=pagure.lib.login.id_generator(64),
|
|
Pierre-Yves Chibon |
0b80a3 |
user_id=user.id,
|
|
Pierre-Yves Chibon |
0b80a3 |
project_id=project.id,
|
|
Pierre-Yves Chibon |
0b80a3 |
expiration=datetime.datetime.utcnow() + datetime.timedelta(days=60)
|
|
Pierre-Yves Chibon |
0b80a3 |
)
|
|
Pierre-Yves Chibon |
0b80a3 |
session.add(token)
|
|
Pierre-Yves Chibon |
0b80a3 |
session.flush()
|
|
Pierre-Yves Chibon |
0b80a3 |
|
|
Pierre-Yves Chibon |
0b80a3 |
for acl in acls_obj:
|
|
Pierre-Yves Chibon |
0b80a3 |
item = pagure.lib.model.TokenAcl(
|
|
Pierre-Yves Chibon |
0b80a3 |
token_id=token.id,
|
|
Pierre-Yves Chibon |
0b80a3 |
acl_id=acl.id,
|
|
Pierre-Yves Chibon |
0b80a3 |
)
|
|
Pierre-Yves Chibon |
0b80a3 |
session.add(item)
|
|
Pierre-Yves Chibon |
0b80a3 |
|
|
Pierre-Yves Chibon |
0b80a3 |
session.commit()
|
|
Pierre-Yves Chibon |
0b80a3 |
|
|
Pierre-Yves Chibon |
0b80a3 |
return 'Token created'
|
|
Pierre-Yves Chibon |
2d9881 |
|
|
Pierre-Yves Chibon |
300559 |
|
|
Pierre-Yves Chibon |
814bc8 |
def text2markdown(text, extended=True):
|
|
Pierre-Yves Chibon |
2d9881 |
""" Simple text to html converter using the markdown library.
|
|
Pierre-Yves Chibon |
2d9881 |
"""
|
|
Pierre-Yves Chibon |
f9f132 |
md_processor = markdown.Markdown(safe_mode="escape")
|
|
Pierre-Yves Chibon |
814bc8 |
if extended:
|
|
Pierre-Yves Chibon |
814bc8 |
# Install our markdown modifications
|
|
Pierre-Yves Chibon |
f9f132 |
md_processor = markdown.Markdown(extensions=['pagure.pfmarkdown'])
|
|
Pierre-Yves Chibon |
814bc8 |
|
|
Pierre-Yves Chibon |
2d9881 |
if text:
|
|
Pierre-Yves Chibon |
2d9881 |
# Hack to allow blockquotes to be marked by ~~~
|
|
Pierre-Yves Chibon |
2d9881 |
ntext = []
|
|
Pierre-Yves Chibon |
2d9881 |
indent = False
|
|
Pierre-Yves Chibon |
2d9881 |
for line in text.split('\n'):
|
|
Pierre-Yves Chibon |
2d9881 |
if line.startswith('~~~'):
|
|
Pierre-Yves Chibon |
2d9881 |
indent = not indent
|
|
Pierre-Yves Chibon |
2d9881 |
continue
|
|
Pierre-Yves Chibon |
2d9881 |
if indent:
|
|
Pierre-Yves Chibon |
2d9881 |
line = ' %s' % line
|
|
Pierre-Yves Chibon |
2d9881 |
ntext.append(line)
|
|
Pierre-Yves Chibon |
f9f132 |
return clean_input(md_processor.convert('\n'.join(ntext)))
|
|
Pierre-Yves Chibon |
2d9881 |
|
|
Pierre-Yves Chibon |
2d9881 |
return ''
|
|
Pierre-Yves Chibon |
3916b5 |
|
|
Pierre-Yves Chibon |
300559 |
|
|
Pierre-Yves Chibon |
300559 |
def filter_img_src(name, value):
|
|
Pierre-Yves Chibon |
300559 |
''' Filter in img html tags images coming from a different domain. '''
|
|
Pierre-Yves Chibon |
300559 |
if name in ('alt', 'height', 'width', 'class'):
|
|
Pierre-Yves Chibon |
300559 |
return True
|
|
Pierre-Yves Chibon |
300559 |
if name == 'src':
|
|
Pierre-Yves Chibon |
f9f132 |
parsed = urlparse.urlparse(value)
|
|
Pierre-Yves Chibon |
f9f132 |
return (not parsed.netloc) or parsed.netloc == urlparse.urlparse(
|
|
Pierre-Yves Chibon |
88a560 |
pagure.APP.config['APP_URL']).netloc
|
|
Pierre-Yves Chibon |
300559 |
return False
|
|
Pierre-Yves Chibon |
300559 |
|
|
Pierre-Yves Chibon |
300559 |
|
|
Pierre-Yves Chibon |
faecff |
def clean_input(text, ignore=None):
|
|
Pierre-Yves Chibon |
3916b5 |
""" For a given html text, escape everything we do not want to support
|
|
Pierre-Yves Chibon |
3916b5 |
to avoid potential security breach.
|
|
Pierre-Yves Chibon |
3916b5 |
"""
|
|
Pierre-Yves Chibon |
faecff |
if ignore and not isinstance(ignore, (tuple, set, list)):
|
|
Pierre-Yves Chibon |
faecff |
ignore = [ignore]
|
|
Pierre-Yves Chibon |
faecff |
|
|
Pierre-Yves Chibon |
3916b5 |
attrs = bleach.ALLOWED_ATTRIBUTES
|
|
Pierre-Yves Chibon |
b60425 |
if not ignore or not 'img' in ignore:
|
|
Pierre-Yves Chibon |
faecff |
attrs['img'] = filter_img_src
|
|
Pierre-Yves Chibon |
faecff |
|
|
Pierre-Yves Chibon |
faecff |
tags = bleach.ALLOWED_TAGS + [
|
|
Pierre-Yves Chibon |
24584d |
'p', 'br', 'div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
|
|
Pierre-Yves Chibon |
24584d |
'table', 'td', 'tr', 'th',
|
|
Pierre-Yves Chibon |
a4a4c1 |
'col', 'tbody', 'pre', 'img', 'hr', 'dl', 'dt', 'dd', 'span',
|
|
Clement Verna |
506ac6 |
'kbd', 'var', 'del',
|
|
Pierre-Yves Chibon |
faecff |
]
|
|
Pierre-Yves Chibon |
faecff |
if ignore:
|
|
Pierre-Yves Chibon |
c52651 |
for tag in ignore:
|
|
Pierre-Yves Chibon |
c52651 |
if tag in tags:
|
|
Pierre-Yves Chibon |
c52651 |
tags.remove(tag)
|
|
Pierre-Yves Chibon |
faecff |
|
|
Pierre-Yves Chibon |
faecff |
return bleach.clean(text, tags=tags, attributes=attrs)
|
|
Pierre-Yves Chibon |
cf88d8 |
|
|
Pierre-Yves Chibon |
cf88d8 |
|
|
Pierre-Yves Chibon |
eae5cc |
def could_be_text(text):
|
|
Pierre-Yves Chibon |
eae5cc |
""" Returns wether we think this chain of character could be text or not
|
|
Pierre-Yves Chibon |
cf88d8 |
"""
|
|
Pierre-Yves Chibon |
fe765e |
try:
|
|
Pierre-Yves Chibon |
b0235c |
text.decode('utf-8')
|
|
Pierre-Yves Chibon |
97c77d |
return True
|
|
Pierre-Yves Chibon |
7f81da |
except:
|
|
Pierre-Yves Chibon |
7f81da |
return False
|
|
Pierre-Yves Chibon |
573e63 |
|
|
Pierre-Yves Chibon |
573e63 |
|
|
Pierre-Yves Chibon |
573e63 |
def get_pull_request_of_user(session, username):
|
|
Pierre-Yves Chibon |
573e63 |
'''List the opened pull-requests of an user.
|
|
Pierre-Yves Chibon |
573e63 |
These pull-requests have either been opened by that user or against
|
|
Pierre-Yves Chibon |
573e63 |
projects that user has commit on.
|
|
Pierre-Yves Chibon |
573e63 |
'''
|
|
Pierre-Yves Chibon |
573e63 |
projects = session.query(
|
|
Pierre-Yves Chibon |
573e63 |
sqlalchemy.distinct(model.Project.id)
|
|
Pierre-Yves Chibon |
573e63 |
)
|
|
Pierre-Yves Chibon |
573e63 |
|
|
Pierre-Yves Chibon |
573e63 |
projects = projects.filter(
|
|
Pierre-Yves Chibon |
573e63 |
# User created the project
|
|
Pierre-Yves Chibon |
573e63 |
sqlalchemy.and_(
|
|
Pierre-Yves Chibon |
573e63 |
model.User.user == username,
|
|
Pierre-Yves Chibon |
573e63 |
model.User.id == model.Project.user_id,
|
|
Pierre-Yves Chibon |
573e63 |
)
|
|
Pierre-Yves Chibon |
573e63 |
)
|
|
Pierre-Yves Chibon |
f9f132 |
sub_q2 = session.query(
|
|
Pierre-Yves Chibon |
573e63 |
model.Project.id
|
|
Pierre-Yves Chibon |
573e63 |
).filter(
|
|
Pierre-Yves Chibon |
573e63 |
# User got commit right
|
|
Pierre-Yves Chibon |
573e63 |
sqlalchemy.and_(
|
|
Pierre-Yves Chibon |
573e63 |
model.User.user == username,
|
|
Pierre-Yves Chibon |
573e63 |
model.User.id == model.ProjectUser.user_id,
|
|
Pierre-Yves Chibon |
573e63 |
model.ProjectUser.project_id == model.Project.id
|
|
Pierre-Yves Chibon |
573e63 |
)
|
|
Pierre-Yves Chibon |
573e63 |
)
|
|
Pierre-Yves Chibon |
f9f132 |
sub_q3 = session.query(
|
|
Pierre-Yves Chibon |
573e63 |
model.Project.id
|
|
Pierre-Yves Chibon |
573e63 |
).filter(
|
|
Pierre-Yves Chibon |
573e63 |
# User created a group that has commit right
|
|
Pierre-Yves Chibon |
573e63 |
sqlalchemy.and_(
|
|
Pierre-Yves Chibon |
573e63 |
model.User.user == username,
|
|
Pierre-Yves Chibon |
573e63 |
model.PagureGroup.user_id == model.User.id,
|
|
Pierre-Yves Chibon |
573e63 |
model.PagureGroup.group_type == 'user',
|
|
Pierre-Yves Chibon |
573e63 |
model.PagureGroup.id == model.ProjectGroup.group_id,
|
|
Pierre-Yves Chibon |
573e63 |
model.Project.id == model.ProjectGroup.project_id,
|
|
Pierre-Yves Chibon |
573e63 |
)
|
|
Pierre-Yves Chibon |
573e63 |
)
|
|
Pierre-Yves Chibon |
f9f132 |
sub_q4 = session.query(
|
|
Pierre-Yves Chibon |
573e63 |
model.Project.id
|
|
Pierre-Yves Chibon |
573e63 |
).filter(
|
|
Pierre-Yves Chibon |
573e63 |
# User is part of a group that has commit right
|
|
Pierre-Yves Chibon |
573e63 |
sqlalchemy.and_(
|
|
Pierre-Yves Chibon |
573e63 |
model.User.user == username,
|
|
Pierre-Yves Chibon |
573e63 |
model.PagureUserGroup.user_id == model.User.id,
|
|
Pierre-Yves Chibon |
573e63 |
model.PagureUserGroup.group_id == model.PagureGroup.id,
|
|
Pierre-Yves Chibon |
573e63 |
model.PagureGroup.group_type == 'user',
|
|
Pierre-Yves Chibon |
573e63 |
model.PagureGroup.id == model.ProjectGroup.group_id,
|
|
Pierre-Yves Chibon |
573e63 |
model.Project.id == model.ProjectGroup.project_id,
|
|
Pierre-Yves Chibon |
573e63 |
)
|
|
Pierre-Yves Chibon |
573e63 |
)
|
|
Pierre-Yves Chibon |
573e63 |
|
|
Pierre-Yves Chibon |
f9f132 |
projects = projects.union(sub_q2).union(sub_q3).union(sub_q4)
|
|
Pierre-Yves Chibon |
573e63 |
|
|
Pierre-Yves Chibon |
573e63 |
query = session.query(
|
|
Pierre-Yves Chibon |
573e63 |
model.PullRequest
|
|
Pierre-Yves Chibon |
573e63 |
).filter(
|
|
Pierre-Yves Chibon |
573e63 |
model.PullRequest.project_id.in_(projects.subquery())
|
|
Pierre-Yves Chibon |
573e63 |
).order_by(
|
|
Pierre-Yves Chibon |
573e63 |
model.PullRequest.date_created.desc()
|
|
Pierre-Yves Chibon |
573e63 |
)
|
|
Pierre-Yves Chibon |
573e63 |
|
|
Pierre-Yves Chibon |
573e63 |
return query.all()
|
|
Gaurav Kumar |
00f2c8 |
|
|
Pierre-Yves Chibon |
b13b92 |
|
|
Gaurav Kumar |
00f2c8 |
def update_watch_status(session, project, user, watch):
|
|
Gaurav Kumar |
00f2c8 |
''' Update the user status for watching a project.
|
|
Gaurav Kumar |
00f2c8 |
'''
|
|
Pierre-Yves Chibon |
6aa385 |
user_obj = get_user(session, user)
|
|
Gaurav Kumar |
00f2c8 |
|
|
Gaurav Kumar |
00f2c8 |
if not user_obj:
|
|
Gaurav Kumar |
00f2c8 |
raise pagure.exceptions.PagureException(
|
|
Gaurav Kumar |
00f2c8 |
'No user with username: %s' % user)
|
|
Gaurav Kumar |
00f2c8 |
|
|
Gaurav Kumar |
00f2c8 |
watcher = session.query(
|
|
Gaurav Kumar |
00f2c8 |
model.Watcher
|
|
Gaurav Kumar |
00f2c8 |
).filter(
|
|
Gaurav Kumar |
00f2c8 |
sqlalchemy.and_(
|
|
Gaurav Kumar |
00f2c8 |
model.Watcher.project_id == project.id,
|
|
Gaurav Kumar |
00f2c8 |
model.Watcher.user_id == user_obj.id,
|
|
Gaurav Kumar |
00f2c8 |
)
|
|
Gaurav Kumar |
00f2c8 |
).first()
|
|
Gaurav Kumar |
00f2c8 |
|
|
Gaurav Kumar |
00f2c8 |
if not watcher:
|
|
Gaurav Kumar |
00f2c8 |
watcher = model.Watcher(
|
|
Gaurav Kumar |
00f2c8 |
project_id=project.id,
|
|
Gaurav Kumar |
00f2c8 |
user_id=user_obj.id,
|
|
Gaurav Kumar |
00f2c8 |
watch=watch
|
|
Gaurav Kumar |
00f2c8 |
)
|
|
Gaurav Kumar |
00f2c8 |
else:
|
|
Gaurav Kumar |
00f2c8 |
watcher.watch = watch
|
|
Gaurav Kumar |
00f2c8 |
|
|
Gaurav Kumar |
00f2c8 |
session.add(watcher)
|
|
Gaurav Kumar |
00f2c8 |
session.flush()
|
|
Gaurav Kumar |
00f2c8 |
|
|
Gaurav Kumar |
6cf178 |
msg_success = 'You are now watching this repo.'
|
|
Gaurav Kumar |
00f2c8 |
if not int(watch):
|
|
Gaurav Kumar |
00f2c8 |
msg_success = 'You are no longer watching this repo.'
|
|
Gaurav Kumar |
00f2c8 |
return msg_success
|
|
Gaurav Kumar |
604af6 |
|
|
Pierre-Yves Chibon |
784502 |
|
|
Pierre-Yves Chibon |
3b50fe |
def is_watching(session, user, reponame, repouser=None, namespace=None):
|
|
Gaurav Kumar |
604af6 |
''' Check user watching the project. '''
|
|
Gaurav Kumar |
604af6 |
|
|
Gaurav Kumar |
4e29d1 |
if user is None:
|
|
Gaurav Kumar |
4e29d1 |
return False
|
|
Gaurav Kumar |
4e29d1 |
|
|
Pierre-Yves Chibon |
784502 |
user_obj = search_user(session, username=user.username)
|
|
Gaurav Kumar |
604af6 |
if not user_obj:
|
|
Pierre-Yves Chibon |
784502 |
return False
|
|
Gaurav Kumar |
604af6 |
|
|
Pierre-Yves Chibon |
c8160d |
query = session.query(
|
|
Gaurav Kumar |
604af6 |
model.Watcher
|
|
Gaurav Kumar |
604af6 |
).filter(
|
|
Pierre-Yves Chibon |
c8160d |
model.Watcher.user_id == user_obj.id
|
|
Pierre-Yves Chibon |
c8160d |
).filter(
|
|
Pierre-Yves Chibon |
c8160d |
model.Watcher.project_id == model.Project.id
|
|
Pierre-Yves Chibon |
c8160d |
).filter(
|
|
Pierre-Yves Chibon |
c8160d |
model.Project.name == reponame
|
|
Pierre-Yves Chibon |
c8160d |
)
|
|
Pierre-Yves Chibon |
c8160d |
|
|
Pierre-Yves Chibon |
c8160d |
if repouser is not None:
|
|
Pierre-Yves Chibon |
c8160d |
query = query.filter(
|
|
Pierre-Yves Chibon |
c8160d |
model.User.user == repouser
|
|
Pierre-Yves Chibon |
c8160d |
).filter(
|
|
Pierre-Yves Chibon |
c8160d |
model.User.id == model.Project.user_id
|
|
Pierre-Yves Chibon |
c8160d |
).filter(
|
|
farhaanbukhsh |
3e1439 |
model.Project.is_fork == True
|
|
Gaurav Kumar |
604af6 |
)
|
|
Pierre-Yves Chibon |
c8160d |
else:
|
|
Pierre-Yves Chibon |
c8160d |
query = query.filter(
|
|
farhaanbukhsh |
3e1439 |
model.Project.is_fork == False
|
|
Pierre-Yves Chibon |
c8160d |
)
|
|
Pierre-Yves Chibon |
c8160d |
|
|
Pierre-Yves Chibon |
3b50fe |
if namespace is not None:
|
|
Pierre-Yves Chibon |
3b50fe |
query = query.filter(
|
|
Pierre-Yves Chibon |
3b50fe |
model.Project.namespace == namespace
|
|
Pierre-Yves Chibon |
3b50fe |
)
|
|
Pierre-Yves Chibon |
3b50fe |
|
|
Pierre-Yves Chibon |
c8160d |
watcher = query.first()
|
|
Gaurav Kumar |
604af6 |
|
|
Gaurav Kumar |
604af6 |
if watcher:
|
|
Gaurav Kumar |
604af6 |
return watcher.watch
|
|
Pierre-Yves Chibon |
b65564 |
|
|
Pierre-Yves Chibon |
3b50fe |
project = pagure.lib.get_project(
|
|
Pierre-Yves Chibon |
3b50fe |
session, reponame, user=repouser, namespace=namespace)
|
|
Pierre-Yves Chibon |
b65564 |
if not project:
|
|
Pierre-Yves Chibon |
b65564 |
return False
|
|
Pierre-Yves Chibon |
b65564 |
|
|
Pierre-Yves Chibon |
784502 |
if user.username == project.user.username:
|
|
Gaurav Kumar |
604af6 |
return True
|
|
Gaurav Kumar |
604af6 |
|
|
Gaurav Kumar |
604af6 |
for group in project.groups:
|
|
Gaurav Kumar |
cece6f |
for guser in group.users:
|
|
Pierre-Yves Chibon |
784502 |
if user.username == guser.username:
|
|
Pierre-Yves Chibon |
cc69f7 |
return True
|
|
Gaurav Kumar |
604af6 |
|
|
Pierre-Yves Chibon |
cc69f7 |
return False
|
|
Vivek Anand |
272efb |
|
|
Vivek Anand |
272efb |
|
|
Vivek Anand |
272efb |
def user_watch_list(session, user):
|
|
Vivek Anand |
272efb |
''' Returns list of all the projects which the user is watching '''
|
|
Vivek Anand |
272efb |
|
|
Vivek Anand |
272efb |
user_obj = search_user(session, username=user)
|
|
Vivek Anand |
272efb |
if not user_obj:
|
|
Vivek Anand |
272efb |
return []
|
|
Vivek Anand |
272efb |
|
|
Vivek Anand |
272efb |
unwatched = session.query(
|
|
Vivek Anand |
272efb |
model.Watcher
|
|
Vivek Anand |
272efb |
).filter(
|
|
Vivek Anand |
272efb |
model.Watcher.user_id == user_obj.id
|
|
Vivek Anand |
272efb |
).filter(
|
|
Vivek Anand |
272efb |
model.Watcher.watch == False
|
|
Vivek Anand |
272efb |
)
|
|
Vivek Anand |
272efb |
|
|
Vivek Anand |
272efb |
unwatched_list = []
|
|
Vivek Anand |
272efb |
if unwatched:
|
|
Vivek Anand |
272efb |
unwatched_list = [unwatch.project for unwatch in unwatched.all()]
|
|
Vivek Anand |
272efb |
|
|
Vivek Anand |
272efb |
watched = session.query(
|
|
Vivek Anand |
272efb |
model.Watcher
|
|
Vivek Anand |
272efb |
).filter(
|
|
Vivek Anand |
272efb |
model.Watcher.user_id == user_obj.id
|
|
Vivek Anand |
272efb |
).filter(
|
|
Vivek Anand |
272efb |
model.Watcher.watch == True
|
|
Vivek Anand |
272efb |
)
|
|
Vivek Anand |
272efb |
|
|
Vivek Anand |
272efb |
watched_list = []
|
|
Vivek Anand |
272efb |
if watched:
|
|
Vivek Anand |
272efb |
watched_list = [watch.project for watch in watched.all()]
|
|
Vivek Anand |
272efb |
|
|
Vivek Anand |
272efb |
user_projects = search_projects(session, username=user_obj.user)
|
|
Vivek Anand |
272efb |
watch = set(watched_list + user_projects)
|
|
Vivek Anand |
272efb |
|
|
Vivek Anand |
272efb |
for project in user_projects:
|
|
Vivek Anand |
272efb |
if project in unwatched_list:
|
|
Vivek Anand |
272efb |
watch.remove(project)
|
|
Vivek Anand |
272efb |
|
|
Vivek Anand |
272efb |
return sorted(list(watch), key=lambda proj: proj.name)
|
|
Pierre-Yves Chibon |
cd6615 |
|
|
Pierre-Yves Chibon |
cd6615 |
|
|
Pierre-Yves Chibon |
cd6615 |
def save_report(session, repo, name, url, username):
|
|
Pierre-Yves Chibon |
cd6615 |
""" Save the report of issues based on the given URL of the project.
|
|
Pierre-Yves Chibon |
cd6615 |
"""
|
|
Pierre-Yves Chibon |
cd6615 |
url_obj = urlparse.urlparse(url)
|
|
Pierre-Yves Chibon |
cd6615 |
url = url_obj.geturl().replace(url_obj.query, '')
|
|
Pierre-Yves Chibon |
cd6615 |
query = dict(urlparse.parse_qsl(url_obj.query))
|
|
Pierre-Yves Chibon |
cd6615 |
reports = repo.reports
|
|
Pierre-Yves Chibon |
cd6615 |
reports[name] = query
|
|
Pierre-Yves Chibon |
cd6615 |
repo.reports = reports
|
|
Pierre-Yves Chibon |
cd6615 |
session.add(repo)
|
|
Pierre-Yves Chibon |
cdb5d4 |
|
|
Pierre-Yves Chibon |
cdb5d4 |
|
|
Pierre-Yves Chibon |
cdb5d4 |
def set_custom_key_fields(session, project, fields, types):
|
|
Pierre-Yves Chibon |
cdb5d4 |
""" Set or update the custom key fields of a project with the values
|
|
Pierre-Yves Chibon |
cdb5d4 |
provided.
|
|
Pierre-Yves Chibon |
cdb5d4 |
"""
|
|
Pierre-Yves Chibon |
cdb5d4 |
|
|
Pierre-Yves Chibon |
cdb5d4 |
current_keys = {}
|
|
Pierre-Yves Chibon |
cdb5d4 |
for key in project.issue_keys:
|
|
Pierre-Yves Chibon |
cdb5d4 |
current_keys[key.name] = key
|
|
Pierre-Yves Chibon |
cdb5d4 |
|
|
Pierre-Yves Chibon |
cdb5d4 |
for idx, key in enumerate(fields):
|
|
Pierre-Yves Chibon |
cdb5d4 |
if key in current_keys:
|
|
Pierre-Yves Chibon |
cdb5d4 |
issuekey = current_keys[key]
|
|
Pierre-Yves Chibon |
1fb905 |
issuekey.key_type = types[idx]
|
|
Pierre-Yves Chibon |
cdb5d4 |
else:
|
|
Pierre-Yves Chibon |
cdb5d4 |
issuekey = model.IssueKeys(
|
|
Pierre-Yves Chibon |
cdb5d4 |
project_id=project.id,
|
|
Pierre-Yves Chibon |
cdb5d4 |
name=key,
|
|
Pierre-Yves Chibon |
1fb905 |
key_type=types[idx],
|
|
Pierre-Yves Chibon |
cdb5d4 |
)
|
|
Pierre-Yves Chibon |
cdb5d4 |
session.add(issuekey)
|
|
Pierre-Yves Chibon |
cdb5d4 |
|
|
Pierre-Yves Chibon |
d89f6b |
# Delete keys
|
|
Pierre-Yves Chibon |
d89f6b |
for key in current_keys:
|
|
Pierre-Yves Chibon |
d89f6b |
if key not in fields:
|
|
Pierre-Yves Chibon |
d89f6b |
session.delete(current_keys[key])
|
|
Pierre-Yves Chibon |
d89f6b |
|
|
Pierre-Yves Chibon |
cdb5d4 |
return 'List of custom fields updated'
|
|
Pierre-Yves Chibon |
cdb5d4 |
|
|
Pierre-Yves Chibon |
cdb5d4 |
|
|
Pierre-Yves Chibon |
cdb5d4 |
def set_custom_key_value(session, issue, key, value):
|
|
Pierre-Yves Chibon |
cdb5d4 |
""" Set or update the value of the specified custom key.
|
|
Pierre-Yves Chibon |
cdb5d4 |
"""
|
|
Pierre-Yves Chibon |
cdb5d4 |
|
|
Pierre-Yves Chibon |
cdb5d4 |
query = session.query(
|
|
Pierre-Yves Chibon |
cdb5d4 |
model.IssueValues
|
|
Pierre-Yves Chibon |
cdb5d4 |
).filter(
|
|
Pierre-Yves Chibon |
4371c1 |
model.IssueValues.key_id == key.id
|
|
Pierre-Yves Chibon |
cdb5d4 |
).filter(
|
|
Pierre-Yves Chibon |
cdb5d4 |
model.IssueValues.issue_uid == issue.uid
|
|
Pierre-Yves Chibon |
cdb5d4 |
)
|
|
Pierre-Yves Chibon |
cdb5d4 |
|
|
Pierre-Yves Chibon |
cdb5d4 |
current_field = query.first()
|
|
Pierre-Yves Chibon |
cdb5d4 |
if current_field:
|
|
Pierre-Yves Chibon |
cdb5d4 |
current_field.value = value
|
|
Pierre-Yves Chibon |
cdb5d4 |
else:
|
|
Pierre-Yves Chibon |
cdb5d4 |
current_field = model.IssueValues(
|
|
Pierre-Yves Chibon |
cdb5d4 |
issue_uid=issue.uid,
|
|
Pierre-Yves Chibon |
cdb5d4 |
key_id=key.id,
|
|
Pierre-Yves Chibon |
cdb5d4 |
value=value,
|
|
Pierre-Yves Chibon |
cdb5d4 |
)
|
|
Pierre-Yves Chibon |
cdb5d4 |
session.add(current_field)
|
|
Pierre-Yves Chibon |
cdb5d4 |
|
|
Pierre-Yves Chibon |
cdb5d4 |
return 'Custom key adjusted'
|