keithsalisbury-subtrac 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION.yml +1 -1
- data/bin/subtrac +2 -0
- data/lib/subtrac.rb +85 -50
- data/lib/subtrac/config/config.yml +22 -19
- data/lib/subtrac/templates/location.erb +2 -2
- data/lib/subtrac/templates/projects/blank/trac/wiki/WikiStart +1 -1
- data/lib/subtrac/templates/trac.erb +1 -1
- data/lib/subtrac/templates/vhost.erb +6 -6
- metadata +1 -105
- data/lib/subtrac/trac-plugins/advancedticketworkflowplugin/advancedworkflow/__init__.py +0 -0
- data/lib/subtrac/trac-plugins/advancedticketworkflowplugin/advancedworkflow/controller.py +0 -419
- data/lib/subtrac/trac-plugins/advancedticketworkflowplugin/setup.cfg +0 -3
- data/lib/subtrac/trac-plugins/advancedticketworkflowplugin/setup.py +0 -20
- data/lib/subtrac/trac-plugins/clientsplugin/clients/__init__.py +0 -0
- data/lib/subtrac/trac-plugins/clientsplugin/clients/action.py +0 -28
- data/lib/subtrac/trac-plugins/clientsplugin/clients/action_email.py +0 -168
- data/lib/subtrac/trac-plugins/clientsplugin/clients/action_zendesk_forum.py +0 -137
- data/lib/subtrac/trac-plugins/clientsplugin/clients/admin.py +0 -91
- data/lib/subtrac/trac-plugins/clientsplugin/clients/api.py +0 -199
- data/lib/subtrac/trac-plugins/clientsplugin/clients/client.py +0 -105
- data/lib/subtrac/trac-plugins/clientsplugin/clients/events.py +0 -287
- data/lib/subtrac/trac-plugins/clientsplugin/clients/eventsadmin.py +0 -71
- data/lib/subtrac/trac-plugins/clientsplugin/clients/htdocs/clients.css +0 -4
- data/lib/subtrac/trac-plugins/clientsplugin/clients/model.py +0 -135
- data/lib/subtrac/trac-plugins/clientsplugin/clients/processor.py +0 -70
- data/lib/subtrac/trac-plugins/clientsplugin/clients/reportmanager.py +0 -142
- data/lib/subtrac/trac-plugins/clientsplugin/clients/reports.py +0 -231
- data/lib/subtrac/trac-plugins/clientsplugin/clients/summary.py +0 -27
- data/lib/subtrac/trac-plugins/clientsplugin/clients/summary_milestone.py +0 -152
- data/lib/subtrac/trac-plugins/clientsplugin/clients/summary_ticketchanges.py +0 -160
- data/lib/subtrac/trac-plugins/clientsplugin/clients/templates/admin_client_events.html +0 -124
- data/lib/subtrac/trac-plugins/clientsplugin/clients/templates/admin_clients.html +0 -134
- data/lib/subtrac/trac-plugins/clientsplugin/cron/changes.xslt +0 -132
- data/lib/subtrac/trac-plugins/clientsplugin/cron/run-client-event +0 -97
- data/lib/subtrac/trac-plugins/clientsplugin/cron/summary.xslt +0 -161
- data/lib/subtrac/trac-plugins/clientsplugin/setup.py +0 -43
- data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/__init__.py +0 -4
- data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/burndownchart.py +0 -273
- data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/hoursinplaceeditor.py +0 -44
- data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/hoursremaining.py +0 -36
- data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/htdocs/jquery-1.2.3.min.js +0 -32
- data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/htdocs/jquery.jeditable.js +0 -409
- data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/htdocs/jquery.jeditable.mini.js +0 -30
- data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/templates/edithours.html +0 -53
- data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/tests/burndownchart.py +0 -181
- data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/tests/hoursremaining.py +0 -66
- data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/tests/workloadchart.py +0 -47
- data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/utils.py +0 -93
- data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/workloadchart.py +0 -86
- data/lib/subtrac/trac-plugins/estimationtoolsplugin/setup.py +0 -20
- data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/SumRollups.js +0 -23
- data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/adw_tracdb.py +0 -128
- data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/git-post-receive +0 -40
- data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/trac-post-commit.py +0 -285
- data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/trac_billing.py +0 -173
- data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/utils/__init__.py +0 -0
- data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/utils/mail.py +0 -164
- data/lib/subtrac/trac-plugins/timingandestimationplugin/setup.py +0 -69
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/__init__.py +0 -1
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/api.py +0 -292
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/blackmagic.py +0 -172
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/dbhelper.py +0 -178
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/billingplugin.css +0 -25
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/field_disabler.js +0 -6
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/formatDate.js +0 -356
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/js/tip_centerwindow.js +0 -100
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/js/tip_followscroll.js +0 -84
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/js/wz_tooltip.js +0 -1149
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/linkifyer.js +0 -119
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/query.js +0 -73
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/ticket.js +0 -165
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/query_webui.py +0 -28
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/reportmanager.py +0 -221
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/reports.py +0 -675
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/reports_filter.py +0 -150
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/statuses.py +0 -25
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/tande_filters.py +0 -131
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/templates/billing.cs +0 -84
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/templates/billing.html +0 -104
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/ticket_daemon.py +0 -194
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/ticket_policy.py +0 -62
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/ticket_webui.py +0 -28
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/usermanual.py +0 -127
- data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/webui.py +0 -129
- data/lib/subtrac/trac-plugins/worklogplugin/setup.py +0 -29
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/__init__.py +0 -1
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/api.py +0 -187
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/jqModal.css +0 -40
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/jqModal.js +0 -67
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/jquery.mousewheel.pack.js +0 -12
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/jquery.timeentry.pack.js +0 -7
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/tracWorklog.js +0 -40
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/ui.datepicker.css +0 -208
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/ui.datepicker.js +0 -1439
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/work.png +0 -0
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/work.xcf +0 -0
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/worklogplugin.css +0 -80
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/workstart.png +0 -0
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/workstop.png +0 -0
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/manager.py +0 -336
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/reports.py +0 -598
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/templates/worklog.html +0 -45
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/templates/worklog_stop.html +0 -70
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/templates/worklog_user.html +0 -40
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/templates/worklog_webadminui.html +0 -59
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/ticket_daemon.py +0 -33
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/ticket_filter.py +0 -153
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/timeline_hook.py +0 -96
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/usermanual.py +0 -29
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/util.py +0 -31
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/webadminui.py +0 -47
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/webui.py +0 -174
- data/lib/subtrac/trac-plugins/worklogplugin/worklog/xmlrpc.py +0 -73
@@ -1,86 +0,0 @@
|
|
1
|
-
from datetime import timedelta
|
2
|
-
from estimationtools.utils import parse_options, execute_query, get_estimation_field, get_estimation_suffix, get_closed_states
|
3
|
-
from trac.util.html import Markup
|
4
|
-
from trac.wiki.macros import WikiMacroBase
|
5
|
-
import copy
|
6
|
-
|
7
|
-
DEFAULT_OPTIONS = {'width': '400', 'height': '100', 'color': 'ff9900'}
|
8
|
-
|
9
|
-
class WorkloadChart(WikiMacroBase):
|
10
|
-
"""Creates workload chart for the selected tickets.
|
11
|
-
|
12
|
-
This macro creates a pie chart that shows the remaining estimated workload per ticket owner,
|
13
|
-
and the remaining work days.
|
14
|
-
It has the following parameters:
|
15
|
-
* a comma-separated list of query parameters for the ticket selection, in the form "key=value" as specified in TracQuery#QueryLanguage.
|
16
|
-
* `width`: width of resulting diagram (defaults to 400)
|
17
|
-
* `height`: height of resulting diagram (defaults to 100)
|
18
|
-
* `color`: color specified as 6-letter string of hexadecimal values in the format `RRGGBB`.
|
19
|
-
Defaults to `ff9900`, a nice orange.
|
20
|
-
|
21
|
-
Examples:
|
22
|
-
{{{
|
23
|
-
[[WorkloadChart(milestone=Sprint 1)]]
|
24
|
-
[[WorkloadChart(milestone=Sprint 1, width=600, height=100, color=00ff00)]]
|
25
|
-
}}}
|
26
|
-
"""
|
27
|
-
|
28
|
-
estimation_field = get_estimation_field()
|
29
|
-
estimation_suffix = get_estimation_suffix()
|
30
|
-
closed_states = get_closed_states()
|
31
|
-
|
32
|
-
def render_macro(self, req, name, content):
|
33
|
-
db = self.env.get_db_cnx()
|
34
|
-
# prepare options
|
35
|
-
options, query_args = parse_options(db, content, copy.copy(DEFAULT_OPTIONS))
|
36
|
-
|
37
|
-
query_args[self.estimation_field + "!"] = None
|
38
|
-
tickets = execute_query(self.env, req, query_args)
|
39
|
-
|
40
|
-
sum = 0.0
|
41
|
-
estimations = {}
|
42
|
-
for ticket in tickets:
|
43
|
-
if ticket['status'] in self.closed_states:
|
44
|
-
continue
|
45
|
-
try:
|
46
|
-
estimation = float(ticket[self.estimation_field])
|
47
|
-
owner = ticket['owner']
|
48
|
-
sum += estimation
|
49
|
-
if estimations.has_key(owner):
|
50
|
-
estimations[owner] += estimation
|
51
|
-
else:
|
52
|
-
estimations[owner] = estimation
|
53
|
-
except:
|
54
|
-
pass
|
55
|
-
|
56
|
-
estimations_string = []
|
57
|
-
labels = []
|
58
|
-
for owner, estimation in estimations.iteritems():
|
59
|
-
labels.append("%s %s%s" % (owner, str(int(estimation)), self.estimation_suffix))
|
60
|
-
estimations_string.append(str(int(estimation)))
|
61
|
-
|
62
|
-
# Title
|
63
|
-
title = 'Workload'
|
64
|
-
|
65
|
-
# calculate remaining work time
|
66
|
-
if options.get('today') and options.get('enddate'):
|
67
|
-
currentdate = options['today']
|
68
|
-
day = timedelta(days=1)
|
69
|
-
days_remaining = 0
|
70
|
-
while currentdate <= options['enddate']:
|
71
|
-
if currentdate.weekday() < 5:
|
72
|
-
days_remaining += 1
|
73
|
-
currentdate += day
|
74
|
-
title += ' %s%s (%s workdays left)' % (int(sum), self.estimation_suffix, days_remaining)
|
75
|
-
|
76
|
-
return Markup("<img src=\"http://chart.apis.google.com/chart?"
|
77
|
-
"chs=%sx%s"
|
78
|
-
"&chf=bg,s,00000000"
|
79
|
-
"&chd=t:%s"
|
80
|
-
"&cht=p3"
|
81
|
-
"&chtt=%s"
|
82
|
-
"&chl=%s"
|
83
|
-
"&chco=%s\" "
|
84
|
-
"alt=\'Workload Chart\' />"
|
85
|
-
% (options['width'], options['height'], ",".join(estimations_string),
|
86
|
-
title, "|".join(labels), options['color']))
|
@@ -1,20 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python
|
2
|
-
# -*- coding: iso-8859-1 -*-
|
3
|
-
|
4
|
-
from setuptools import setup
|
5
|
-
|
6
|
-
setup(
|
7
|
-
name = 'EstimationTools',
|
8
|
-
author = 'Joachim Hoessler',
|
9
|
-
author_email = 'hoessler@gmail.com',
|
10
|
-
description = 'Trac plugin for visualizing and quick editing of effort estimations',
|
11
|
-
version = '0.4',
|
12
|
-
license='BSD',
|
13
|
-
packages=['estimationtools'],
|
14
|
-
package_data = { 'estimationtools': ['htdocs/*.js', 'templates/*.html'] },
|
15
|
-
entry_points = {
|
16
|
-
'trac.plugins': [
|
17
|
-
'estimationtools = estimationtools'
|
18
|
-
]
|
19
|
-
}
|
20
|
-
)
|
@@ -1,23 +0,0 @@
|
|
1
|
-
//javascript:(function(){var filter = function (fn, list, thisObj) { var arr = []; for (var i = 0; i < list.length; i++) { if (fn.call(thisObj, list[i])) { arr.push(list[i]);return arr;var sum = 0; var tds = filter(function(td){return td.innerHTML =='None';document.getElementsByTagName('td'),this); for(var i = 0; i < tds.length; i++){sum += parseFloat(tds[i].parentNode.childNodes[5].innerHTML);alert('Total hours: ' + sum);})();
|
2
|
-
javascript:(
|
3
|
-
function(){
|
4
|
-
var filter = function (fn, list, thisObj) {
|
5
|
-
var arr = [];
|
6
|
-
for (var i = 0; i < list.length; i++) {
|
7
|
-
if (fn.call(thisObj, list[i])) {
|
8
|
-
arr.push(list[i]);
|
9
|
-
}
|
10
|
-
}
|
11
|
-
return arr;
|
12
|
-
};
|
13
|
-
var sum = 0;
|
14
|
-
var tds = filter(function(td){
|
15
|
-
return td.innerHTML =='None';
|
16
|
-
},
|
17
|
-
document.getElementsByTagName('td'),this);
|
18
|
-
for(var i = 0; i < tds.length; i++){
|
19
|
-
sum += parseFloat(tds[i].parentNode.childNodes[5].innerHTML);
|
20
|
-
}
|
21
|
-
alert('Total hours: ' + sum);
|
22
|
-
}
|
23
|
-
)();
|
@@ -1,128 +0,0 @@
|
|
1
|
-
from pysqlite2 import dbapi2 as sqlite
|
2
|
-
from datetime import datetime, timedelta
|
3
|
-
from time import mktime
|
4
|
-
import os
|
5
|
-
|
6
|
-
tracDir = '/var/trac'
|
7
|
-
projectDBLocationFormat = '/var/trac/%s/db/trac.db'
|
8
|
-
# all directories in the trac directory
|
9
|
-
projects = [f for f in os.listdir(tracDir) if os.path.isdir('/'.join ([tracDir, f]))]
|
10
|
-
|
11
|
-
def makeDb(proj):
|
12
|
-
return projectDBLocationFormat % proj
|
13
|
-
|
14
|
-
def collectResultsFromAllTracs( sql ):
|
15
|
-
lst = []
|
16
|
-
for proj in projects:
|
17
|
-
try:
|
18
|
-
lst.extend([( proj , getResultSet( proj, sql ))])
|
19
|
-
except Exception, e:
|
20
|
-
print "collectResultsFromAllTracs: sql failed to execute on %s : %s " % (proj, e.args)
|
21
|
-
|
22
|
-
return lst
|
23
|
-
|
24
|
-
def executeAgainstAllTracs( sql ):
|
25
|
-
for proj in projects:
|
26
|
-
try:
|
27
|
-
executeNonQuery( proj, sql )
|
28
|
-
except:
|
29
|
-
print "executeAgainstAllTracs: sql failed to execute on %s" % proj
|
30
|
-
|
31
|
-
|
32
|
-
def executeNonQuery(proj, sql, *params):
|
33
|
-
"""Executes the query on the given project"""
|
34
|
-
con = sqlite.connect(makeDb(proj))
|
35
|
-
cur = con.cursor()
|
36
|
-
try:
|
37
|
-
cur.execute(sql, params)
|
38
|
-
con.commit()
|
39
|
-
finally:
|
40
|
-
cur.close()
|
41
|
-
con.close()
|
42
|
-
|
43
|
-
def getColumnAsList(db, sql, col=0, *params):
|
44
|
-
return [valueList[col] for valueList in get_all(db, sql, *params)[1]]
|
45
|
-
|
46
|
-
def getScalar(proj , sql, col=0, *params):
|
47
|
-
db = sqlite.connect(makeDb(proj))
|
48
|
-
cur = db.cursor()
|
49
|
-
try:
|
50
|
-
cur.execute(sql, params)
|
51
|
-
data = cur.fetchone()
|
52
|
-
finally:
|
53
|
-
cur.close()
|
54
|
-
return data[col]
|
55
|
-
|
56
|
-
|
57
|
-
def getVector(proj, sql, *params):
|
58
|
-
db = sqlite.connect(makeDb(proj))
|
59
|
-
cur = db.cursor()
|
60
|
-
try:
|
61
|
-
cur.execute(sql, params)
|
62
|
-
data = cur.fetchone()
|
63
|
-
finally:
|
64
|
-
cur.close()
|
65
|
-
return data
|
66
|
-
|
67
|
-
def getAll(proj, sql, *params):
|
68
|
-
"""Executes the query and returns the (description, data)"""
|
69
|
-
con = sqlite.connect(makeDb(proj))
|
70
|
-
cur = con.cursor()
|
71
|
-
try:
|
72
|
-
cur.execute(sql, params)
|
73
|
-
data = cur.fetchall()
|
74
|
-
desc = cur.description
|
75
|
-
finally:
|
76
|
-
cur.close()
|
77
|
-
con.close()
|
78
|
-
return (desc, data)
|
79
|
-
|
80
|
-
def getResultSet(proj, sql, *params):
|
81
|
-
"""Executes the query and returns a Result Set"""
|
82
|
-
return ResultSet(getAll(proj, sql, *params))
|
83
|
-
|
84
|
-
def _columnName( columnDescription ):
|
85
|
-
""" given a the columnHeader from the result set from getAll gives you the column Headers """
|
86
|
-
return columnDescription[0];
|
87
|
-
|
88
|
-
class ResultSet:
|
89
|
-
""" the result of calling getResultSet """
|
90
|
-
def __init__ (self, (columnDescription, rows)):
|
91
|
-
self.columnDescription, self.rows = columnDescription, rows
|
92
|
-
self.columnNames = [_columnName(_) for _ in self.columnDescription]
|
93
|
-
self.columnMap = self.getColumnMap()
|
94
|
-
|
95
|
-
def getColumnMap ( self ):
|
96
|
-
"""This function will take the result set from getAll and will
|
97
|
-
return a hash of the column names to their index """
|
98
|
-
h = {}
|
99
|
-
i = 0
|
100
|
-
if self.columnDescription:
|
101
|
-
for col in self.columnNames:
|
102
|
-
h[ col ] = i
|
103
|
-
i+=1
|
104
|
-
return h;
|
105
|
-
|
106
|
-
def value(self, col, row ):
|
107
|
-
""" given a row(list or idx) and a column( name or idx ), retrieve the appropriate value"""
|
108
|
-
tcol = type(col)
|
109
|
-
trow = type(row)
|
110
|
-
if tcol == str:
|
111
|
-
if(trow == list or trow == tuple):
|
112
|
-
return row[self.columnMap[col]]
|
113
|
-
elif(trow == int):
|
114
|
-
return self.rows[row][self.columnMap[col]]
|
115
|
-
else:
|
116
|
-
print ("rs.value Type Failed col:%s row:%s" % (type(col), type(row)))
|
117
|
-
elif tcol == int:
|
118
|
-
if(trow == list or trow == tuple):
|
119
|
-
return row[col]
|
120
|
-
elif(trow == int):
|
121
|
-
return self.rows[row][col]
|
122
|
-
else:
|
123
|
-
print ("rs.value Type Failed col:%s row:%s" % (type(col), type(row)))
|
124
|
-
else:
|
125
|
-
print ("rs.value Type Failed col:%s row:%s" % (type(col), type(row)))
|
126
|
-
|
127
|
-
|
128
|
-
|
@@ -1,40 +0,0 @@
|
|
1
|
-
#!/bin/sh
|
2
|
-
#
|
3
|
-
# An example hook script for the post-receive event
|
4
|
-
#
|
5
|
-
# This script is run after receive-pack has accepted a pack and the
|
6
|
-
# repository has been updated. It is passed arguments in through stdin
|
7
|
-
# in the form
|
8
|
-
# <oldrev> <newrev> <refname>
|
9
|
-
# For example:
|
10
|
-
# aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
|
11
|
-
#
|
12
|
-
# see contrib/hooks/ for an sample, or uncomment the next line (on debian)
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
TRAC_ENV="YOUR TRAC ENV HERE"
|
17
|
-
LOG="/dev/null"
|
18
|
-
echo "in git post commit: $TRAC_ENV" | cat >>$LOG
|
19
|
-
|
20
|
-
while read oval nval ref ; do
|
21
|
-
if expr "$oval" : '0*$' >/dev/null
|
22
|
-
then
|
23
|
-
git-rev-list "$nval"
|
24
|
-
else
|
25
|
-
git-rev-list "$nval" "^$oval"
|
26
|
-
fi | while read com ; do
|
27
|
-
echo "posting a comment to trac" | cat >>$LOG
|
28
|
-
/usr/bin/python /usr/share/trac/contrib/trac-post-commit.py \
|
29
|
-
-p "$TRAC_ENV" \
|
30
|
-
-r "$com" \
|
31
|
-
-u "$(git-rev-list -n 1 $com --pretty=format:%an | sed '1d')" \
|
32
|
-
-m "$(git-rev-list -n 1 $com --pretty=medium | sed '1,3d;s:^ ::')"
|
33
|
-
echo "DONE posting a comment to trac" | cat >>$LOG
|
34
|
-
done
|
35
|
-
done
|
36
|
-
|
37
|
-
echo "Done with trac commit hook: $TRAC_ENV" | cat >>$LOG
|
38
|
-
|
39
|
-
git reset --hard
|
40
|
-
echo "resetting repo working copy" | cat >>$LOG
|
@@ -1,285 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python
|
2
|
-
|
3
|
-
# trac-post-commit-hook
|
4
|
-
# ----------------------------------------------------------------------------
|
5
|
-
# Copyright (c) 2004 Stephen Hansen
|
6
|
-
#
|
7
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
-
# of this software and associated documentation files (the "Software"), to
|
9
|
-
# deal in the Software without restriction, including without limitation the
|
10
|
-
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
11
|
-
# sell copies of the Software, and to permit persons to whom the Software is
|
12
|
-
# furnished to do so, subject to the following conditions:
|
13
|
-
#
|
14
|
-
# The above copyright notice and this permission notice shall be included in
|
15
|
-
# all copies or substantial portions of the Software.
|
16
|
-
#
|
17
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
20
|
-
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
22
|
-
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
23
|
-
# IN THE SOFTWARE.
|
24
|
-
# ----------------------------------------------------------------------------
|
25
|
-
|
26
|
-
### Changes for the Timing and Estimation plugin
|
27
|
-
#
|
28
|
-
# This script is very similar to "trac-post-commit" included with trac
|
29
|
-
# itself. This section explains functional changes relative to that
|
30
|
-
# script, and comments throughout the code explain other differences.
|
31
|
-
#
|
32
|
-
## Logging support for debugging this hook
|
33
|
-
#
|
34
|
-
## Support for specifying time spent in commit messages.
|
35
|
-
#
|
36
|
-
# "Blah refs #12 (1)" will add 1h to the spent time for issue #12
|
37
|
-
# "Blah refs #12 (spent 1.5)" will add 1h to the spent time for issue #12
|
38
|
-
#
|
39
|
-
# As above it is possible to use complicated messages:
|
40
|
-
#
|
41
|
-
# "Changed blah and foo to do this or that. Fixes #10 (1) and #12 (2),
|
42
|
-
# and refs #13 (0.5)."
|
43
|
-
#
|
44
|
-
# This will close #10 and #12, and add a note to #13 and also add 1h
|
45
|
-
# spent time to #10, add 2h spent time to #12 and add 30m spent time
|
46
|
-
# to #13.
|
47
|
-
#
|
48
|
-
# Note that:
|
49
|
-
# (spent 2), (sp 2) or simply (2) may be used for spent
|
50
|
-
# ' ', ',', '&' or 'and' may be used references
|
51
|
-
|
52
|
-
# This Subversion post-commit hook script is meant to interface to the
|
53
|
-
# Trac (http://www.edgewall.com/products/trac/) issue tracking/wiki/etc
|
54
|
-
# system.
|
55
|
-
#
|
56
|
-
# It should be called from the 'post-commit' script in Subversion, such as
|
57
|
-
# via:
|
58
|
-
#
|
59
|
-
# REPOS="$1"
|
60
|
-
# REV="$2"
|
61
|
-
# TRAC_ENV="/path/to/tracenv"
|
62
|
-
#
|
63
|
-
# /usr/bin/python /usr/local/src/trac/contrib/trac-post-commit-hook \
|
64
|
-
# -p "$TRAC_ENV" -r "$REV"
|
65
|
-
#
|
66
|
-
# (all the other arguments are now deprecated and not needed anymore)
|
67
|
-
#
|
68
|
-
# It searches commit messages for text in the form of:
|
69
|
-
# command #1
|
70
|
-
# command #1, #2
|
71
|
-
# command #1 & #2
|
72
|
-
# command #1 and #2
|
73
|
-
#
|
74
|
-
# Instead of the short-hand syntax "#1", "ticket:1" can be used as well, e.g.:
|
75
|
-
# command ticket:1
|
76
|
-
# command ticket:1, ticket:2
|
77
|
-
# command ticket:1 & ticket:2
|
78
|
-
# command ticket:1 and ticket:2
|
79
|
-
#
|
80
|
-
# In addition, the ':' character can be omitted and issue or bug can be used
|
81
|
-
# instead of ticket.
|
82
|
-
#
|
83
|
-
# You can have more then one command in a message. The following commands
|
84
|
-
# are supported. There is more then one spelling for each command, to make
|
85
|
-
# this as user-friendly as possible.
|
86
|
-
#
|
87
|
-
# close, closed, closes, fix, fixed, fixes
|
88
|
-
# The specified issue numbers are closed with the contents of this
|
89
|
-
# commit message being added to it.
|
90
|
-
# references, refs, addresses, re, see
|
91
|
-
# The specified issue numbers are left in their current status, but
|
92
|
-
# the contents of this commit message are added to their notes.
|
93
|
-
#
|
94
|
-
# A fairly complicated example of what you can do is with a commit message
|
95
|
-
# of:
|
96
|
-
#
|
97
|
-
# Changed blah and foo to do this or that. Fixes #10 and #12, and refs #12.
|
98
|
-
#
|
99
|
-
# This will close #10 and #12, and add a note to #12.
|
100
|
-
|
101
|
-
import re
|
102
|
-
import os
|
103
|
-
import sys
|
104
|
-
from datetime import datetime
|
105
|
-
from optparse import OptionParser
|
106
|
-
|
107
|
-
parser = OptionParser()
|
108
|
-
depr = '(not used anymore)'
|
109
|
-
parser.add_option('-e', '--require-envelope', dest='envelope', default='',
|
110
|
-
help="""
|
111
|
-
Require commands to be enclosed in an envelope.
|
112
|
-
If -e[], then commands must be in the form of [closes #4].
|
113
|
-
Must be two characters.""")
|
114
|
-
parser.add_option('-p', '--project', dest='project',
|
115
|
-
help='Path to the Trac project.')
|
116
|
-
parser.add_option('-r', '--revision', dest='rev',
|
117
|
-
help='Repository revision number.')
|
118
|
-
parser.add_option('-u', '--user', dest='user',
|
119
|
-
help='The user who is responsible for this action '+depr)
|
120
|
-
parser.add_option('-m', '--msg', dest='msg',
|
121
|
-
help='The log message to search '+depr)
|
122
|
-
parser.add_option('-c', '--encoding', dest='encoding',
|
123
|
-
help='The encoding used by the log message '+depr)
|
124
|
-
parser.add_option('-s', '--siteurl', dest='url',
|
125
|
-
help=depr+' the base_url from trac.ini will always be used.')
|
126
|
-
|
127
|
-
(options, args) = parser.parse_args(sys.argv[1:])
|
128
|
-
|
129
|
-
if not 'PYTHON_EGG_CACHE' in os.environ:
|
130
|
-
os.environ['PYTHON_EGG_CACHE'] = os.path.join(options.project, '.egg-cache')
|
131
|
-
|
132
|
-
from trac.env import open_environment
|
133
|
-
from trac.ticket.notification import TicketNotifyEmail
|
134
|
-
from trac.ticket import Ticket
|
135
|
-
from trac.ticket.web_ui import TicketModule
|
136
|
-
# TODO: move grouped_changelog_entries to model.py
|
137
|
-
from trac.util.text import to_unicode
|
138
|
-
from trac.util.datefmt import utc
|
139
|
-
from trac.versioncontrol.api import NoSuchChangeset
|
140
|
-
|
141
|
-
# Change logfile to point to someplace this script can write.
|
142
|
-
logfile = "/var/trac/commithook.log"
|
143
|
-
LOG = False
|
144
|
-
|
145
|
-
if LOG:
|
146
|
-
f = open (logfile,"w")
|
147
|
-
f.write("Begin Log\n")
|
148
|
-
f.close()
|
149
|
-
def log (s, *params):
|
150
|
-
f = open (logfile,"a")
|
151
|
-
f.write(s % params)
|
152
|
-
f.write("\n")
|
153
|
-
f.close()
|
154
|
-
else:
|
155
|
-
def log (s, *params):
|
156
|
-
pass
|
157
|
-
|
158
|
-
# Relative to trac standard, this table is hoisted out of class
|
159
|
-
# CommitHook so that it can be used in constructing a regexp that only
|
160
|
-
# matches on supported commands.
|
161
|
-
_supported_cmds = {'close': '_cmdClose',
|
162
|
-
'closed': '_cmdClose',
|
163
|
-
'closes': '_cmdClose',
|
164
|
-
'fix': '_cmdClose',
|
165
|
-
'fixed': '_cmdClose',
|
166
|
-
'fixes': '_cmdClose',
|
167
|
-
'addresses': '_cmdRefs',
|
168
|
-
're': '_cmdRefs',
|
169
|
-
'references': '_cmdRefs',
|
170
|
-
'refs': '_cmdRefs',
|
171
|
-
'see': '_cmdRefs'}
|
172
|
-
|
173
|
-
# Regexps are extended to include "(1)" and "(spent 1)".
|
174
|
-
ticket_prefix = '(?:#|(?:ticket|issue|bug)[: ]?)'
|
175
|
-
time_pattern = r'[ ]?(?:\((?:(?:spent|sp)[ ]?)?(-?[0-9]*(?:\.[0-9]+)?)\))?'
|
176
|
-
ticket_reference = ticket_prefix + '[0-9]+' + time_pattern
|
177
|
-
support_cmds_pattern = '|'.join(_supported_cmds.keys())
|
178
|
-
|
179
|
-
# Relative to upstream, only match command tokens (rather than
|
180
|
-
# matching all words).
|
181
|
-
ticket_command = (r'(?P<action>(?:%s))[ ]*'
|
182
|
-
'(?P<ticket>%s(?:(?:[, &]*|[ ]?and[ ]?)%s)*)' %
|
183
|
-
(support_cmds_pattern, ticket_reference, ticket_reference))
|
184
|
-
|
185
|
-
if options.envelope:
|
186
|
-
ticket_command = r'\%s%s\%s' % (options.envelope[0], ticket_command,
|
187
|
-
options.envelope[1])
|
188
|
-
|
189
|
-
# Because we build the regexp to recognize only supported commands,
|
190
|
-
# ignore case here.
|
191
|
-
command_re = re.compile(ticket_command, re.IGNORECASE)
|
192
|
-
ticket_re = re.compile(ticket_prefix + '([0-9]+)' + time_pattern, re.IGNORECASE)
|
193
|
-
|
194
|
-
class CommitHook:
|
195
|
-
def __init__(self, project=options.project, author=options.user,
|
196
|
-
rev=options.rev, url=options.url):
|
197
|
-
self.env = open_environment(project)
|
198
|
-
repos = self.env.get_repository()
|
199
|
-
repos.sync()
|
200
|
-
|
201
|
-
# Instead of bothering with the encoding, we'll use unicode data
|
202
|
-
# as provided by the Trac versioncontrol API (#1310).
|
203
|
-
try:
|
204
|
-
chgset = repos.get_changeset(rev)
|
205
|
-
except NoSuchChangeset:
|
206
|
-
return # out of scope changesets are not cached
|
207
|
-
self.author = chgset.author
|
208
|
-
self.rev = rev
|
209
|
-
self.msg = "(In [%s]) %s" % (rev, chgset.message)
|
210
|
-
self.now = datetime.now(utc)
|
211
|
-
|
212
|
-
cmd_groups = command_re.findall(self.msg)
|
213
|
-
|
214
|
-
log ("cmd_groups:%s", cmd_groups)
|
215
|
-
tickets = {}
|
216
|
-
# \todo Explain what xxx1 and xxx2 do; I can't see more params
|
217
|
-
# in command_re.
|
218
|
-
for cmd, tkts, xxx1, xxx2 in cmd_groups:
|
219
|
-
log ("cmd:%s, tkts%s ", cmd, tkts)
|
220
|
-
funcname = _supported_cmds.get(cmd.lower(), '')
|
221
|
-
if funcname:
|
222
|
-
for tkt_id, spent in ticket_re.findall(tkts):
|
223
|
-
func = getattr(self, funcname)
|
224
|
-
tickets.setdefault(tkt_id, []).append([func, spent])
|
225
|
-
|
226
|
-
for tkt_id, vals in tickets.iteritems():
|
227
|
-
log ("tkt_id:%s, vals%s ", tkt_id, vals)
|
228
|
-
spent_total = 0.0
|
229
|
-
try:
|
230
|
-
db = self.env.get_db_cnx()
|
231
|
-
|
232
|
-
ticket = Ticket(self.env, int(tkt_id), db)
|
233
|
-
for (cmd, spent) in vals:
|
234
|
-
cmd(ticket)
|
235
|
-
if spent:
|
236
|
-
spent_total += float(spent)
|
237
|
-
|
238
|
-
# determine sequence number...
|
239
|
-
cnum = 0
|
240
|
-
tm = TicketModule(self.env)
|
241
|
-
for change in tm.grouped_changelog_entries(ticket, db):
|
242
|
-
if change['permanent']:
|
243
|
-
cnum += 1
|
244
|
-
|
245
|
-
if spent_total:
|
246
|
-
self._setTimeTrackerFields(ticket, spent_total)
|
247
|
-
ticket.save_changes(self.author, self.msg, self.now, db, cnum+1)
|
248
|
-
db.commit()
|
249
|
-
|
250
|
-
tn = TicketNotifyEmail(self.env)
|
251
|
-
tn.notify(ticket, newticket=0, modtime=self.now)
|
252
|
-
except Exception, e:
|
253
|
-
# import traceback
|
254
|
-
# traceback.print_exc(file=sys.stderr)
|
255
|
-
log('Unexpected error while processing ticket ' \
|
256
|
-
'ID %s: %s' % (tkt_id, e))
|
257
|
-
print>>sys.stderr, 'Unexpected error while processing ticket ' \
|
258
|
-
'ID %s: %s' % (tkt_id, e)
|
259
|
-
|
260
|
-
|
261
|
-
def _cmdClose(self, ticket):
|
262
|
-
ticket['status'] = 'closed'
|
263
|
-
ticket['resolution'] = 'fixed'
|
264
|
-
|
265
|
-
def _cmdRefs(self, ticket):
|
266
|
-
pass
|
267
|
-
|
268
|
-
def _setTimeTrackerFields(self, ticket, spent):
|
269
|
-
log ("Setting ticket:%s spent: %s", ticket, spent)
|
270
|
-
if (spent != ''):
|
271
|
-
spentTime = float(spent)
|
272
|
-
# \bug If the ticket has not been modified since
|
273
|
-
# TimingAndEstimation was installed, then it might not
|
274
|
-
# have hours. It should still get hours applied because
|
275
|
-
# estimating and recording are separate.
|
276
|
-
if (ticket.values.has_key('hours')):
|
277
|
-
ticket['hours'] = str(spentTime)
|
278
|
-
|
279
|
-
if __name__ == "__main__":
|
280
|
-
if len(sys.argv) < 5:
|
281
|
-
print "For usage: %s --help" % (sys.argv[0])
|
282
|
-
print
|
283
|
-
print "Note that the deprecated options will be removed in Trac 0.12."
|
284
|
-
else:
|
285
|
-
CommitHook()
|