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
RevLine 
[1119]1import re
2import dbhelper
[1369]3import time
[3784]4from tande_filters import *
[1119]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
[3784]11from webui import *
[1516]12from ticket_webui import *
[2298]13from query_webui import *
[2390]14from reportmanager import CustomReportManager
[2774]15from statuses import *
[2785]16from reports import all_reports
[7435]17from stopwatch import *
[10643]18from hours_layout_changer import *
[1119]19
[6531]20
[1119]21## report columns
22## id|author|title|query|description
[3784]23
[1119]24class TimeTrackingSetupParticipant(Component):
25    """ This is the config that must be there for this plugin to work:
[3784]26
[1119]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
[3784]39
[1119]40        estimatedhours = text
41        estimatedhours.value = 0
42        estimatedhours.label = Estimated Hours?
[3784]43
[1119]44        """
45    implements(IEnvironmentSetupParticipant)
[2390]46    db_version_key = None
47    db_version = None
48    db_installed_version = None
[3784]49
[1119]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):
[2390]54        # Setup logging
[2774]55        self.statuses_key = 'T&E-statuses'
[2390]56        self.db_version_key = 'TimingAndEstimationPlugin_Db_Version'
[2590]57        self.db_version = 6
[2390]58        # Initialise database schema version tracking.
[3784]59        self.db_installed_version = dbhelper.get_system_value(self, \
[3119]60            self.db_version_key) or 0
[2390]61
[1119]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)
[2390]66
[3784]67
[2390]68    def system_needs_upgrade(self):
69        return self.db_installed_version < self.db_version
[3784]70
[2390]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:
[3784]74            bill_date = dbhelper.db_table_exists(self, 'bill_date');
75            report_version = dbhelper.db_table_exists(self, 'report_version');
[2390]76            if bill_date and report_version:
77                self.db_installed_version = 1
78        # End Legacy support hack
79
[3784]80
[2390]81        if self.db_installed_version < 1:
[1119]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            """
[3784]90            dbhelper.execute_non_query(self,  sql)
[2823]91
[3784]92
[1119]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            """
[3784]101            dbhelper.execute_non_query(self, sql)
[2349]102
[2390]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            """
[3784]108            dbhelper.execute_non_query(self, sql)
[2349]109
[2390]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)"
[3784]117            dbhelper.execute_non_query(self, sql, 'Timing and Estimation Plugin')
[2349]118
[2390]119            sql = "DROP TABLE report_version"
[3784]120            dbhelper.execute_non_query(self, sql)
121
122        #version 6 upgraded reports
123
[2390]124        # This statement block always goes at the end this method
[3784]125        dbhelper.set_system_value(self, self.db_version_key, self.db_version)
[2390]126        self.db_installed_version = self.db_version
[3784]127
[2785]128    def reports_need_upgrade(self):
129        mgr = CustomReportManager(self.env, self.log)
[5491]130        db_reports = mgr.get_version_hash_by_group(CustomReportManager.TimingAndEstimationKey)
131        py_reports = {}
[2785]132        for report_group in all_reports:
133            for report in report_group['reports']:
[5491]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               
[3179]139        if len(diff) > 0:
[5491]140            self.log.debug ("T&E needs upgrades for the following reports: %s" %
141                            (diff, ))
[3179]142        return len(diff) > 0
[3784]143
[2774]144    def do_reports_upgrade(self, force=False):
[1626]145        self.log.debug( "Beginning Reports Upgrade");
[2390]146        mgr = CustomReportManager(self.env, self.log)
[3784]147        statuses = get_statuses(self)
[2774]148        stat_vars = status_variables(statuses)
[3784]149
[2785]150        for report_group in all_reports:
[1119]151            rlist = report_group["reports"]
[2349]152            group_title = report_group["title"]
[1119]153            for report in rlist:
154                title = report["title"]
155                new_version = report["version"]
[3784]156
[2774]157                sql = report["sql"].replace('#STATUSES#', stat_vars)
[2390]158                mgr.add_report(report["title"], "Timing and Estimation Plugin", \
[2774]159                               "Reports Must Be Accessed From the Management Screen",
160                               sql, report["uuid"], report["version"],
161                               CustomReportManager.TimingAndEstimationKey,
162                               group_title, force)
[1119]163
164    def ticket_fields_need_upgrade(self):
165        ticket_custom = "ticket-custom"
166        return not ( self.config.get( ticket_custom, "totalhours" ) and \
[3784]167
[3362]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
[1119]173                     self.config.get( ticket_custom, "hours" ) and \
[1554]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 \
[3362]177
[1119]178                     self.config.get( ticket_custom, "estimatedhours"))
[3784]179
[1119]180    def do_ticket_field_upgrade(self):
181        ticket_custom = "ticket-custom"
[3784]182
[1119]183        self.config.set(ticket_custom,"totalhours", "text")
[1554]184        if not self.config.get( ticket_custom, "totalhours.order") :
185            self.config.set(ticket_custom,"totalhours.order", "4")
[5486]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")
[1119]190
191        self.config.set(ticket_custom,"billable", "checkbox")
[5486]192        if not self.config.get( ticket_custom, "billable.value") :
193            self.config.set(ticket_custom,"billable.value", "1")
[1554]194        if not self.config.get( ticket_custom, "billable.order") :
195            self.config.set(ticket_custom,"billable.order", "3")
[5486]196        if not self.config.get( ticket_custom, "billable.label") :
197            self.config.set(ticket_custom,"billable.label", "Billable?")
[3784]198
[1119]199        self.config.set(ticket_custom,"hours", "text")
[5486]200        if not self.config.get( ticket_custom, "hours.value") :
201            self.config.set(ticket_custom,"hours.value", "0")
[1554]202        if not self.config.get( ticket_custom, "hours.order") :
203            self.config.set(ticket_custom,"hours.order", "2")
[5486]204        if not self.config.get( ticket_custom, "hours.label") :
205            self.config.set(ticket_custom,"hours.label", "Add Hours to Ticket")
[3784]206
[1119]207        self.config.set(ticket_custom,"estimatedhours", "text")
[5486]208        if not self.config.get( ticket_custom, "estimatedhours.value") :
209            self.config.set(ticket_custom,"estimatedhours.value", "0")
[1554]210        if not self.config.get( ticket_custom, "estimatedhours.order") :
211            self.config.set(ticket_custom,"estimatedhours.order", "1")
[5486]212        if not self.config.get( ticket_custom, "estimatedhours.label") :
213            self.config.set(ticket_custom,"estimatedhours.label", "Estimated Number of Hours")
[1119]214
215        self.config.save();
216
217    def needs_user_man(self):
[3784]218        maxversion = dbhelper.get_scalar(self, "SELECT MAX(version) FROM wiki WHERE name like %s", 0,
[1119]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):
[1444]225
[1369]226        when = int(time.time())
[1119]227        sql = """
228        INSERT INTO wiki (name,version,time,author,ipnr,text,comment,readonly)
[1369]229        VALUES ( %s, %s, %s, 'Timing and Estimation Plugin', '127.0.0.1', %s,'',0)
[1119]230        """
[3784]231        dbhelper.execute_non_query(self, sql,
[1119]232                                   user_manual_wiki_title,
233                                   user_manual_version,
[1369]234                                   when,
[1119]235                                   user_manual_content)
[3784]236
237
[1119]238    def environment_needs_upgrade(self, db):
239        """Called when Trac checks whether the environment needs to be upgraded.
[3784]240
[1119]241        Should return `True` if this participant needs an upgrade to be
242        performed, `False` otherwise.
243
244        """
[2823]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())))
[2390]251        return (self.system_needs_upgrade()) or \
[2785]252               (self.reports_need_upgrade()) or \
[2774]253               (self.have_statuses_changed()) or \
[1204]254               (self.ticket_fields_need_upgrade()) or \
[3784]255               (self.needs_user_man())
256
[1119]257    def upgrade_environment(self, db):
258        """Actually perform an environment upgrade.
[3784]259
[1119]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"
[2390]268        p("Upgrading Database")
269        self.do_db_upgrade()
270        p("Upgrading reports")
[2774]271        self.do_reports_upgrade(force=self.have_statuses_changed())
[3784]272
[2774]273        #make sure we upgrade the statuses string so that we dont need to always rebuild the
274        # reports
[3784]275        stats = get_statuses(self)
[2774]276        val = ','.join(list(stats))
[3784]277        dbhelper.set_system_value(self, self.statuses_key, val)
278
[1119]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
[2774]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        """
[3784]292        s = dbhelper.get_system_value(self, self.statuses_key)
[2774]293        if not s:
294            return True
[3784]295        sys_stats = get_statuses(self)
[2774]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.