source: timingandestimationplugin/branches/trac0.11/timingandestimationplugin/api.py

Last change on this file was 11653, checked in by Russ Tyndall, 11 years ago

Removing deprecated unused code in prep for trac1.0 re #10101

File size: 11.8 KB
Line 
1import re
2import dbhelper
3import time
4from tande_filters import *
5from ticket_daemon import *
6from usermanual import *
7from trac.ticket import ITicketChangeListener, Ticket
8from trac.core import *
9from trac.env import IEnvironmentSetupParticipant
10from trac.perm import IPermissionRequestor, PermissionSystem
11from webui import *
12from ticket_webui import *
13from query_webui import *
14from reportmanager import CustomReportManager
15from statuses import *
16from reports import all_reports
17from stopwatch import *
18from hours_layout_changer import *
19
20
21## report columns
22## id|author|title|query|description
23
24class TimeTrackingSetupParticipant(Component):
25    """ This is the config that must be there for this plugin to work:
26
27        [ticket-custom]
28        totalhours = text
29        totalhours.value = 0
30        totalhours.label = Total Hours
31
32        billable = checkbox
33        billable.value = 1
34        billable.label = Is this billable?
35
36        hours = text
37        hours.value = 0
38        hours.label = Hours to Add
39
40        estimatedhours = text
41        estimatedhours.value = 0
42        estimatedhours.label = Estimated Hours?
43
44        """
45    implements(IEnvironmentSetupParticipant)
46    db_version_key = None
47    db_version = None
48    db_installed_version = None
49
50    """Extension point interface for components that need to participate in the
51    creation and upgrading of Trac environments, for example to create
52    additional database tables."""
53    def __init__(self):
54        # Setup logging
55        self.statuses_key = 'T&E-statuses'
56        self.db_version_key = 'TimingAndEstimationPlugin_Db_Version'
57        self.db_version = 6
58        # Initialise database schema version tracking.
59        self.db_installed_version = dbhelper.get_system_value(self, \
60            self.db_version_key) or 0
61
62    def environment_created(self):
63        """Called when a new Trac environment is created."""
64        if self.environment_needs_upgrade(None):
65            self.upgrade_environment(None)
66
67
68    def system_needs_upgrade(self):
69        return self.db_installed_version < self.db_version
70
71    def do_db_upgrade(self):
72        # Legacy support hack (supports upgrades from 0.1.6 to 0.1.7)
73        if self.db_installed_version == 0:
74            bill_date = dbhelper.db_table_exists(self, 'bill_date');
75            report_version = dbhelper.db_table_exists(self, 'report_version');
76            if bill_date and report_version:
77                self.db_installed_version = 1
78        # End Legacy support hack
79
80
81        if self.db_installed_version < 1:
82            print "Creating bill_date table"
83            sql = """
84            CREATE TABLE bill_date (
85            time integer,
86            set_when integer,
87            str_value text
88            );
89            """
90            dbhelper.execute_non_query(self,  sql)
91
92
93            print "Creating report_version table"
94            sql = """
95            CREATE TABLE report_version (
96            report integer,
97            version integer,
98            UNIQUE (report, version)
99            );
100            """
101            dbhelper.execute_non_query(self, sql)
102
103        if self.db_installed_version < 4:
104            print "Upgrading report_version table to v4"
105            sql ="""
106            ALTER TABLE report_version ADD COLUMN tags varchar(1024) null;
107            """
108            dbhelper.execute_non_query(self, sql)
109
110        if self.db_installed_version < 5:
111            # In this version we convert to using reportmanager.py
112            # The easiest migration path is to remove all the reports!!
113            # They will be added back in later but all custom reports will be lost (deleted)
114            print "Dropping report_version table"
115            sql = "DELETE FROM report " \
116                  "WHERE author=%s AND id IN (SELECT report FROM report_version)"
117            dbhelper.execute_non_query(self, sql, 'Timing and Estimation Plugin')
118
119            sql = "DROP TABLE report_version"
120            dbhelper.execute_non_query(self, sql)
121
122        #version 6 upgraded reports
123
124        # This statement block always goes at the end this method
125        dbhelper.set_system_value(self, self.db_version_key, self.db_version)
126        self.db_installed_version = self.db_version
127
128    def reports_need_upgrade(self):
129        mgr = CustomReportManager(self.env, self.log)
130        db_reports = mgr.get_version_hash_by_group(CustomReportManager.TimingAndEstimationKey)
131        py_reports = {}
132        for report_group in all_reports:
133            for report in report_group['reports']:
134                py_reports[report['uuid']]= report['version']
135       
136        diff = [(uuid, version) for (uuid, version) in py_reports.items()
137                if not db_reports.has_key(uuid) or int(db_reports[uuid]) < int(version)]
138               
139        if len(diff) > 0:
140            self.log.debug ("T&E needs upgrades for the following reports: %s" %
141                            (diff, ))
142        return len(diff) > 0
143
144    def do_reports_upgrade(self, force=False):
145        self.log.debug( "Beginning Reports Upgrade");
146        mgr = CustomReportManager(self.env, self.log)
147        statuses = get_statuses(self)
148        stat_vars = status_variables(statuses)
149
150        for report_group in all_reports:
151            rlist = report_group["reports"]
152            group_title = report_group["title"]
153            for report in rlist:
154                title = report["title"]
155                new_version = report["version"]
156
157                sql = report["sql"].replace('#STATUSES#', stat_vars)
158                mgr.add_report(report["title"], "Timing and Estimation Plugin", \
159                               "Reports Must Be Accessed From the Management Screen",
160                               sql, report["uuid"], report["version"],
161                               CustomReportManager.TimingAndEstimationKey,
162                               group_title, force)
163
164    def ticket_fields_need_upgrade(self):
165        ticket_custom = "ticket-custom"
166        return not ( self.config.get( ticket_custom, "totalhours" ) and \
167
168                     #self.config.get( ticket_custom, "billable" ) and \
169                     #self.config.get( ticket_custom, "billable.order") and \
170                     #(self.config.get( ticket_custom, "billable" ) == "checkbox") and \
171                     #(not self.config.get( ticket_custom, "lastbilldate" )) and \
172
173                     self.config.get( ticket_custom, "hours" ) and \
174                     self.config.get( ticket_custom, "totalhours.order") and \
175                     self.config.get( ticket_custom, "hours.order") and \
176                     self.config.get( ticket_custom, "estimatedhours.order") and \
177
178                     self.config.get( ticket_custom, "estimatedhours"))
179
180    def do_ticket_field_upgrade(self):
181        ticket_custom = "ticket-custom"
182
183        self.config.set(ticket_custom,"totalhours", "text")
184        if not self.config.get( ticket_custom, "totalhours.order") :
185            self.config.set(ticket_custom,"totalhours.order", "4")
186        if not self.config.get( ticket_custom, "totalhours.value") :
187            self.config.set(ticket_custom,"totalhours.value", "0")
188        if not self.config.get( ticket_custom, "totalhours.label") :
189            self.config.set(ticket_custom,"totalhours.label", "Total Hours")
190
191        self.config.set(ticket_custom,"billable", "checkbox")
192        if not self.config.get( ticket_custom, "billable.value") :
193            self.config.set(ticket_custom,"billable.value", "1")
194        if not self.config.get( ticket_custom, "billable.order") :
195            self.config.set(ticket_custom,"billable.order", "3")
196        if not self.config.get( ticket_custom, "billable.label") :
197            self.config.set(ticket_custom,"billable.label", "Billable?")
198
199        self.config.set(ticket_custom,"hours", "text")
200        if not self.config.get( ticket_custom, "hours.value") :
201            self.config.set(ticket_custom,"hours.value", "0")
202        if not self.config.get( ticket_custom, "hours.order") :
203            self.config.set(ticket_custom,"hours.order", "2")
204        if not self.config.get( ticket_custom, "hours.label") :
205            self.config.set(ticket_custom,"hours.label", "Add Hours to Ticket")
206
207        self.config.set(ticket_custom,"estimatedhours", "text")
208        if not self.config.get( ticket_custom, "estimatedhours.value") :
209            self.config.set(ticket_custom,"estimatedhours.value", "0")
210        if not self.config.get( ticket_custom, "estimatedhours.order") :
211            self.config.set(ticket_custom,"estimatedhours.order", "1")
212        if not self.config.get( ticket_custom, "estimatedhours.label") :
213            self.config.set(ticket_custom,"estimatedhours.label", "Estimated Number of Hours")
214
215        self.config.save();
216
217    def needs_user_man(self):
218        maxversion = dbhelper.get_scalar(self, "SELECT MAX(version) FROM wiki WHERE name like %s", 0,
219                                         user_manual_wiki_title)
220        if (not maxversion) or maxversion < user_manual_version:
221            return True
222        return False
223
224    def do_user_man_update(self):
225
226        when = int(time.time())
227        sql = """
228        INSERT INTO wiki (name,version,time,author,ipnr,text,comment,readonly)
229        VALUES ( %s, %s, %s, 'Timing and Estimation Plugin', '127.0.0.1', %s,'',0)
230        """
231        dbhelper.execute_non_query(self, sql,
232                                   user_manual_wiki_title,
233                                   user_manual_version,
234                                   when,
235                                   user_manual_content)
236
237
238    def environment_needs_upgrade(self, db):
239        """Called when Trac checks whether the environment needs to be upgraded.
240
241        Should return `True` if this participant needs an upgrade to be
242        performed, `False` otherwise.
243
244        """
245        self.log.debug("NEEDS UP?: sys:%s, rep:%s, stats:%s, fields:%s, man:%s" % \
246                       ((self.system_needs_upgrade()),
247                        (self.reports_need_upgrade()),
248                        (self.have_statuses_changed()),
249                        (self.ticket_fields_need_upgrade()),
250                        (self.needs_user_man())))
251        return (self.system_needs_upgrade()) or \
252               (self.reports_need_upgrade()) or \
253               (self.have_statuses_changed()) or \
254               (self.ticket_fields_need_upgrade()) or \
255               (self.needs_user_man())
256
257    def upgrade_environment(self, db):
258        """Actually perform an environment upgrade.
259
260        Implementations of this method should not commit any database
261        transactions. This is done implicitly after all participants have
262        performed the upgrades they need without an error being raised.
263        """
264        def p(s):
265            print s
266            return True
267        print "Timing and Estimation needs an upgrade"
268        p("Upgrading Database")
269        self.do_db_upgrade()
270        p("Upgrading reports")
271        self.do_reports_upgrade(force=self.have_statuses_changed())
272
273        #make sure we upgrade the statuses string so that we dont need to always rebuild the
274        # reports
275        stats = get_statuses(self)
276        val = ','.join(list(stats))
277        dbhelper.set_system_value(self, self.statuses_key, val)
278
279        if self.ticket_fields_need_upgrade():
280            p("Upgrading fields")
281            self.do_ticket_field_upgrade()
282        if self.needs_user_man():
283            p("Upgrading usermanual")
284            self.do_user_man_update()
285        print "Done Upgrading"
286
287    def have_statuses_changed(self):
288        """get the statuses from the last time we saved them,
289        compare them to the ones we have now (ignoring '' and None),
290        if we have different ones, throw return true
291        """
292        s = dbhelper.get_system_value(self, self.statuses_key)
293        if not s:
294            return True
295        sys_stats = get_statuses(self)
296        s = s.split(',')
297        sys_stats.symmetric_difference_update(s)
298        sys_stats.difference_update(['', None])
299        return len(sys_stats) > 0
Note: See TracBrowser for help on using the repository browser.