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.
Files changed (113) hide show
  1. data/VERSION.yml +1 -1
  2. data/bin/subtrac +2 -0
  3. data/lib/subtrac.rb +85 -50
  4. data/lib/subtrac/config/config.yml +22 -19
  5. data/lib/subtrac/templates/location.erb +2 -2
  6. data/lib/subtrac/templates/projects/blank/trac/wiki/WikiStart +1 -1
  7. data/lib/subtrac/templates/trac.erb +1 -1
  8. data/lib/subtrac/templates/vhost.erb +6 -6
  9. metadata +1 -105
  10. data/lib/subtrac/trac-plugins/advancedticketworkflowplugin/advancedworkflow/__init__.py +0 -0
  11. data/lib/subtrac/trac-plugins/advancedticketworkflowplugin/advancedworkflow/controller.py +0 -419
  12. data/lib/subtrac/trac-plugins/advancedticketworkflowplugin/setup.cfg +0 -3
  13. data/lib/subtrac/trac-plugins/advancedticketworkflowplugin/setup.py +0 -20
  14. data/lib/subtrac/trac-plugins/clientsplugin/clients/__init__.py +0 -0
  15. data/lib/subtrac/trac-plugins/clientsplugin/clients/action.py +0 -28
  16. data/lib/subtrac/trac-plugins/clientsplugin/clients/action_email.py +0 -168
  17. data/lib/subtrac/trac-plugins/clientsplugin/clients/action_zendesk_forum.py +0 -137
  18. data/lib/subtrac/trac-plugins/clientsplugin/clients/admin.py +0 -91
  19. data/lib/subtrac/trac-plugins/clientsplugin/clients/api.py +0 -199
  20. data/lib/subtrac/trac-plugins/clientsplugin/clients/client.py +0 -105
  21. data/lib/subtrac/trac-plugins/clientsplugin/clients/events.py +0 -287
  22. data/lib/subtrac/trac-plugins/clientsplugin/clients/eventsadmin.py +0 -71
  23. data/lib/subtrac/trac-plugins/clientsplugin/clients/htdocs/clients.css +0 -4
  24. data/lib/subtrac/trac-plugins/clientsplugin/clients/model.py +0 -135
  25. data/lib/subtrac/trac-plugins/clientsplugin/clients/processor.py +0 -70
  26. data/lib/subtrac/trac-plugins/clientsplugin/clients/reportmanager.py +0 -142
  27. data/lib/subtrac/trac-plugins/clientsplugin/clients/reports.py +0 -231
  28. data/lib/subtrac/trac-plugins/clientsplugin/clients/summary.py +0 -27
  29. data/lib/subtrac/trac-plugins/clientsplugin/clients/summary_milestone.py +0 -152
  30. data/lib/subtrac/trac-plugins/clientsplugin/clients/summary_ticketchanges.py +0 -160
  31. data/lib/subtrac/trac-plugins/clientsplugin/clients/templates/admin_client_events.html +0 -124
  32. data/lib/subtrac/trac-plugins/clientsplugin/clients/templates/admin_clients.html +0 -134
  33. data/lib/subtrac/trac-plugins/clientsplugin/cron/changes.xslt +0 -132
  34. data/lib/subtrac/trac-plugins/clientsplugin/cron/run-client-event +0 -97
  35. data/lib/subtrac/trac-plugins/clientsplugin/cron/summary.xslt +0 -161
  36. data/lib/subtrac/trac-plugins/clientsplugin/setup.py +0 -43
  37. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/__init__.py +0 -4
  38. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/burndownchart.py +0 -273
  39. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/hoursinplaceeditor.py +0 -44
  40. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/hoursremaining.py +0 -36
  41. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/htdocs/jquery-1.2.3.min.js +0 -32
  42. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/htdocs/jquery.jeditable.js +0 -409
  43. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/htdocs/jquery.jeditable.mini.js +0 -30
  44. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/templates/edithours.html +0 -53
  45. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/tests/burndownchart.py +0 -181
  46. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/tests/hoursremaining.py +0 -66
  47. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/tests/workloadchart.py +0 -47
  48. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/utils.py +0 -93
  49. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/workloadchart.py +0 -86
  50. data/lib/subtrac/trac-plugins/estimationtoolsplugin/setup.py +0 -20
  51. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/SumRollups.js +0 -23
  52. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/adw_tracdb.py +0 -128
  53. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/git-post-receive +0 -40
  54. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/trac-post-commit.py +0 -285
  55. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/trac_billing.py +0 -173
  56. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/utils/__init__.py +0 -0
  57. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/utils/mail.py +0 -164
  58. data/lib/subtrac/trac-plugins/timingandestimationplugin/setup.py +0 -69
  59. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/__init__.py +0 -1
  60. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/api.py +0 -292
  61. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/blackmagic.py +0 -172
  62. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/dbhelper.py +0 -178
  63. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/billingplugin.css +0 -25
  64. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/field_disabler.js +0 -6
  65. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/formatDate.js +0 -356
  66. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/js/tip_centerwindow.js +0 -100
  67. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/js/tip_followscroll.js +0 -84
  68. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/js/wz_tooltip.js +0 -1149
  69. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/linkifyer.js +0 -119
  70. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/query.js +0 -73
  71. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/ticket.js +0 -165
  72. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/query_webui.py +0 -28
  73. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/reportmanager.py +0 -221
  74. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/reports.py +0 -675
  75. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/reports_filter.py +0 -150
  76. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/statuses.py +0 -25
  77. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/tande_filters.py +0 -131
  78. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/templates/billing.cs +0 -84
  79. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/templates/billing.html +0 -104
  80. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/ticket_daemon.py +0 -194
  81. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/ticket_policy.py +0 -62
  82. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/ticket_webui.py +0 -28
  83. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/usermanual.py +0 -127
  84. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/webui.py +0 -129
  85. data/lib/subtrac/trac-plugins/worklogplugin/setup.py +0 -29
  86. data/lib/subtrac/trac-plugins/worklogplugin/worklog/__init__.py +0 -1
  87. data/lib/subtrac/trac-plugins/worklogplugin/worklog/api.py +0 -187
  88. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/jqModal.css +0 -40
  89. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/jqModal.js +0 -67
  90. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/jquery.mousewheel.pack.js +0 -12
  91. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/jquery.timeentry.pack.js +0 -7
  92. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/tracWorklog.js +0 -40
  93. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/ui.datepicker.css +0 -208
  94. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/ui.datepicker.js +0 -1439
  95. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/work.png +0 -0
  96. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/work.xcf +0 -0
  97. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/worklogplugin.css +0 -80
  98. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/workstart.png +0 -0
  99. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/workstop.png +0 -0
  100. data/lib/subtrac/trac-plugins/worklogplugin/worklog/manager.py +0 -336
  101. data/lib/subtrac/trac-plugins/worklogplugin/worklog/reports.py +0 -598
  102. data/lib/subtrac/trac-plugins/worklogplugin/worklog/templates/worklog.html +0 -45
  103. data/lib/subtrac/trac-plugins/worklogplugin/worklog/templates/worklog_stop.html +0 -70
  104. data/lib/subtrac/trac-plugins/worklogplugin/worklog/templates/worklog_user.html +0 -40
  105. data/lib/subtrac/trac-plugins/worklogplugin/worklog/templates/worklog_webadminui.html +0 -59
  106. data/lib/subtrac/trac-plugins/worklogplugin/worklog/ticket_daemon.py +0 -33
  107. data/lib/subtrac/trac-plugins/worklogplugin/worklog/ticket_filter.py +0 -153
  108. data/lib/subtrac/trac-plugins/worklogplugin/worklog/timeline_hook.py +0 -96
  109. data/lib/subtrac/trac-plugins/worklogplugin/worklog/usermanual.py +0 -29
  110. data/lib/subtrac/trac-plugins/worklogplugin/worklog/util.py +0 -31
  111. data/lib/subtrac/trac-plugins/worklogplugin/worklog/webadminui.py +0 -47
  112. data/lib/subtrac/trac-plugins/worklogplugin/worklog/webui.py +0 -174
  113. data/lib/subtrac/trac-plugins/worklogplugin/worklog/xmlrpc.py +0 -73
@@ -1,105 +0,0 @@
1
- from trac.core import *
2
- from trac.web.chrome import add_stylesheet, ITemplateProvider
3
- from trac.web.api import IRequestFilter, ITemplateStreamFilter
4
- from trac.ticket.api import ITicketManipulator
5
- from trac.ticket.model import Ticket
6
- from trac.util.html import html, Markup
7
-
8
- from genshi.core import Markup
9
- from genshi.builder import tag
10
- from genshi.filters.transform import Transformer
11
-
12
- from clients import model
13
- from StringIO import StringIO
14
-
15
- class ClientModule(Component):
16
- """Allows for tickets to be assigned to particular clients."""
17
-
18
- implements(IRequestFilter, ITemplateStreamFilter, ITemplateProvider)
19
-
20
- # IRequestFilter methods
21
- def pre_process_request(self, req, handler):
22
- # Add Stylesheet here, so that the ticket page gets it too :)
23
- add_stylesheet(req, "clients/clients.css")
24
- return handler
25
-
26
- def post_process_request(self, req, template, data, content_type):
27
- # Some ticket views do not actually load the data in this way
28
- # e.g. action=history or action=diff
29
- if not data or not data.has_key('fields'):
30
- return template, data, content_type
31
-
32
- newticket = req.path_info.startswith('/newticket')
33
- if req.path_info.startswith('/ticket/') or newticket:
34
- for field in data['fields']:
35
- if 'client' == field['name']:
36
- field['type'] = 'select'
37
- field['options'] = []
38
- for client in model.Client.select(self.env):
39
- field['options'].append(client.name)
40
- if newticket:
41
- default_client = self.config.get('ticket', 'default_client')
42
- if default_client:
43
- data['ticket']['client'] = default_client
44
- break;
45
- elif req.path_info.startswith('/query'):
46
- if data['fields'].has_key('client'):
47
- data['fields']['client']['type'] = 'select'
48
- data['fields']['client']['options'] = []
49
- for client in model.Client.select(self.env):
50
- data['fields']['client']['options'].append(client.name)
51
- return template, data, content_type
52
-
53
- # ITemplateStreamFilter methods
54
- def filter_stream(self, req, method, filename, stream, data):
55
- newticket = req.path_info.startswith('/newticket')
56
- if req.path_info.startswith('/ticket/') or newticket:
57
- setdefaultrate = ''
58
- if newticket:
59
- setdefaultrate = "$('#field-client').trigger('change');"
60
-
61
- script = StringIO()
62
- script.write("""
63
- $(document).ready(function() {
64
- $('#field-client').change(function() {
65
- """);
66
- script.write('var clientrates = new Array();')
67
- for client in model.Client.select(self.env):
68
- script.write('clientrates["%s"] = %s;' % (client.name, client.default_rate or '""'))
69
- script.write("""
70
- try { $('#field-clientrate').attr('value', clientrates[this.options[this.selectedIndex].value]); }
71
- catch (er) { }
72
- });
73
- %s
74
- });""" % setdefaultrate);
75
- stream |= Transformer('.//head').append(tag.script(script.getvalue(), type_='text/javascript'))
76
- return stream
77
-
78
- # ITemplateProvider
79
- def get_htdocs_dirs(self):
80
- """Return the absolute path of a directory containing additional
81
- static resources (such as images, style sheets, etc).
82
- """
83
- from pkg_resources import resource_filename
84
- return [('clients', resource_filename(__name__, 'htdocs'))]
85
-
86
- def get_templates_dirs(self):
87
- """Return the absolute path of the directory containing the provided
88
- ClearSilver templates.
89
- """
90
- from pkg_resources import resource_filename
91
- return [resource_filename(__name__, 'templates')]
92
-
93
- # ITicketManipulator methods
94
- def prepare_ticket(self, req, ticket, fields, actions):
95
- pass
96
-
97
- def validate_ticket(self, req, ticket):
98
- # Todo validate client is valid
99
- pass
100
- #if req.args.get('action') == 'resolve':
101
- # links = TicketLinks(self.env, ticket)
102
- # for i in links.blocked_by:
103
- # if Ticket(self.env, i)['status'] != 'closed':
104
- # yield None, 'Ticket #%s is blocking this ticket'%i
105
-
@@ -1,287 +0,0 @@
1
- import md5
2
- import sys
3
- import time
4
-
5
- from trac.core import *
6
-
7
- from clients.summary import IClientSummaryProvider
8
- from clients.action import IClientActionProvider
9
-
10
-
11
-
12
- __all__ = ['ClientEvent']
13
-
14
- def simplify_whitespace(name):
15
- """Strip spaces and remove duplicate spaces within names"""
16
- return ' '.join(name.split())
17
-
18
- class ClientEventsSystem(Component):
19
- summaries = ExtensionPoint(IClientSummaryProvider)
20
- actions = ExtensionPoint(IClientActionProvider)
21
-
22
- def get_summaries(self):
23
- for summary in self.summaries:
24
- yield summary.get_name()
25
-
26
- def get_summary(self, name):
27
- for summary in self.summaries:
28
- if name == summary.get_name():
29
- return summary
30
- return None
31
-
32
- def get_actions(self):
33
- for action in self.actions:
34
- yield action.get_name()
35
-
36
- def get_action(self, name):
37
- for action in self.actions:
38
- if name == action.get_name():
39
- return action
40
- return None
41
-
42
- class ClientEvent(object):
43
-
44
- def __init__(self, env, name=None, client=None, db=None):
45
- self.env = env
46
- if name:
47
- name = simplify_whitespace(name)
48
- if name:
49
- if not db:
50
- db = self.env.get_db_cnx()
51
- cursor = db.cursor()
52
- cursor.execute("SELECT summary, action, lastrun "
53
- "FROM client_events "
54
- "WHERE name=%s", (name,))
55
- row = cursor.fetchone()
56
- if not row:
57
- raise TracError('Client Event %s does not exist.' % name)
58
- self.md5 = md5.new(name).hexdigest()
59
- self.name = self._old_name = name
60
- self.summary = row[0] or ''
61
- self.action = row[1] or ''
62
- self.lastrun = row[2] or 0
63
- self._load_options(client, db)
64
- else:
65
- self.name = self._old_name = None
66
- self.summary = ''
67
- self.action = ''
68
- self.lastrun = 0
69
-
70
-
71
- exists = property(fget=lambda self: self._old_name is not None)
72
-
73
-
74
- def delete(self, db=None):
75
- assert self.exists, 'Cannot deleting non-existent client event'
76
- if not db:
77
- db = self.env.get_db_cnx()
78
- handle_ta = True
79
- else:
80
- handle_ta = False
81
-
82
- cursor = db.cursor()
83
- self.env.log.info('Deleting client event %s' % self.name)
84
- cursor.execute("DELETE FROM client_events WHERE name=%s", (self.name,))
85
-
86
- self.name = self._old_name = None
87
-
88
- if handle_ta:
89
- db.commit()
90
-
91
- def insert(self, db=None):
92
- assert not self.exists, 'Cannot insert existing client event'
93
- system = ClientEventsSystem(self.env);
94
- assert system.get_summary(self.summary) is not None , 'Invalid summary'
95
- assert system.get_action(self.action) is not None, 'Invalid action'
96
- self.name = simplify_whitespace(self.name)
97
- assert self.name, 'Cannot create client event with no name'
98
- if not db:
99
- db = self.env.get_db_cnx()
100
- handle_ta = True
101
- else:
102
- handle_ta = False
103
-
104
- # Todo: verify client_event with that name does not currently exist...
105
- cursor = db.cursor()
106
- self.env.log.debug("Creating new client event '%s'" % self.name)
107
- cursor.execute("INSERT INTO client_events (name,summary,action,lastrun) "
108
- "VALUES (%s,%s,%s,%s)",
109
- (self.name, self.summary, self.action, int(time.time())))
110
-
111
- if handle_ta:
112
- db.commit()
113
-
114
- def _load_client_options(self, client, opttype, db):
115
- assert self.exists, 'Cannot update non-existent client event'
116
- assert opttype in ('summary', 'action'), 'Invalid options type'
117
- system = ClientEventsSystem(self.env);
118
- if 'summary' == opttype:
119
- thing = system.get_summary(self.summary)
120
- assert thing is not None , 'Invalid summary'
121
- self.summary_description = thing.get_description()
122
- else:
123
- thing = system.get_action(self.action)
124
- assert thing is not None, 'Invalid action'
125
- self.action_description = thing.get_description()
126
-
127
- options = {}
128
- table = 'client_event_' + opttype + '_options'
129
- cursor = db.cursor()
130
- cursor.execute("SELECT name, value "
131
- "FROM " + table + " "
132
- "WHERE client_event=%s AND client=%s",
133
- (self._old_name, client or ''))
134
- for name, value in cursor:
135
- options[name] = value
136
- rv = {}
137
- for option in thing.options(client):
138
- option['md5'] = md5.new(option['name']).hexdigest()
139
- if options.has_key(option['name']):
140
- option['value'] = options[option['name']]
141
- else:
142
- option['value'] = ''
143
- rv[option['name']] = option
144
- return rv
145
-
146
-
147
- def _load_options(self, client, db):
148
- self.summary_options = self._load_client_options(None, 'summary', db)
149
- self.action_options = self._load_client_options(None, 'action', db)
150
- if client:
151
- self.summary_client_options = self._load_client_options(client, 'summary', db)
152
- self.action_client_options = self._load_client_options(client, 'action', db)
153
-
154
-
155
- def _update_client_options(self, client, opttype, options, db=None):
156
- assert self.exists, 'Cannot update non-existent client event'
157
- assert opttype in ('summary', 'action'), 'Invalid options type'
158
- system = ClientEventsSystem(self.env);
159
- if 'summary' == opttype:
160
- thing = system.get_summary(self.summary)
161
- assert thing is not None , 'Invalid summary'
162
- else:
163
- thing = system.get_action(self.action)
164
- assert thing is not None, 'Invalid action'
165
-
166
- if not db:
167
- db = self.env.get_db_cnx()
168
- handle_ta = True
169
- else:
170
- handle_ta = False
171
-
172
- table = 'client_event_' + opttype + '_options'
173
- cursor = db.cursor()
174
- self.env.log.info('Updating client event "%s"' % self._old_name)
175
- cursor.execute("DELETE FROM " + table + " "
176
- "WHERE client_event=%s AND client=%s",
177
- (self._old_name, client or ''))
178
-
179
- valid_options = []
180
- for option in thing.options(client):
181
- valid_options.append(option['name'])
182
- for option in options.values():
183
- if option['name'] in valid_options:
184
- cursor.execute("INSERT INTO " + table + " (client_event, client, name, value) "
185
- "VALUES (%s, %s, %s, %s)",
186
- (self._old_name, client or '', option['name'], option['value']))
187
-
188
- if handle_ta:
189
- db.commit()
190
-
191
-
192
- def update_options(self, client=None, db=None):
193
- assert self.exists, 'Cannot update non-existent client event'
194
- if not db:
195
- db = self.env.get_db_cnx()
196
- handle_ta = True
197
- else:
198
- handle_ta = False
199
-
200
- if client:
201
- self._update_client_options(client, 'summary', self.summary_client_options, db)
202
- self._update_client_options(client, 'action', self.action_client_options, db)
203
- else:
204
- self._update_client_options(None, 'summary', self.summary_options, db)
205
- self._update_client_options(None, 'action', self.action_options, db)
206
-
207
- if handle_ta:
208
- db.commit()
209
-
210
-
211
- def update(self, db=None):
212
- assert self.exists, 'Cannot update non-existent client event'
213
- self.name = simplify_whitespace(self.name)
214
- assert self.name, 'Cannot update client event with no name'
215
- if not db:
216
- db = self.env.get_db_cnx()
217
- handle_ta = True
218
- else:
219
- handle_ta = False
220
-
221
- cursor = db.cursor()
222
- self.env.log.info('Updating client event "%s"' % self._old_name)
223
- cursor.execute("UPDATE client_events SET lastrun=%s "
224
- "WHERE name=%s",
225
- (int(self.lastrun), self._old_name))
226
-
227
- if handle_ta:
228
- db.commit()
229
-
230
- def trigger(self, req, client, fromdate, todate, db=None):
231
- assert self.exists, 'Cannot trigger a client event that does not exits'
232
- system = ClientEventsSystem(self.env);
233
- summary = system.get_summary(self.summary)
234
- assert summary is not None , 'Invalid summary'
235
- action = system.get_action(self.action)
236
- assert action is not None, 'Invalid action'
237
-
238
- if not summary.init(self, client):
239
- self.env.log.info("Could not init summary")
240
- return False
241
- if not action.init(self, client):
242
- self.env.log.info("Could not init action")
243
- return False
244
-
245
- self.env.log.debug("Performing action")
246
- return action.perform(req, summary.get_summary(req, fromdate, todate))
247
-
248
-
249
- def select(cls, env, client=None, db=None):
250
- if not db:
251
- db = env.get_db_cnx()
252
- cursor = db.cursor()
253
- cursor.execute("SELECT name, summary, action, lastrun "
254
- "FROM client_events "
255
- "ORDER BY name")
256
- for name, summary, action, lastrun in cursor:
257
- clev = cls(env)
258
- clev.md5 = md5.new(name).hexdigest()
259
- clev.name = clev._old_name = name
260
- clev.summary = summary or ''
261
- clev.action = action or ''
262
- clev.lastrun = lastrun or 0
263
- clev._load_options(client, db)
264
- yield clev
265
- select = classmethod(select)
266
-
267
- def triggerall(cls, env, req, event, db=None):
268
- if not db:
269
- db = env.get_db_cnx()
270
-
271
- try:
272
- ev = cls(env, event, None, db)
273
- except:
274
- env.log.error("Could not run the event %s" % (event,))
275
- return
276
- #ev.lastrun = 1
277
- now = int(time.time())
278
-
279
- cursor = db.cursor()
280
- cursor.execute("SELECT name FROM client ORDER BY name")
281
- for client, in cursor:
282
- env.log.info("Running event for client: %s" % (client, ))
283
- clev = cls(env, event, client)
284
- clev.trigger(req, client, ev.lastrun, now)
285
- ev.lastrun = now
286
- ev.update()
287
- triggerall = classmethod(triggerall)
@@ -1,71 +0,0 @@
1
- from trac.core import *
2
- from trac.perm import PermissionSystem
3
- #from trac.ticket.model import AbstractEnum
4
- #from trac.ticket.admin import AbstractEnumAdminPage
5
- from trac.ticket.admin import TicketAdminPanel
6
-
7
-
8
- from clients.events import ClientEvent, ClientEventsSystem
9
-
10
- from trac.util.datefmt import utc, parse_date, get_date_format_hint, \
11
- get_datetime_format_hint
12
- from trac.web.chrome import add_link, add_script
13
-
14
-
15
- class ClientEventsAdminPanel(TicketAdminPanel):
16
-
17
- _type = 'clientevents'
18
- _label = ('Client Events', 'Client Events')
19
-
20
- # TicketAdminPanel methods
21
- def _render_admin_panel(self, req, cat, page, event):
22
- # Detail view?
23
- if event:
24
- clev = ClientEvent(self.env, event)
25
- if req.method == 'POST':
26
- if req.args.get('save'):
27
- # Client Events are not saved... just deleted or viewed...
28
- for option in clev.summary_options:
29
- arg = 'summary-option-%s' % clev.summary_options[option]['md5']
30
- clev.summary_options[option]['value'] = req.args.get(arg)
31
- for option in clev.action_options:
32
- arg = 'action-option-%s' % clev.action_options[option]['md5']
33
- clev.action_options[option]['value'] = req.args.get(arg)
34
- clev.update_options()
35
- req.redirect(req.href.admin(cat, page))
36
- elif req.args.get('cancel'):
37
- req.redirect(req.href.admin(cat, page))
38
-
39
- add_script(req, 'common/js/wikitoolbar.js')
40
- data = {'view': 'detail', 'event': clev}
41
-
42
- else:
43
- if req.method == 'POST':
44
- # Add Client
45
- if req.args.get('add') and req.args.get('name'):
46
- clev = ClientEvent(self.env)
47
- clev.name = req.args.get('name')
48
- clev.summary = req.args.get('summary')
49
- clev.action = req.args.get('action')
50
- clev.insert()
51
- req.redirect(req.href.admin(cat, page))
52
-
53
- # Remove clients
54
- elif req.args.get('remove') and req.args.get('sel'):
55
- sel = req.args.get('sel')
56
- sel = isinstance(sel, list) and sel or [sel]
57
- if not sel:
58
- raise TracError('No client event selected')
59
- db = self.env.get_db_cnx()
60
- for name in sel:
61
- clev = ClientEvent(self.env, name, db=db)
62
- clev.delete(db=db)
63
- db.commit()
64
- req.redirect(req.href.admin(cat, page))
65
-
66
- data = {'view': 'list',
67
- 'events': ClientEvent.select(self.env),
68
- 'summaries': ClientEventsSystem(self.env).get_summaries(),
69
- 'actions': ClientEventsSystem(self.env).get_actions()}
70
-
71
- return 'admin_client_events.html', data