Blame progit/ui/plugins.py

Pierre-Yves Chibon 33b534
# -*- coding: utf-8 -*-
Pierre-Yves Chibon 5df12e
Pierre-Yves Chibon 5df12e
"""
Pierre-Yves Chibon 5df12e
 (c) 2014 - Copyright Red Hat Inc
Pierre-Yves Chibon 5df12e
Pierre-Yves Chibon 5df12e
 Authors:
Pierre-Yves Chibon 5df12e
   Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
Pierre-Yves Chibon 5df12e
Pierre-Yves Chibon 5df12e
"""
Pierre-Yves Chibon 5df12e
Pierre-Yves Chibon 5df12e
import flask
Pierre-Yves Chibon 5df12e
import os
Pierre-Yves Chibon 5df12e
import sys
Pierre-Yves Chibon 5df12e
from math import ceil
Pierre-Yves Chibon 5df12e
Pierre-Yves Chibon 5df12e
import pygit2
Pierre-Yves Chibon 5df12e
from sqlalchemy.exc import SQLAlchemyError
Pierre-Yves Chibon 5df12e
from straight.plugin import load
Pierre-Yves Chibon 805d77
from progit.hooks import BaseHook
Pierre-Yves Chibon 5df12e
Pierre-Yves Chibon 5df12e
import progit.exceptions
Pierre-Yves Chibon 5df12e
import progit.lib
Pierre-Yves Chibon 5df12e
import progit.forms
Pierre-Yves Chibon 1a6981
from progit import APP, SESSION, LOG, cla_required, is_repo_admin
Pierre-Yves Chibon 26b4f4
from progit.lib.model import BASE
Pierre-Yves Chibon 5df12e
Pierre-Yves Chibon 5df12e
Pierre-Yves Chibon 5df12e
def get_plugin_names():
Pierre-Yves Chibon 5df12e
    ''' Return the list of plugins names. '''
Pierre-Yves Chibon 5df12e
    plugins = load('progit.hooks', subclasses=BaseHook)
Pierre-Yves Chibon 5df12e
    output = [plugin.name for plugin in plugins]
Pierre-Yves Chibon 5df12e
    return output
Pierre-Yves Chibon 5df12e
Pierre-Yves Chibon 5df12e
Pierre-Yves Chibon 1a6981
def get_plugin_tables():
Pierre-Yves Chibon 1a6981
    ''' Return the list of all plugins. '''
Pierre-Yves Chibon 1a6981
    plugins = load('progit.hooks', subclasses=BASE)
Pierre-Yves Chibon 1a6981
    return plugins
Pierre-Yves Chibon 1a6981
Pierre-Yves Chibon 1a6981
Pierre-Yves Chibon 5df12e
def get_plugin(plugin_name):
Pierre-Yves Chibon 5df12e
    ''' Return the list of plugins names. '''
Pierre-Yves Chibon 5df12e
    plugins = load('progit.hooks', subclasses=BaseHook)
Pierre-Yves Chibon 5df12e
    for plugin in plugins:
Pierre-Yves Chibon 5df12e
        if plugin.name == plugin_name:
Pierre-Yves Chibon 5df12e
            return plugin
Pierre-Yves Chibon 5df12e
Pierre-Yves Chibon 5df12e
Pierre-Yves Chibon 5df12e
@APP.route('/<repo>/settings/<plugin>', methods=('GET', 'POST'))</plugin></repo>
Pierre-Yves Chibon 05748c
@APP.route('/fork/<username>/<repo>/settings/<plugin>',</plugin></repo></username>
Pierre-Yves Chibon 05748c
           methods=('GET', 'POST'))
Pierre-Yves Chibon 5df12e
@cla_required
Pierre-Yves Chibon 5df12e
def view_plugin(repo, plugin, username=None):
Pierre-Yves Chibon 5df12e
    """ Presents the settings of the project.
Pierre-Yves Chibon 5df12e
    """
Pierre-Yves Chibon 5df12e
    return view_plugin_page(repo, plugin, username=username, full=True)
Pierre-Yves Chibon 5df12e
Pierre-Yves Chibon 5df12e
Pierre-Yves Chibon 5df12e
@APP.route(
Pierre-Yves Chibon 5df12e
    '/<repo>/settings/<plugin>/<int:full>', methods=('GET', 'POST'))</int:full></plugin></repo>
Pierre-Yves Chibon 5df12e
@APP.route(
Pierre-Yves Chibon 5df12e
    '/fork/<username>/<repo>/settings/<plugin>/<int:full>',</int:full></plugin></repo></username>
Pierre-Yves Chibon 5df12e
    methods=('GET', 'POST'))
Pierre-Yves Chibon 5df12e
@cla_required
Pierre-Yves Chibon 5df12e
def view_plugin_page(repo, plugin, full, username=None):
Pierre-Yves Chibon 5df12e
    """ Presents the settings of the project.
Pierre-Yves Chibon 5df12e
    """
Pierre-Yves Chibon 5df12e
    repo = progit.lib.get_project(SESSION, repo, user=username)
Pierre-Yves Chibon 5df12e
Pierre-Yves Chibon 5df12e
    if not repo:
Pierre-Yves Chibon 5df12e
        flask.abort(404, 'Project not found')
Pierre-Yves Chibon 5df12e
Pierre-Yves Chibon 5df12e
    if not is_repo_admin(repo):
Pierre-Yves Chibon 5df12e
        flask.abort(
Pierre-Yves Chibon 5df12e
            403,
Pierre-Yves Chibon 5df12e
            'You are not allowed to change the settings for this project')
Pierre-Yves Chibon 5df12e
Pierre-Yves Chibon 5df12e
    plugin = get_plugin(plugin)
Pierre-Yves Chibon 5df12e
    fields = []
Pierre-Yves Chibon 535b02
    new = True
Pierre-Yves Chibon 535b02
    dbobj = plugin.db_object()
Pierre-Yves Chibon 535b02
    if hasattr(repo, plugin.backref):
Pierre-Yves Chibon 535b02
        dbobj = getattr(repo, plugin.backref)
Pierre-Yves Chibon 535b02
        # There should always be only one, but let's double check
Pierre-Yves Chibon 535b02
        if dbobj and len(dbobj) > 0:
Pierre-Yves Chibon 535b02
            dbobj = dbobj[0]
Pierre-Yves Chibon 535b02
            new = False
Pierre-Yves Chibon 535b02
        else:
Pierre-Yves Chibon 535b02
            dbobj = plugin.db_object()
Pierre-Yves Chibon 535b02
Pierre-Yves Chibon 535b02
    form = plugin.form(obj=dbobj)
Pierre-Yves Chibon 5df12e
    for field in plugin.form_fields:
Pierre-Yves Chibon 1a6981
        fields.append(getattr(form, field))
Pierre-Yves Chibon 5df12e
Pierre-Yves Chibon 535b02
    if form.validate_on_submit():
Pierre-Yves Chibon 535b02
        form.populate_obj(obj=dbobj)
Pierre-Yves Chibon 535b02
        if new:
Pierre-Yves Chibon 535b02
            dbobj.project_id = repo.id
Pierre-Yves Chibon 535b02
            SESSION.add(dbobj)
Pierre-Yves Chibon 535b02
        try:
Pierre-Yves Chibon 535b02
            SESSION.flush()
Pierre-Yves Chibon 8c3c55
        except SQLAlchemyError, err:  # pragma: no cover
Pierre-Yves Chibon 6b241d
            SESSION.rollback()
Pierre-Yves Chibon 535b02
            APP.logger.debug('Could not add plugin %s', plugin.name)
Pierre-Yves Chibon 535b02
            APP.logger.exception(err)
Pierre-Yves Chibon 535b02
            flask.flash(
Pierre-Yves Chibon 535b02
                'Could not add plugin %s, please contact an admin'
Pierre-Yves Chibon 535b02
                % plugin.name)
Pierre-Yves Chibon 535b02
Pierre-Yves Chibon 535b02
            return flask.render_template(
Pierre-Yves Chibon 535b02
                'plugin.html',
Pierre-Yves Chibon 535b02
                select='settings',
Pierre-Yves Chibon 535b02
                full=full,
Pierre-Yves Chibon 535b02
                repo=repo,
Pierre-Yves Chibon 535b02
                username=username,
Pierre-Yves Chibon 535b02
                plugin=plugin,
Pierre-Yves Chibon 535b02
                form=form,
Pierre-Yves Chibon 535b02
                fields=fields,
Pierre-Yves Chibon 535b02
            )
Pierre-Yves Chibon 535b02
Pierre-Yves Chibon 535b02
        if form.active.data:
Pierre-Yves Chibon c2a594
            # Set up the main script if necessary
Pierre-Yves Chibon c2a594
            plugin.set_up(repo)
Pierre-Yves Chibon c2a594
            # Install the plugin itself
Pierre-Yves Chibon c2a594
            plugin.install(repo, dbobj)
Pierre-Yves Chibon 535b02
            flask.flash('Hook activated')
Pierre-Yves Chibon 535b02
        else:
Pierre-Yves Chibon 535b02
            plugin.remove(repo)
Pierre-Yves Chibon 535b02
            flask.flash('Hook inactived')
Pierre-Yves Chibon 535b02
Pierre-Yves Chibon 535b02
        SESSION.commit()
Pierre-Yves Chibon 535b02
Pierre-Yves Chibon 5df12e
    return flask.render_template(
Pierre-Yves Chibon 5df12e
        'plugin.html',
Pierre-Yves Chibon 5df12e
        select='settings',
Pierre-Yves Chibon 5df12e
        full=full,
Pierre-Yves Chibon 5df12e
        repo=repo,
Pierre-Yves Chibon 5df12e
        username=username,
Pierre-Yves Chibon 5df12e
        plugin=plugin,
Pierre-Yves Chibon 1a6981
        form=form,
Pierre-Yves Chibon 5df12e
        fields=fields,
Pierre-Yves Chibon 5df12e
    )