changeset 1460:b50348816a80 beta

Added more advanced hook management into rhodecode admin settings
author Marcin Kuzminski <marcin@python-works.com>
date Fri, 09 Sep 2011 20:30:14 +0300
parents 6691d4097344
children e7d9d543364d
files rhodecode/controllers/admin/settings.py rhodecode/lib/db_manage.py rhodecode/model/db.py rhodecode/templates/admin/settings/hooks.html rhodecode/templates/admin/settings/settings.html
diffstat 5 files changed, 189 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/rhodecode/controllers/admin/settings.py	Fri Sep 09 19:54:23 2011 +0300
+++ b/rhodecode/controllers/admin/settings.py	Fri Sep 09 20:30:14 2011 +0300
@@ -225,6 +225,34 @@
                      prefix_error=False,
                      encoding="UTF-8")
 
+
+        if setting_id == 'hooks':
+            ui_key = request.POST.get('new_hook_ui_key')
+            ui_value = request.POST.get('new_hook_ui_value')
+            try:
+                
+                if ui_value and ui_key:
+                    RhodeCodeUi.create_or_update_hook(ui_key, ui_value)
+                    h.flash(_('Added new hook'),
+                            category='success')
+
+                # check for edits
+                update = False
+                _d = request.POST.dict_of_lists()
+                for k, v in zip(_d.get('hook_ui_key',[]), _d.get('hook_ui_value_new',[])):
+                    RhodeCodeUi.create_or_update_hook(k, v)
+                    update = True
+
+                if update:
+                    h.flash(_('Updated hooks'), category='success')
+
+            except:
+                log.error(traceback.format_exc())
+                h.flash(_('error occurred during hook creation'),
+                        category='error')
+
+            return redirect(url('admin_edit_setting', setting_id='hooks'))
+
         return redirect(url('admin_settings'))
 
     @HasPermissionAllDecorator('hg.admin')
@@ -236,7 +264,11 @@
         #    h.form(url('admin_setting', setting_id=ID),
         #           method='delete')
         # url('admin_setting', setting_id=ID)
-
+        if setting_id == 'hooks':
+            hook_id = request.POST.get('hook_id')
+            RhodeCodeUi.delete(hook_id)
+            
+            
     @HasPermissionAllDecorator('hg.admin')
     def show(self, setting_id, format='html'):
         """
@@ -250,6 +282,16 @@
         edit an existing item"""
         # url('admin_edit_setting', setting_id=ID)
 
+        c.hooks = RhodeCodeUi.get_builtin_hooks()
+        c.custom_hooks = RhodeCodeUi.get_custom_hooks()
+
+        return htmlfill.render(
+            render('admin/settings/hooks.html'),
+            defaults={},
+            encoding="UTF-8",
+            force_defaults=False
+        )
+
     @NotAnonymous()
     def my_account(self):
         """
--- a/rhodecode/lib/db_manage.py	Fri Sep 09 19:54:23 2011 +0300
+++ b/rhodecode/lib/db_manage.py	Fri Sep 09 20:30:14 2011 +0300
@@ -261,7 +261,7 @@
 
         """
         #HOOKS
-        hooks1_key = 'changegroup.update'
+        hooks1_key = RhodeCodeUi.HOOK_UPDATE
         hooks1_ = self.sa.query(RhodeCodeUi)\
             .filter(RhodeCodeUi.ui_key == hooks1_key).scalar()
 
@@ -271,7 +271,7 @@
         hooks1.ui_value = 'hg update >&2'
         hooks1.ui_active = False
 
-        hooks2_key = 'changegroup.repo_size'
+        hooks2_key = RhodeCodeUi.HOOK_REPO_SIZE
         hooks2_ = self.sa.query(RhodeCodeUi)\
             .filter(RhodeCodeUi.ui_key == hooks2_key).scalar()
 
@@ -282,12 +282,12 @@
 
         hooks3 = RhodeCodeUi()
         hooks3.ui_section = 'hooks'
-        hooks3.ui_key = 'pretxnchangegroup.push_logger'
+        hooks3.ui_key = RhodeCodeUi.HOOK_PUSH
         hooks3.ui_value = 'python:rhodecode.lib.hooks.log_push_action'
 
         hooks4 = RhodeCodeUi()
         hooks4.ui_section = 'hooks'
-        hooks4.ui_key = 'preoutgoing.pull_logger'
+        hooks4.ui_key = RhodeCodeUi.HOOK_PULL
         hooks4.ui_value = 'python:rhodecode.lib.hooks.log_pull_action'
 
         #For mercurial 1.7 set backward comapatibility with format
--- a/rhodecode/model/db.py	Fri Sep 09 19:54:23 2011 +0300
+++ b/rhodecode/model/db.py	Fri Sep 09 20:30:14 2011 +0300
@@ -125,7 +125,13 @@
     @classmethod
     def get(cls, id_):
         return Session.query(cls).get(id_)
-
+    
+    @classmethod
+    def delete(cls, id_):
+        obj = Session.query(cls).get(id_)
+        Session.delete(obj)
+        Session.commit()
+        
 
 class RhodeCodeSettings(Base, BaseModel):
     __tablename__ = 'rhodecode_settings'
@@ -181,7 +187,13 @@
 
 class RhodeCodeUi(Base, BaseModel):
     __tablename__ = 'rhodecode_ui'
-    __table_args__ = {'extend_existing':True}
+    __table_args__ = (UniqueConstraint('ui_key'), {'extend_existing':True})
+
+    HOOK_UPDATE = 'changegroup.update'
+    HOOK_REPO_SIZE = 'changegroup.repo_size'
+    HOOK_PUSH = 'pretxnchangegroup.push_logger'
+    HOOK_PULL = 'preoutgoing.pull_logger'
+
     ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
     ui_section = Column("ui_section", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
     ui_key = Column("ui_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
@@ -194,6 +206,35 @@
         return Session.query(cls).filter(cls.ui_key == key)
 
 
+    @classmethod
+    def get_builtin_hooks(cls):
+        q = cls.query()
+        q = q.filter(cls.ui_key.in_([cls.HOOK_UPDATE,
+                                    cls.HOOK_REPO_SIZE,
+                                    cls.HOOK_PUSH, cls.HOOK_PULL]))
+        return q.all()
+
+    @classmethod
+    def get_custom_hooks(cls):
+        q = cls.query()
+        q = q.filter(~cls.ui_key.in_([cls.HOOK_UPDATE,
+                                    cls.HOOK_REPO_SIZE,
+                                    cls.HOOK_PUSH, cls.HOOK_PULL]))
+        q = q.filter(cls.ui_section == 'hooks')
+        return q.all()
+
+    @classmethod
+    def create_or_update_hook(cls, key, val):
+        new_ui = cls.get_by_key(key).scalar() or cls()
+        new_ui.ui_section = 'hooks'
+        new_ui.ui_active = True
+        new_ui.ui_key = key
+        new_ui.ui_value = val
+
+        Session.add(new_ui)
+        Session.commit()
+
+
 class User(Base, BaseModel):
     __tablename__ = 'users'
     __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'extend_existing':True})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rhodecode/templates/admin/settings/hooks.html	Fri Sep 09 20:30:14 2011 +0300
@@ -0,0 +1,96 @@
+## -*- coding: utf-8 -*-
+<%inherit file="/base/base.html"/>
+
+<%def name="title()">
+    ${_('Settings administration')} - ${c.rhodecode_name}
+</%def>
+
+<%def name="breadcrumbs_links()">
+    ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; ${_('Settings')}
+</%def>
+
+<%def name="page_nav()">
+	${self.menu('admin')}
+</%def>
+
+<%def name="main()">
+<div class="box">
+    <!-- box / title -->
+    <div class="title">
+        ${self.breadcrumbs()}       
+    </div>
+    <!-- end box / title -->
+    
+    <h3>${_('Built in hooks - read only')}</h3>
+    <div class="form">
+        <div class="fields">
+          % for hook in c.hooks:
+          <div class="field">
+	        <div class="label label">
+	            <label for="${hook.ui_key}">${hook.ui_key}</label>
+	        </div>
+	        <div class="input" style="margin-left:280px">
+                  ${h.text(hook.ui_key,hook.ui_value,size=60,readonly="readonly")}
+	        </div>
+          </div>
+          % endfor
+		</div>
+    </div>
+    
+    <h3>${_('Custom hooks')}</h3>
+    ${h.form(url('admin_setting', setting_id='hooks'),method='put')}
+    <div class="form">
+        <div class="fields">
+        
+          % for hook in c.custom_hooks:
+          <div class="field"  id="${'id%s' % hook.ui_id }">
+            <div class="label label">
+                <label for="${hook.ui_key}">${hook.ui_key}</label>
+            </div>
+            <div class="input" style="margin-left:280px">                
+                ${h.hidden('hook_ui_key',hook.ui_key)}
+                ${h.hidden('hook_ui_value',hook.ui_value)}
+                ${h.text('hook_ui_value_new',hook.ui_value,size=60)}
+                <span class="delete_icon action_button" 
+                onclick="ajaxActionHook(${hook.ui_id},'${'id%s' % hook.ui_id }')">
+                ${_('remove')}
+                </span>
+            </div>
+          </div>
+          % endfor        
+        
+          <div class="field">
+            <div class="input" style="margin-left:-180px;position: absolute;">
+              <div class="input">
+                 ${h.text('new_hook_ui_key',size=30)}
+              </div>
+            </div>
+            <div class="input" style="margin-left:280px">
+                ${h.text('new_hook_ui_value',size=60)}
+            </div>
+          </div>
+          <div class="buttons" style="margin-left:280px">
+             ${h.submit('save','Save',class_="ui-button")}
+          </div>          
+        </div>
+    </div>
+    ${h.end_form()}
+</div>
+<script type="text/javascript">
+function ajaxActionHook(hook_id,field_id) {
+    var sUrl = "${h.url('admin_setting', setting_id='hooks')}";
+    var callback = {
+        success: function (o) {
+            var elem = YUD.get(""+field_id);
+            elem.parentNode.removeChild(elem);
+        },
+        failure: function (o) {
+            alert("${_('Failed to remove hook')}");
+        },
+    };
+    var postData = '_method=delete&hook_id=' + hook_id;
+    var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);
+};
+</script>
+      
+</%def>    
--- a/rhodecode/templates/admin/settings/settings.html	Fri Sep 09 19:54:23 2011 +0300
+++ b/rhodecode/templates/admin/settings/settings.html	Fri Sep 09 20:30:14 2011 +0300
@@ -138,6 +138,9 @@
                 <div class="label label-checkbox">
                     <label for="web_push_ssl">${_('Hooks')}:</label>
                 </div>
+                <div class="input">
+                    ${h.link_to('advanced setup',url('admin_edit_setting',setting_id='hooks'))}
+                </div>                
                 <div class="checkboxes">
 					<div class="checkbox">
 						${h.checkbox('hooks_changegroup_update','True')}