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