pagure-new/pagure/ui/plugins.py

190 lines
5.5 KiB
Python

# -*- coding: utf-8 -*-
"""
(c) 2014-2016 - Copyright Red Hat Inc
Authors:
Pierre-Yves Chibon <pingou@pingoured.fr>
"""
# pylint: disable=too-many-branches
# pylint: disable=no-member
import flask
from sqlalchemy.exc import SQLAlchemyError
from straight.plugin import load
from pagure.hooks import BaseHook
import pagure.exceptions
import pagure.lib
import pagure.forms
from pagure import APP, SESSION, login_required
from pagure.lib.model import BASE
from pagure.exceptions import FileNotFoundException
def get_plugin_names(blacklist=None):
''' Return the list of plugins names. '''
plugins = load('pagure.hooks', subclasses=BaseHook)
if not blacklist:
blacklist = []
elif not isinstance(blacklist, list):
blacklist = [blacklist]
output = [
plugin.name
for plugin in plugins
if plugin.name not in blacklist
]
return sorted(output)
def get_plugin_tables():
''' Return the list of all plugins. '''
plugins = load('pagure.hooks', subclasses=BASE)
return plugins
def get_plugin(plugin_name):
''' Return the list of plugins names. '''
plugins = load('pagure.hooks', subclasses=BaseHook)
for plugin in plugins:
if plugin.name == plugin_name:
return plugin
@APP.route('/<repo>/settings/<plugin>/', methods=('GET', 'POST'))
@APP.route('/<repo>/settings/<plugin>', methods=('GET', 'POST'))
@APP.route('/<namespace>/<repo>/settings/<plugin>/', methods=('GET', 'POST'))
@APP.route('/<namespace>/<repo>/settings/<plugin>', methods=('GET', 'POST'))
@APP.route(
'/<repo>/settings/<plugin>/<int:full>/',
methods=('GET', 'POST'))
@APP.route(
'/<repo>/settings/<plugin>/<int:full>',
methods=('GET', 'POST'))
@APP.route(
'/<namespace>/<repo>/settings/<plugin>/<int:full>/',
methods=('GET', 'POST'))
@APP.route(
'/<namespace>/<repo>/settings/<plugin>/<int:full>',
methods=('GET', 'POST'))
@APP.route(
'/fork/<username>/<repo>/settings/<plugin>/',
methods=('GET', 'POST'))
@APP.route(
'/fork/<username>/<namespace>/<repo>/settings/<plugin>/',
methods=('GET', 'POST'))
@APP.route(
'/fork/<username>/<repo>/settings/<plugin>',
methods=('GET', 'POST'))
@APP.route(
'/fork/<username>/<namespace>/<repo>/settings/<plugin>',
methods=('GET', 'POST'))
@APP.route(
'/fork/<username>/<repo>/settings/<plugin>/<int:full>/',
methods=('GET', 'POST'))
@APP.route(
'/fork/<username>/<namespace>/<repo>/settings/<plugin>/<int:full>/',
methods=('GET', 'POST'))
@APP.route(
'/fork/<username>/<repo>/settings/<plugin>/<int:full>',
methods=('GET', 'POST'))
@APP.route(
'/fork/<username>/<namespace>/<repo>/settings/<plugin>/<int:full>',
methods=('GET', 'POST'))
@login_required
def view_plugin(repo, plugin, username=None, namespace=None, full=True):
""" Presents the settings of the project.
"""
repo = flask.g.repo
if not flask.g.repo_admin:
flask.abort(
403,
'You are not allowed to change the settings for this project')
if plugin in APP.config.get('DISABLED_PLUGINS', []):
flask.abort(404, 'Plugin disabled')
plugin = get_plugin(plugin)
fields = []
new = True
dbobj = plugin.db_object()
if hasattr(repo, plugin.backref):
dbobj = getattr(repo, plugin.backref)
# There should always be only one, but let's double check
if dbobj:
new = False
else:
dbobj = plugin.db_object()
form = plugin.form(obj=dbobj)
for field in plugin.form_fields:
fields.append(getattr(form, field))
if form.validate_on_submit():
form.populate_obj(obj=dbobj)
if new:
dbobj.project_id = repo.id
SESSION.add(dbobj)
try:
SESSION.flush()
except SQLAlchemyError as err: # pragma: no cover
SESSION.rollback()
APP.logger.debug('Could not add plugin %s', plugin.name)
APP.logger.exception(err)
flask.flash(
'Could not add plugin %s, please contact an admin'
% plugin.name)
return flask.render_template(
'plugin.html',
select='settings',
full=full,
repo=repo,
username=username,
namespace=namespace,
plugin=plugin,
form=form,
fields=fields)
if form.active.data:
# Set up the main script if necessary
plugin.set_up(repo)
# Install the plugin itself
try:
plugin.install(repo, dbobj)
flask.flash('Hook %s activated' % plugin.name)
except FileNotFoundException as err:
pagure.APP.logger.exception(err)
flask.abort(404, 'No git repo found')
else:
try:
plugin.remove(repo)
flask.flash('Hook %s inactived' % plugin.name)
except FileNotFoundException as err:
pagure.APP.logger.exception(err)
flask.abort(404, 'No git repo found')
SESSION.commit()
return flask.redirect(flask.url_for(
'view_settings', repo=repo.name, username=username,
namespace=namespace))
return flask.render_template(
'plugin.html',
select='settings',
full=full,
repo=repo,
namespace=namespace,
username=username,
plugin=plugin,
form=form,
fields=fields)