Blame progit/hooks/progit_ticket_hook.py

Pierre-Yves Chibon 33b534
# -*- coding: utf-8 -*-
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
"""
Pierre-Yves Chibon 1d6d27
 (c) 2014 - Copyright Red Hat Inc
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
 Authors:
Pierre-Yves Chibon 1d6d27
   Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
"""
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
import os
Pierre-Yves Chibon 1d6d27
import shutil
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon eab92f
import flask
Pierre-Yves Chibon 1d6d27
import sqlalchemy as sa
Pierre-Yves Chibon 1d6d27
import pygit2
Pierre-Yves Chibon 1d6d27
import wtforms
Pierre-Yves Chibon 1d6d27
from flask.ext import wtf
Pierre-Yves Chibon 1d6d27
from sqlalchemy.orm import relation
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
from progit.hooks import BaseHook
Pierre-Yves Chibon 26b4f4
from progit.lib.model import BASE, Project
Pierre-Yves Chibon 1d6d27
from progit import SESSION, APP
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
class ProgitTicketsTable(BASE):
Pierre-Yves Chibon 1d6d27
    """ Stores information about the progit tickets hook deployed on a project.
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
    Table -- hook_progit_tickets
Pierre-Yves Chibon 1d6d27
    """
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
    __tablename__ = 'hook_progit_tickets'
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
    id = sa.Column(sa.Integer, primary_key=True)
Pierre-Yves Chibon 1d6d27
    project_id = sa.Column(
Pierre-Yves Chibon 1d6d27
        sa.Integer,
Pierre-Yves Chibon 1d6d27
        sa.ForeignKey('projects.id', onupdate='CASCADE'),
Pierre-Yves Chibon 1d6d27
        nullable=False,
Pierre-Yves Chibon 1d6d27
        unique=True,
Pierre-Yves Chibon 1d6d27
        index=True)
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
    active = sa.Column(sa.Boolean, nullable=False, default=False)
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
    project = relation(
Pierre-Yves Chibon 016952
        'Project', remote_side=[Project.id], backref='progit_hook_tickets',
Pierre-Yves Chibon 016952
        cascade="delete, delete-orphan", single_parent=True)
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
class ProgitTicketsForm(wtf.Form):
Pierre-Yves Chibon 1d6d27
    ''' Form to configure the progit hook. '''
Pierre-Yves Chibon 1d6d27
    active = wtforms.BooleanField(
Pierre-Yves Chibon 65fcfd
        'Active',
Pierre-Yves Chibon 1d6d27
        [wtforms.validators.Optional()]
Pierre-Yves Chibon 1d6d27
    )
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
class ProgitTicketHook(BaseHook):
Pierre-Yves Chibon 1d6d27
    ''' Progit ticket hook. '''
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
    name = 'progit tickets'
Pierre-Yves Chibon 1d6d27
    form = ProgitTicketsForm
Pierre-Yves Chibon 1d6d27
    db_object = ProgitTicketsTable
Pierre-Yves Chibon 452840
    backref = 'progit_hook_tickets'
Pierre-Yves Chibon 1d6d27
    form_fields = ['active']
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
    @classmethod
Pierre-Yves Chibon eab92f
    def set_up(cls, project):
Pierre-Yves Chibon eab92f
        ''' Install the generic post-receive hook that allow us to call
Pierre-Yves Chibon eab92f
        multiple post-receive hooks as set per plugin.
Pierre-Yves Chibon eab92f
        '''
Pierre-Yves Chibon eab92f
        repopath = os.path.join(APP.config['TICKETS_FOLDER'], project.path)
Pierre-Yves Chibon eab92f
        if not os.path.exists(repopath):
Pierre-Yves Chibon eab92f
            flask.abort(404, 'No git repo found')
Pierre-Yves Chibon eab92f
Pierre-Yves Chibon eab92f
        hook_files = os.path.join(
Pierre-Yves Chibon eab92f
            os.path.dirname(os.path.realpath(__file__)), 'files')
Pierre-Yves Chibon eab92f
Pierre-Yves Chibon eab92f
        # Make sure the hooks folder exists
Pierre-Yves Chibon eab92f
        hookfolder = os.path.join(repopath, 'hooks')
Pierre-Yves Chibon eab92f
        if not os.path.exists(hookfolder):
Pierre-Yves Chibon eab92f
            os.makedirs(hookfolder)
Pierre-Yves Chibon eab92f
Pierre-Yves Chibon eab92f
        # Install the main post-receive file
Pierre-Yves Chibon eab92f
        postreceive = os.path.join(hookfolder, 'post-receive')
Pierre-Yves Chibon eab92f
        if not os.path.exists(postreceive):
Pierre-Yves Chibon eab92f
            shutil.copyfile(
Pierre-Yves Chibon eab92f
                os.path.join(hook_files, 'post-receive'),
Pierre-Yves Chibon eab92f
                postreceive)
Pierre-Yves Chibon eab92f
            os.chmod(postreceive, 0755)
Pierre-Yves Chibon eab92f
Pierre-Yves Chibon eab92f
    @classmethod
Pierre-Yves Chibon 1d6d27
    def install(cls, project, dbobj):
Pierre-Yves Chibon 1d6d27
        ''' Method called to install the hook for a project.
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
        :arg project: a ``progit.model.Project`` object to which the hook
Pierre-Yves Chibon 1d6d27
            should be installed
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
        '''
Pierre-Yves Chibon 1d6d27
        repopath = os.path.join(APP.config['TICKETS_FOLDER'], project.path)
Pierre-Yves Chibon 068919
        if not os.path.exists(repopath):
Pierre-Yves Chibon 068919
            flask.abort(404, 'No git repo found')
Pierre-Yves Chibon 068919
Pierre-Yves Chibon 1d6d27
        hook_files = os.path.join(
Pierre-Yves Chibon 1d6d27
            os.path.dirname(os.path.realpath(__file__)), 'files')
Pierre-Yves Chibon 1d6d27
        repo_obj = pygit2.Repository(repopath)
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
        # Install the hook itself
Pierre-Yves Chibon 1d6d27
        shutil.copyfile(
Pierre-Yves Chibon 59bf8a
            os.path.join(hook_files, 'progit_hook_tickets.py'),
Pierre-Yves Chibon 1d6d27
            os.path.join(repopath, 'hooks', 'post-receive.progit')
Pierre-Yves Chibon 1d6d27
        )
Pierre-Yves Chibon 1d6d27
        os.chmod(
Pierre-Yves Chibon 6a0f99
            os.path.join(repopath, 'hooks', 'post-receive.progit'),
Pierre-Yves Chibon 1d6d27
            0755)
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
    @classmethod
Pierre-Yves Chibon 1d6d27
    def remove(cls, project):
Pierre-Yves Chibon 1d6d27
        ''' Method called to remove the hook of a project.
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
        :arg project: a ``progit.model.Project`` object to which the hook
Pierre-Yves Chibon 1d6d27
            should be installed
Pierre-Yves Chibon 1d6d27
Pierre-Yves Chibon 1d6d27
        '''
Pierre-Yves Chibon 1d6d27
        repopath = os.path.join(APP.config['TICKETS_FOLDER'], project.path)
Pierre-Yves Chibon 068919
        if not os.path.exists(repopath):
Pierre-Yves Chibon 068919
            flask.abort(404, 'No git repo found')
Pierre-Yves Chibon 068919
Pierre-Yves Chibon 1d6d27
        hook_path = os.path.join(
Pierre-Yves Chibon 6a0f99
            repopath, 'hooks', 'post-receive.progit')
Pierre-Yves Chibon 1d6d27
        if os.path.exists(hook_path):
Pierre-Yves Chibon 1d6d27
            os.unlink(hook_path)