2020-04-02 00:51:14 +02:00
|
|
|
from flask import Blueprint, render_template, request, redirect, url_for
|
2021-02-22 01:32:23 +01:00
|
|
|
from flask import abort
|
2020-04-02 00:51:14 +02:00
|
|
|
from hubsrht.projects import ProjectAccess, get_project
|
|
|
|
from hubsrht.services import todo
|
2020-04-29 19:34:57 +02:00
|
|
|
from hubsrht.types import Event, EventType, Tracker, Visibility
|
2020-04-02 00:51:14 +02:00
|
|
|
from srht.database import db
|
|
|
|
from srht.flask import paginate_query
|
2020-04-29 19:25:49 +02:00
|
|
|
from srht.oauth import current_user, loginrequired
|
2020-04-02 00:51:14 +02:00
|
|
|
from srht.search import search_by
|
|
|
|
from srht.validation import Validation
|
|
|
|
|
|
|
|
trackers = Blueprint("trackers", __name__)
|
|
|
|
|
2020-04-02 16:18:04 +02:00
|
|
|
@trackers.route("/<owner>/<project_name>/trackers")
|
|
|
|
def trackers_GET(owner, project_name):
|
2020-04-29 16:36:59 +02:00
|
|
|
owner, project = get_project(owner, project_name, ProjectAccess.read)
|
2020-04-02 16:18:04 +02:00
|
|
|
trackers = (Tracker.query
|
|
|
|
.filter(Tracker.project_id == project.id)
|
|
|
|
.order_by(Tracker.updated.desc()))
|
2020-04-29 19:25:49 +02:00
|
|
|
if not current_user or current_user.id != owner.id:
|
2022-06-30 23:05:56 +02:00
|
|
|
trackers = trackers.filter(Tracker.visibility == Visibility.PUBLIC)
|
2020-04-02 16:18:04 +02:00
|
|
|
|
|
|
|
terms = request.args.get("search")
|
|
|
|
search_error = None
|
|
|
|
try:
|
|
|
|
trackers = search_by(trackers, terms,
|
|
|
|
[Tracker.name, Tracker.description])
|
|
|
|
except ValueError as ex:
|
|
|
|
search_error = str(ex)
|
|
|
|
|
|
|
|
trackers, pagination = paginate_query(trackers)
|
|
|
|
return render_template("trackers.html", view="tickets",
|
|
|
|
owner=owner, project=project, trackers=trackers,
|
|
|
|
search=terms, search_error=search_error,
|
|
|
|
**pagination)
|
|
|
|
|
2020-04-02 00:51:14 +02:00
|
|
|
@trackers.route("/<owner>/<project_name>/trackers/new")
|
|
|
|
@loginrequired
|
|
|
|
def new_GET(owner, project_name):
|
|
|
|
owner, project = get_project(owner, project_name, ProjectAccess.write)
|
|
|
|
# TODO: Pagination
|
|
|
|
trackers = todo.get_trackers(owner)
|
|
|
|
trackers = sorted(trackers, key=lambda r: r["updated"], reverse=True)
|
2020-04-29 15:59:53 +02:00
|
|
|
existing = [t.remote_id for t in (Tracker.query
|
|
|
|
.filter(Tracker.project_id == project.id)).all()]
|
2020-04-02 00:51:14 +02:00
|
|
|
return render_template("tracker-new.html", view="new-resource",
|
2020-04-29 15:59:53 +02:00
|
|
|
owner=owner, project=project, trackers=trackers, existing=existing)
|
2020-04-02 15:24:29 +02:00
|
|
|
|
|
|
|
@trackers.route("/<owner>/<project_name>/trackers/new", methods=["POST"])
|
|
|
|
@loginrequired
|
|
|
|
def new_POST(owner, project_name):
|
|
|
|
owner, project = get_project(owner, project_name, ProjectAccess.write)
|
|
|
|
valid = Validation(request)
|
|
|
|
if "create" in valid:
|
2021-10-29 10:55:05 +02:00
|
|
|
remote_tracker = todo.create_tracker(owner, valid, project.visibility)
|
2020-04-02 19:41:46 +02:00
|
|
|
trackers = todo.get_trackers(owner)
|
|
|
|
trackers = sorted(trackers, key=lambda r: r["updated"], reverse=True)
|
|
|
|
if not valid.ok:
|
2021-08-12 08:21:29 +02:00
|
|
|
existing = [t.remote_id for t in (Tracker.query
|
|
|
|
.filter(Tracker.project_id == project.id)).all()]
|
2020-04-02 19:41:46 +02:00
|
|
|
return render_template("tracker-new.html",
|
|
|
|
view="new-resource", owner=owner, project=project,
|
2021-08-12 08:21:29 +02:00
|
|
|
trackers=trackers, existing=existing, **valid.kwargs)
|
2020-04-02 15:24:29 +02:00
|
|
|
else:
|
|
|
|
tracker_name = None
|
|
|
|
for field in valid.source:
|
|
|
|
if field.startswith("existing-"):
|
|
|
|
tracker_name = field[len("existing-"):]
|
|
|
|
break
|
|
|
|
|
|
|
|
if not tracker_name:
|
|
|
|
search = valid.optional("search")
|
|
|
|
trackers = todo.get_trackers(owner)
|
2020-04-02 19:38:28 +02:00
|
|
|
trackers = filter(lambda r:
|
|
|
|
search.lower() in r["name"].lower()
|
|
|
|
or search.lower() in r["description"].lower(), trackers)
|
|
|
|
trackers = sorted(trackers, key=lambda r: r["updated"], reverse=True)
|
2021-08-12 08:21:29 +02:00
|
|
|
existing = [t.remote_id for t in (Tracker.query
|
|
|
|
.filter(Tracker.project_id == project.id)).all()]
|
2020-04-02 15:24:29 +02:00
|
|
|
return render_template("tracker-new.html", view="new-resource",
|
|
|
|
owner=owner, project=project, trackers=trackers,
|
2021-08-12 08:21:29 +02:00
|
|
|
existing=existing, search=search)
|
2020-04-02 15:24:29 +02:00
|
|
|
|
|
|
|
remote_tracker = todo.get_tracker(owner, tracker_name)
|
|
|
|
|
|
|
|
tracker = Tracker()
|
|
|
|
tracker.remote_id = remote_tracker["id"]
|
|
|
|
tracker.project_id = project.id
|
|
|
|
tracker.owner_id = owner.id
|
|
|
|
tracker.name = remote_tracker["name"]
|
|
|
|
tracker.description = remote_tracker["description"]
|
2021-10-06 10:06:51 +02:00
|
|
|
if any(remote_tracker["default_access"]):
|
2022-06-30 23:05:56 +02:00
|
|
|
tracker.visibility = Visibility.PUBLIC
|
2020-04-29 19:25:49 +02:00
|
|
|
else:
|
2022-06-30 23:05:56 +02:00
|
|
|
tracker.visibility = Visibility.UNLISTED
|
2020-04-02 15:24:29 +02:00
|
|
|
db.session.add(tracker)
|
|
|
|
db.session.flush()
|
|
|
|
|
|
|
|
event = Event()
|
|
|
|
event.event_type = EventType.tracker_added
|
|
|
|
event.tracker_id = tracker.id
|
|
|
|
event.project_id = project.id
|
|
|
|
event.user_id = project.owner_id
|
|
|
|
db.session.add(event)
|
|
|
|
|
|
|
|
todo.ensure_user_webhooks(owner)
|
2020-04-06 22:15:52 +02:00
|
|
|
todo.ensure_tracker_webhooks(tracker)
|
2020-04-02 15:24:29 +02:00
|
|
|
|
|
|
|
db.session.commit()
|
|
|
|
|
|
|
|
return redirect(url_for("projects.summary_GET",
|
|
|
|
owner=owner.canonical_name, project_name=project.name))
|
2020-04-02 16:26:04 +02:00
|
|
|
|
|
|
|
@trackers.route("/<owner>/<project_name>/trackers/manage")
|
|
|
|
@loginrequired
|
|
|
|
def manage_GET(owner, project_name):
|
|
|
|
owner, project = get_project(owner, project_name, ProjectAccess.write)
|
|
|
|
trackers = (Tracker.query
|
|
|
|
.filter(Tracker.project_id == project.id)
|
|
|
|
.order_by(Tracker.updated.desc()))
|
|
|
|
|
|
|
|
terms = request.args.get("search")
|
|
|
|
search_error = None
|
|
|
|
try:
|
|
|
|
trackers = search_by(trackers, terms,
|
|
|
|
[Tracker.name, Tracker.description])
|
|
|
|
except ValueError as ex:
|
|
|
|
search_error = str(ex)
|
|
|
|
|
|
|
|
trackers, pagination = paginate_query(trackers)
|
|
|
|
return render_template("trackers-manage.html", view="tickets",
|
|
|
|
owner=owner, project=project, trackers=trackers,
|
|
|
|
search=terms, search_error=search_error,
|
|
|
|
**pagination)
|
|
|
|
|
|
|
|
@trackers.route("/<owner>/<project_name>/trackers/delete/<int:tracker_id>")
|
|
|
|
@loginrequired
|
|
|
|
def delete_GET(owner, project_name, tracker_id):
|
|
|
|
owner, project = get_project(owner, project_name, ProjectAccess.write)
|
|
|
|
tracker = (Tracker.query
|
|
|
|
.filter(Tracker.id == tracker_id)
|
|
|
|
.filter(Tracker.project_id == project.id)).one_or_none()
|
|
|
|
if not tracker:
|
|
|
|
abort(404)
|
|
|
|
return render_template("resource-delete.html", view="tickets",
|
|
|
|
owner=owner, project=project, resource=tracker,
|
|
|
|
resource_type="ticket tracker")
|
|
|
|
|
|
|
|
@trackers.route("/<owner>/<project_name>/trackers/delete/<int:tracker_id>",
|
|
|
|
methods=["POST"])
|
|
|
|
@loginrequired
|
|
|
|
def delete_POST(owner, project_name, tracker_id):
|
|
|
|
owner, project = get_project(owner, project_name, ProjectAccess.write)
|
|
|
|
tracker = (Tracker.query
|
|
|
|
.filter(Tracker.id == tracker_id)
|
|
|
|
.filter(Tracker.project_id == project.id)).one_or_none()
|
|
|
|
if not tracker:
|
|
|
|
abort(404)
|
2020-07-08 18:19:48 +02:00
|
|
|
tracker_name = tracker.name
|
2020-04-02 16:26:04 +02:00
|
|
|
db.session.delete(tracker)
|
2020-07-08 18:19:48 +02:00
|
|
|
db.session.commit()
|
2020-04-02 16:26:04 +02:00
|
|
|
|
|
|
|
valid = Validation(request)
|
|
|
|
delete_remote = valid.optional("delete-remote") == "on"
|
|
|
|
if delete_remote:
|
2020-07-08 18:19:48 +02:00
|
|
|
todo.delete_tracker(owner, tracker_name)
|
2020-04-02 16:26:04 +02:00
|
|
|
|
|
|
|
return redirect(url_for("projects.summary_GET",
|
|
|
|
owner=owner.canonical_name, project_name=project.name))
|