Changeset 2390

Show
Ignore:
Timestamp:
07/05/07 09:00:57 (1 year ago)
Author:
bobbysmith007
Message:

TimingAndEstimationPlugin:

closes #1737

Applied Colin Guthrie's patch to make managing custom reports easier.

Thanks for the patch!

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • timingandestimationplugin/branches/trac0.10/setup.py

    r2372 r2390  
    88      description='Plugin to make Trac support time estimation and tracking', 
    99      keywords='trac plugin estimation timetracking', 
    10       version='0.4.4', 
    11       url='', 
     10      version='0.4.5', 
     11      url='http://www.trac-hacks.org/wiki/TimingAndEstimationPlugin', 
    1212      license='http://www.opensource.org/licenses/mit-license.php', 
    1313      author='Russ Tyndall at Acceleration.net', 
     
    1919      """, 
    2020      packages=[PACKAGE], 
    21       package_data={PACKAGE : ['templates/*.cs', 'htdocs/*', 'migrate/*.py']}, 
     21      package_data={PACKAGE : ['templates/*.cs', 'htdocs/*']}, 
    2222      entry_points={'trac.plugins': '%s = %s' % (PACKAGE, PACKAGE)}) 
    2323 
     
    4444## made it so that base_url was unnecessary 
    4545 
     46## Colin Guthrie 
     47## trac-hacks user: coling 
     48## Refactored the custom reports code to make it 
     49## easy for other plugins to provide reports to 
     50## compliment those provided by default 
     51 
  • timingandestimationplugin/branches/trac0.10/timingandestimationplugin/api.py

    r2372 r2390  
    44from ticket_daemon import * 
    55from usermanual import * 
    6 from reports import all_reports 
    76from trac.log import logger_factory 
    87from trac.ticket import ITicketChangeListener, Ticket 
     
    1211from webui import *  
    1312from ticket_webui import * 
     13from reportmanager import CustomReportManager 
    1414 
    1515## report columns 
     
    3838        """ 
    3939    implements(IEnvironmentSetupParticipant) 
     40 
     41    db_version_key = None 
     42    db_version = None 
     43    db_installed_version = None 
    4044     
    4145    """Extension point interface for components that need to participate in the 
     
    4347    additional database tables.""" 
    4448    def __init__(self): 
    45         sql = "SELECT id, title FROM report ORDER BY ID" 
     49        # Setup logging 
    4650        dbhelper.mylog = self.log 
    47         self.reportmap = dbhelper.get_all(self.env.get_db_cnx(), sql)[1] 
    48          
     51        self.db_version_key = 'TimingAndEstimationPlugin_Db_Version' 
     52        self.db_version = 5 
     53        self.db_installed_version = None 
     54 
     55        # Initialise database schema version tracking. 
     56        db = self.env.get_db_cnx() 
     57        cursor = db.cursor() 
     58        cursor.execute("SELECT value FROM system WHERE name=%s", (self.db_version_key,)) 
     59        try: 
     60            self.db_installed_version = int(cursor.fetchone()[0]) 
     61        except: 
     62            self.db_installed_version = 0 
     63            cursor.execute("INSERT INTO system (name,value) VALUES(%s,%s)", 
     64                           (self.db_version_key, self.db_installed_version)) 
     65            db.commit() 
     66            db.close() 
     67            print "Done" 
     68 
    4969    def environment_created(self): 
    5070        """Called when a new Trac environment is created.""" 
     
    5272            self.upgrade_environment(None) 
    5373             
    54     def db_needs_upgrade(self): 
    55         bill_date = dbhelper.db_table_exists(self.env.get_db_cnx(), 'bill_date'); 
    56         report_version = dbhelper.db_table_exists(self.env.get_db_cnx(), 'report_version'); 
    57         val =  dbhelper.db_needs_upgrade(self.env.get_db_cnx()) 
    58         return val or not bill_date or not report_version 
    59          
    60     def db_do_upgrade(self): 
    61         bill_date = dbhelper.db_table_exists(self.env.get_db_cnx(), 'bill_date'); 
    62         report_version = dbhelper.db_table_exists(self.env.get_db_cnx(), 'report_version'); 
    63         if not bill_date: 
     74    def system_needs_upgrade(self): 
     75        return self.db_installed_version < self.db_version 
     76         
     77    def do_db_upgrade(self): 
     78        # Legacy support hack (supports upgrades from 0.1.6 to 0.1.7) 
     79        if self.db_installed_version == 0: 
     80            bill_date = dbhelper.db_table_exists(self.env.get_db_cnx(), 'bill_date'); 
     81            report_version = dbhelper.db_table_exists(self.env.get_db_cnx(), 'report_version'); 
     82            if bill_date and report_version: 
     83                self.db_installed_version = 1 
     84        # End Legacy support hack 
     85         
     86         
     87        if self.db_installed_version < 1: 
    6488            print "Creating bill_date table" 
    6589            sql = """ 
     
    7296            dbhelper.execute_non_query(self.env.get_db_cnx(), sql) 
    7397             
    74              
    75         if not report_version: 
    7698            print "Creating report_version table" 
    7799            sql = """ 
     
    83105            """ 
    84106            dbhelper.execute_non_query(self.env.get_db_cnx(), sql) 
    85         dbhelper.migrate_up_to_version(self.env.get_db_cnx, dbhelper) 
    86         dbhelper.set_plugin_db_version(self.env.get_db_cnx) 
    87      
    88     def reports_need_upgrade(self): 
    89         bit = False 
    90         report_version = dbhelper.db_table_exists(self.env.get_db_cnx(), 'report_version'); 
    91         if not report_version: 
    92             return True 
    93          
    94         #make versions hash 
    95         try: 
    96             _versions = dbhelper.get_result_set(self.env.get_db_cnx(),""" 
    97                SELECT report as id, version, r.title as title 
    98                FROM report_version 
    99                JOIN report r ON r.Id = report_version.report 
    100                WHERE tags LIKE '%T&E%' """) 
    101         except Exception: 
    102             return True; 
    103         versions = {} 
    104  
    105         if _versions.rows == None: 
    106             return True 
    107  
    108         for (id, version, title) in _versions.rows: 
    109             versions[title] = (id, version) 
    110  
    111              
    112         for report_group in all_reports: 
     107 
     108        if self.db_installed_version < 4: 
     109            print "Upgrading report_version table to v4" 
     110            sql =""" 
     111            ALTER TABLE report_version ADD COLUMN tags varchar(1024) null; 
     112            """ 
     113            dbhelper.execute_non_query(self.env.get_db_cnx(), sql) 
     114 
     115        if self.db_installed_version < 5: 
     116            # In this version we convert to using reportmanager.py 
     117            # The easiest migration path is to remove all the reports!! 
     118            # They will be added back in later but all custom reports will be lost (deleted) 
     119            print "Dropping report_version table" 
     120            sql = "DELETE FROM report " \ 
     121                  "WHERE author=%s AND id IN (SELECT report FROM report_version)" 
     122            dbhelper.execute_non_query(self.env.get_db_cnx(), sql, 'Timing and Estimation Plugin') 
     123             
     124            sql = "DROP TABLE report_version" 
     125            dbhelper.execute_non_query(self.env.get_db_cnx(), sql) 
     126         
     127         
     128        # This statement block always goes at the end this method 
     129        sql = "UPDATE system SET value=%s WHERE name=%s" 
     130        dbhelper.execute_non_query(self.env.get_db_cnx(), 
     131                                   sql, self.db_version, self.db_version_key) 
     132        self.db_installed_version = self.db_version 
     133     
     134 
     135    def do_reports_upgrade(self): 
     136        self.log.debug( "Beginning Reports Upgrade"); 
     137        mgr = CustomReportManager(self.env, self.log) 
     138        r = __import__("reports", globals(), locals(), ["all_reports"]) 
     139 
     140        for report_group in r.all_reports: 
    113141            rlist = report_group["reports"] 
     142            group_title = report_group["title"] 
    114143            for report in rlist: 
    115144                title = report["title"] 
    116145                new_version = report["version"] 
    117                 #the report map is a list of (id, name) tuples for the reports 
    118                 # here we want to see if our report is in the list 
    119                 idx = [i for i in range(0, len(self.reportmap)) if self.reportmap[i][1] == title] 
    120                 if not idx: 
    121                     self.log.warning("Report '%s' needs to be added" % title) 
    122                     bit = True; 
    123                 else: 
    124                     # If we had a report make sure its at the correct version 
    125                     if versions.has_key(title): 
    126                         (id, ver) = versions[title] 
    127                     else: 
    128                         ver = 0 
    129                     if ver < new_version: 
    130                         bit = True 
    131         return bit 
    132                  
    133     def do_reports_upgrade(self): 
    134         self.log.debug( "Beginning Reports Upgrade"); 
    135         #make version hash 
    136         _versions = dbhelper.get_result_set(self.env.get_db_cnx(), 
    137                                            """ 
    138                                            SELECT report as id, version, r.title as title 
    139                                            FROM report_version 
    140                                            JOIN report r ON r.Id = report_version.report 
    141                                            WHERE tags LIKE '%T&E%' 
    142                                            """) 
    143         versions = {} 
    144         if _versions and _versions.rows: 
    145             for (id, version, title) in _versions.rows: 
    146                 versions[title] = (id, version) 
    147              
    148         biggestId = dbhelper.get_scalar(self.env.get_db_cnx(), 
    149                                         "SELECT ID FROM report ORDER BY ID DESC LIMIT 1") 
    150         def insert_report_version(id, ver, tag): 
    151             sql = "DELETE FROM report_version WHERE report = %s;" 
    152             dbhelper.execute_non_query(self.env.get_db_cnx(), sql, id  ) 
    153             sql = """ 
    154             INSERT INTO report_version (report, version, tags) 
    155             VALUES (%s, %s, %s);""" 
    156             # print "about to insert report_version" 
    157             dbhelper.execute_non_query(self.env.get_db_cnx(), sql, id, ver, tag ) 
    158             # print "inserted report_version" 
    159              
    160         for report_group in all_reports: 
    161             rlist = report_group["reports"] 
    162             group_title = report_group["title"] 
    163             tag = "T&E %s" % group_title 
    164             for report in rlist: 
    165                 title = report["title"] 
    166                 new_version = report["version"] 
    167                 report_id = [rid 
    168                              for (rid, map_title) in self.reportmap 
    169                              if map_title == title] 
    170                 if not report_id: 
    171                     bit = True;  
    172                     sql = """INSERT INTO report (id,author,title,query,description)  
    173                              VALUES (%s,'Timing and Estimation Plugin',%s,%s,'') """ 
    174                     biggestId += 1 
    175                     dbhelper.execute_non_query(self.env.get_db_cnx(), sql, 
    176                                                biggestId, title, report["sql"]) 
    177                     insert_report_version(biggestId, new_version, tag) 
    178  
    179                     report["reportnumber"] = biggestId 
    180                     self.reportmap.extend([(biggestId,title)]) 
    181                 else: 
    182                     report_id = report_id[0] 
    183                     report["reportnumber"] = report_id 
    184                      # If we had a report make sure its at the correct version 
    185                     if versions.has_key(title): 
    186                         ( _ , ver) = versions[title] 
    187                     else: 
    188                         ver = 0 
    189                     if not ver: 
    190                         sql = """ 
    191                         UPDATE report 
    192                         SET query=%s  
    193                         WHERE id = %s """ 
    194                         print "updating report: %s" % title 
    195                         dbhelper.execute_non_query(self.env.get_db_cnx(), sql, 
    196                                                    report["sql"], report_id ) 
    197                         insert_report_version( report_id, new_version, tag ) 
    198                     elif ver < new_version: 
    199                         sql = """ 
    200                         UPDATE report 
    201                         SET query=%s  
    202                         WHERE id = %s """ 
    203                         print "updating report to new version: %s" % title 
    204                         dbhelper.execute_non_query(self.env.get_db_cnx(), sql, 
    205                                                    report["sql"], report_id ) 
    206                          
    207                         sql = """ 
    208                         UPDATE report_version 
    209                         SET version = %s, tags = %s 
    210                          
    211                         WHERE report = %s 
    212                         """ 
    213                         dbhelper.execute_non_query(self.env.get_db_cnx(), sql, new_version, tag, report_id) 
    214                          
     146                mgr.add_report(report["title"], "Timing and Estimation Plugin", \ 
     147                               "", report["sql"], \ 
     148                               report["uuid"], report["version"], 
     149                               "Timing and Estimation Plugin", 
     150                               group_title) 
     151 
     152     
    215153    def ticket_fields_need_upgrade(self): 
    216154        ticket_custom = "ticket-custom" 
     
    284222 
    285223        """ 
    286         return (self.db_needs_upgrade()) or \ 
     224        return (self.system_needs_upgrade()) or \ 
    287225               (self.ticket_fields_need_upgrade()) or \ 
    288                (self.reports_need_upgrade()) or \ 
    289226               (self.needs_user_man())  
    290227             
     
    300237            return True 
    301238        print "Timing and Estimation needs an upgrade" 
    302         if self.db_needs_upgrade(): 
    303             p("Upgrading Database") 
    304             self.db_do_upgrade() 
     239        p("Upgrading Database") 
     240        self.do_db_upgrade() 
     241        p("Upgrading reports") 
     242        self.do_reports_upgrade() 
     243 
    305244        if self.ticket_fields_need_upgrade(): 
    306245            p("Upgrading fields") 
    307246            self.do_ticket_field_upgrade() 
    308         if self.reports_need_upgrade(): 
    309             p("Upgrading reports") 
    310             self.do_reports_upgrade() 
    311247        if self.needs_user_man(): 
    312248            p("Upgrading usermanual") 
     
    318254 
    319255 
     256 
  • timingandestimationplugin/branches/trac0.10/timingandestimationplugin/dbhelper.py

    r2372 r2390  
    1 db_version_key = 'TimingAndEstimationPlugin_Db_Version'; 
    2 db_version = 4 
    31mylog = None; 
    42 
     
    6159        return None; 
    6260 
    63 def get_plugin_db_version(db): 
    64     sql = "SELECT value FROM system where name = '%s';" % db_version_key 
    65     val = get_scalar(db, sql) 
    66     return val; 
    67  
    68 def set_plugin_db_version(db_fn): 
    69     if get_plugin_db_version(db_fn()): 
    70         sql = "UPDATE system SET value='%s' WHERE name = '%s'" % (db_version, db_version_key) 
    71     else: 
    72         sql = "INSERT INTO system (name, value) VALUES( '%s', '%s') " % ( db_version_key, str(db_version) ) 
    73     execute_non_query(db_fn(), sql); 
    74  
    75 def db_needs_upgrade(db): 
    76     ver = get_plugin_db_version(db); 
    77     if not ver or int(ver) < int(db_version): 
    78         return True 
    79     return False 
    80  
    8161def db_table_exists(db, table): 
    8262    sql = "SELECT * FROM %s LIMIT 1" % table; 
     
    10383    """Executes the query and returns a Result Set""" 
    10484    return ResultSet(get_all(db, sql, *params)) 
    105  
    106 def migrate_up_to_version( db_fn, helper ): 
    107     try: 
    108         start = int(get_plugin_db_version(db_fn())) 
    109     except Exception: 
    110         start = 0 
    111     end = db_version 
    112     r = range( start+1, end+1) 
    113     import migrate 
    114     for i in  r: 
    115         key = "upgrade"+str(i) 
    116         try: 
    117             m = __import__("migrate."+key, globals(), locals(), ["up"]) 
    118             m.up(db_fn, helper) 
    119         except Exception, e: 
    120             #we were not using this sytem before version 4 
    121             if i >= 4: 
    122                 print "no migration for %s " % key 
    12385 
    12486 
  • timingandestimationplugin/branches/trac0.10/timingandestimationplugin/reports.py

    r2349 r2390  
    77billing_reports = [ 
    88        { 
     9    "uuid":"b24f08c0-d41f-4c63-93a5-25e18a8513c2", 
    910    "title":"Ticket Work Summary", 
    1011    "reportnumber":None, 
     
    4849    },#END Ticket work summary 
    4950        { 
     51    "uuid":"af13564f-0e36-4a17-96c0-632dc68d8d14", 
    5052    "title":"Milestone Work Summary", 
    5153    "reportnumber":None, 
     
    9597         
    9698    { 
     99    "uuid":"7bd4b0ce-da6d-4b11-8be3-07e65b540d99", 
    97100    "title":"Developer Work Summary", 
    98101    "reportnumber":None, 
     
    136139ticket_hours_reports = [ 
    137140{ 
     141    "uuid":"8d785cdb-dcf5-43c9-b2a6-216997b0011a", 
    138142    "title": "Ticket Hours", 
    139143    "reportnumber": None, 
     
    205209#END Ticket Hours  
    206210{ 
     211    "uuid":"71e7c36d-e512-4d0b-b499-087d4d20ff0b", 
    207212    "title": "Ticket Hours with Description", 
    208213    "reportnumber": None, 
     
    283288 
    284289    { 
     290    "uuid":"5f33b102-e6a6-47e8-976c-ac7a6794a909", 
    285291    "title":"Ticket Hours Grouped By Component", 
    286292    "reportnumber":None, 
     
    363369     
    364370    { 
     371    "uuid":"7816f034-a174-4a94-aed6-358fb648b2fc", 
    365372    "title":"Ticket Hours Grouped By Component with Description", 
    366373    "reportnumber":None, 
     
    438445# END Ticket Hours Grouped BY Component with Description 
    439446    { 
     447    "uuid":"03815803-7688-4f3a-8e65-8d254cc1d1fb", 
    440448    "title":"Ticket Hours Grouped By Milestone", 
    441449    "reportnumber":None, 
     
    514522#END Ticket Hours Grouped By MileStone 
    515523        { 
     524    "uuid":"040c9025-7641-4d18-96ad-2b26b4095566", 
    516525    "title":"Ticket Hours Grouped By MileStone with Description", 
    517526    "reportnumber":None, 
  • timingandestimationplugin/branches/trac0.10/timingandestimationplugin/templates/billing.cs

    r1204 r2390  
    7070      <ul> 
    7171        <?cs each:report = report_group.reports ?> 
    72           <li><a href="" onmouseover="linkify(this, '<?cs var:report.href ?>')"  > 
     72          <li><a href="" onmouseover="linkify(this, '<?cs var:billing_info.report_base_href ?>/<?cs var:report.id ?>')"  > 
    7373            <?cs var:report.title ?> 
    7474          </a></li>      
  • timingandestimationplugin/branches/trac0.10/timingandestimationplugin/usermanual.py

    r2349 r2390  
    11user_manual_title = "Timing and Estimation Plugin User Manual" 
    2 user_manual_version = 9 
     2user_manual_version = 10 
    33user_manual_wiki_title = "TimingAndEstimationPluginUserManual" 
    44user_manual_content = """ 
    5 [[TOC]] 
     5[[PageOutline]] 
    66= Timing and Estimation Plugin User Manual = 
    77[http://trac-hacks.org/wiki/TimingAndEstimationPlugin TimingAndEstimationPlugin on TracHacks] | [http://trac-hacks.org/report/9?COMPONENT=TimingAndEstimationPlugin Open Tickets] | [http://trac-hacks.org/newticket?component=TimingAndEstimationPlugin&owner=bobbysmith007 New Ticket]  |  
     
    5353To add reports to the Management screen sections, you must run the following sql against your trac database 
    5454Remember to fill in the @reportID of the report you want to insert, and to select the insert statement for the section of your choice. 
    55  * '''INSERT INTO report_version (report, version, tags) VALUES ( @reportID , 1, 'Ticket/Hour Reports');''' 
    56  * '''INSERT INTO report_version (report, version, tags) VALUES ( @reportID , 1, 'Billing Reports');''' 
     55 * {{{INSERT INTO custom_report (id, uuid, maingroup, subgroup, version, ordering) VALUES (@reportID , @uuid, 'Timing and Estimation Plugin', 'Billing Reports', 1, 0);}}} 
     56 * {{{INSERT INTO custom_report (id, uuid, maingroup, subgroup, version, ordering) VALUES (@reportID , @uuid, 'Timing and Estimation Plugin', 'Ticket/Hour Reports', 1, 0);}}} 
     57 
     58''NB: @uuid is a globally uninque identifier created via a tool such as {{{uuidgen}}} on Linux or various [http://www.famkruithof.net/uuid/uuidgen online tools]. It is used in this plugin to provide programatic reference to specific reports such that they can be upgraded successfully on future revisions of the plugin'' 
    5759 
    5860=== Removing a Report === 
    5961To remove reports from the Management page, run the following query.  
    60 Remember to fill in the @reportID of the report you want to insert, and to select the insert statement for the section of your choice
     62Remember to fill in the @reportID of the report you want to modify
    6163 * To remove for this version of the plugin (will be over written in future plugin upgrades) 
    62    * '''UPDATE report_version SET tags=!'' WHERE report = @reportID ;''' 
     64   * {{{UPDATE custom_report SET maingroup='x'||maingroup WHERE report = @reportID;}}} 
    6365 * To remove permanently (wont be over written in future plugin upgrades) 
    64    * '''UPDATE report_version SET version=9999, tags=!'' WHERE report = @reportID ;''' 
     66   * {{{UPDATE custom_report SET version=9999, maingroup='x'||maingroup WHERE report = @reportID;}}} 
     67''NB: The 'x' part is not important - you just need to make the column read something other than 'Timing and Estimation Plugin'.'' 
    6568 
    6669=== TAKE NOTE === 
  • timingandestimationplugin/branches/trac0.10/timingandestimationplugin/webui.py

    r2349 r2390  
    44import dbhelper 
    55from usermanual import *  
    6 from reports import all_reports 
    76from trac.log import logger_factory 
    87from trac.core import * 
     
    1211     INavigationContributor, ITemplateProvider 
    1312from trac.web.href import Href 
     13from reportmanager import CustomReportManager 
    1414 
    1515 
     
    1818    implements(INavigationContributor, IRequestHandler, ITemplateProvider) 
    1919 
    20     #CACHING THIS WAS CAUSING PROBLEMS ON A GLOBAL INSTALL 
    21     def get_copy_report_hash_for_render(self, req): 
    22         new_reports = [] 
    23         sql = "SELECT id, title FROM report ORDER BY ID" 
    24         reportmap = dbhelper.get_all(self.env.get_db_cnx(), sql)[1] 
    25          
    26         for report_group in all_reports: 
    27             new_group = { "title" : report_group["title"] } 
    28             sql = """ 
    29             SELECT id, title 
    30             FROM report 
    31             JOIN report_version on report.id = report_version.report 
    32             WHERE tags LIKE '%%%s%%' 
    33             ORDER BY ID""" % report_group["title"] 
    34             reportmap = dbhelper.get_all(self.env.get_db_cnx(), sql)[1] 
    35             new_reports_list = [] 
    36              
    37             for (r_id, r_name) in reportmap: 
    38                 #find the report id for the name 
    39                 new_report = {"title" : r_name, 
    40                               "reportnumber" : r_id, 
    41                               "href" : "%s/%s" % (req.href.report(), r_id)} 
    42                 new_reports_list.extend([ new_report ]) 
    43             new_group["reports"] = new_reports_list 
    44             new_reports.extend([new_group]) 
    45         return new_reports 
    46              
    4720    def __init__(self): 
    4821        pass 
     
    11285                self.set_bill_date(req.authname) 
    11386                addMessage("All tickets last bill date updated") 
    114                  
    115         req.hdf["billing_info"] = {"messages": messages, 
    116                                    "href":req.href.Billing(), 
    117                                    "reports": self.get_copy_report_hash_for_render(req), 
    118                                    "usermanual_href":req.href.wiki(user_manual_wiki_title), 
    119                                    "usermanual_title":user_manual_title 
     87 
     88        mgr = CustomReportManager(self.env, self.log) 
     89        req.hdf["billing_info"] = {"messages":         messages, 
     90                                   "href":             req.href.Billing(), 
     91                                   "report_base_href": req.href.report(), 
     92                                   "reports":          mgr.get_reports_by_group("Timing and Estimation Plugin"), 
     93                                   "usermanual_href":  req.href.wiki(user_manual_wiki_title), 
     94                                   "usermanual_title": user_manual_title 
    12095                                   } 
    12196        self.set_request_billing_dates(req) 
  • timingandestimationplugin/branches/trac0.11/setup.py

    r2372 r2390  
    88      description='Plugin to make Trac support time estimation and tracking', 
    99      keywords='trac plugin estimation timetracking', 
    10       version='0.4.4', 
     10      version='0.4.5', 
    1111      url='http://trac-hacks.org/wiki/TimingAndEstimationPlugin', 
    1212      license='http://www.opensource.org/licenses/mit-license.php', 
     
    1919      """, 
    2020      packages=[PACKAGE], 
    21       package_data={PACKAGE : ['templates/*.cs', 'htdocs/*', 'migrate/*.py']}, 
     21      package_data={PACKAGE : ['templates/*.html', 'htdocs/*']}, 
    2222      entry_points={'trac.plugins': '%s = %s' % (PACKAGE, PACKAGE)}) 
    2323 
     
    4444## made it so that base_url was unnecessary 
    4545 
     46## Colin Guthrie 
     47## trac-hacks user: coling 
     48## Refactored the custom reports code to make it 
     49## easy for other plugins to provide reports to 
     50## compliment those provided by default 
     51 
  • timingandestimationplugin/branches/trac0.11/timingandestimationplugin/api.py

    r2372 r2390  
    44from ticket_daemon import * 
    55from usermanual import * 
    6 from reports import all_reports 
    76from trac.log import logger_factory 
    87from trac.ticket import ITicketChangeListener, Ticket 
     
    1312from ticket_webui import * 
    1413from query_webui import * 
     14from reportmanager import CustomReportManager 
     15 
    1516 
    1617## report columns 
     
    3940        """ 
    4041    implements(IEnvironmentSetupParticipant) 
     42    db_version_key = None 
     43    db_version = None 
     44    db_installed_version = None 
    4145     
    4246    """Extension point interface for components that need to participate in the 
     
    4448    additional database tables.""" 
    4549    def __init__(self): 
    46         sql = "SELECT id, title FROM report ORDER BY ID" 
     50        # Setup logging 
    4751        dbhelper.mylog = self.log 
    48         self.reportmap = dbhelper.get_all(self.env.get_db_cnx(), sql)[1] 
    49          
     52        self.db_version_key = 'TimingAndEstimationPlugin_Db_Version' 
     53        self.db_version = 5 
     54        self.db_installed_version = None 
     55 
     56        # Initialise database schema version tracking. 
     57        db = self.env.get_db_cnx() 
     58        cursor = db.cursor() 
     59        cursor.execute("SELECT value FROM system WHERE name=%s", (self.db_version_key,)) 
     60        try: 
     61            self.db_installed_version = int(cursor.fetchone()[0]) 
     62        except: 
     63            self.db_installed_version = 0 
     64            cursor.execute("INSERT INTO system (name,value) VALUES(%s,%s)", 
     65                           (self.db_version_key, self.db_installed_version)) 
     66            db.commit() 
     67            db.close() 
     68            print "Done" 
     69 
    5070    def environment_created(self): 
    5171        """Called when a new Trac environment is created.""" 
     
    5373            self.upgrade_environment(None) 
    5474             
    55     def db_needs_upgrade(self): 
    56         bill_date = dbhelper.db_table_exists(self.env.get_db_cnx(), 'bill_date'); 
    57         report_version = dbhelper.db_table_exists(self.env.get_db_cnx(), 'report_version'); 
    58         val =  dbhelper.db_needs_upgrade(self.env.get_db_cnx()) 
    59         return val or not bill_date or not report_version 
    60          
    61     def db_do_upgrade(self): 
    62         bill_date = dbhelper.db_table_exists(self.env.get_db_cnx(), 'bill_date'); 
    63         report_version = dbhelper.db_table_exists(self.env.get_db_cnx(), 'report_version'); 
    64         if not bill_date: 
     75 
     76    def system_needs_upgrade(self): 
     77        return self.db_installed_version < self.db_version 
     78         
     79    def do_db_upgrade(self): 
     80        # Legacy support hack (supports upgrades from 0.1.6 to 0.1.7) 
     81        if self.db_installed_version == 0: 
     82            bill_date = dbhelper.db_table_exists(self.env.get_db_cnx(), 'bill_date'); 
     83            report_version = dbhelper.db_table_exists(self.env.get_db_cnx(), 'report_version'); 
     84            if bill_date and report_version: 
     85                self.db_installed_version = 1 
     86        # End Legacy support hack 
     87 
     88         
     89        if self.db_installed_version < 1: 
    6590            print "Creating bill_date table" 
    6691            sql = """ 
     
    7398            dbhelper.execute_non_query(self.env.get_db_cnx(), sql) 
    7499             
    75              
    76         if not report_version: 
    77100            print "Creating report_version table" 
    78101            sql = """ 
     
    84107            """ 
    85108            dbhelper.execute_non_query(self.env.get_db_cnx(), sql) 
    86         dbhelper.migrate_up_to_version(self.env.get_db_cnx, dbhelper) 
    87         dbhelper.set_plugin_db_version(self.env.get_db_cnx) 
     109 
     110        if self.db_installed_version < 4: 
     111            print "Upgrading report_version table to v4" 
     112            sql =""" 
     113            ALTER TABLE report_version ADD COLUMN tags varchar(1024) null; 
     114            """ 
     115            dbhelper.execute_non_query(self.env.get_db_cnx(), sql) 
     116 
     117        if self.db_installed_version < 5: 
     118            # In this version we convert to using reportmanager.py 
     119            # The easiest migration path is to remove all the reports!! 
     120            # They will be added back in later but all custom reports will be lost (deleted) 
     121            print "Dropping report_version table" 
     122            sql = "DELETE FROM report " \ 
     123                  "WHERE author=%s AND id IN (SELECT report FROM report_version)" 
     124            dbhelper.execute_non_query(self.env.get_db_cnx(), sql, 'Timing and Estimation Plugin') 
     125 
     126            sql = "DROP TABLE report_version" 
     127            dbhelper.execute_non_query(self.env.get_db_cnx(), sql) 
     128 
     129                 
     130        # This statement block always goes at the end this method 
     131        sql = "UPDATE system SET value=%s WHERE name=%s" 
     132        dbhelper.execute_non_query(self.env.get_db_cnx(), 
     133                                   sql, self.db_version, self.db_version_key) 
     134        self.db_installed_version = self.db_version 
    88135     
    89     def reports_need_upgrade(self): 
    90         bit = False 
    91         report_version = dbhelper.db_table_exists(self.env.get_db_cnx(), 'report_version'); 
    92         if not report_version: 
    93             return True 
    94          
    95         #make versions hash 
    96         try: 
    97             _versions = dbhelper.get_result_set(self.env.get_db_cnx(),""" 
    98                SELECT report as id, version, r.title as title 
    99                FROM report_version 
    100                JOIN report r ON r.Id = report_version.report 
    101                WHERE tags LIKE '%T&E%' """) 
    102         except Exception: 
    103             return True; 
    104         versions = {} 
    105  
    106         if _versions.rows == None: 
    107             return True 
    108  
    109         for (id, version, title) in _versions.rows: 
    110             versions[title] = (id, version) 
    111  
    112              
    113         for report_group in all_reports: 
     136 
     137    def do_reports_upgrade(self): 
     138        self.log.debug( "Beginning Reports Upgrade"); 
     139        mgr = CustomReportManager(self.env, self.log) 
     140        r = __import__("reports", globals(), locals(), ["all_reports"]) 
     141 
     142        for report_group in r.all_reports: 
    114143            rlist = report_group["reports"] 
     144            group_title = report_group["title"] 
    115145            for report in rlist: 
    116146                title = report["title"] 
    117147                new_version = report["version"] 
    118                 #the report map is a list of (id, name) tuples for the reports 
    119                 # here we want to see if our report is in the list 
    120                 idx = [i for i in range(0, len(self.reportmap)) if self.reportmap[i][1] == title] 
    121                 if not idx: 
    122                     self.log.warning("Report '%s' needs to be added" % title) 
    123                     bit = True; 
    124                 else: 
    125                     # If we had a report make sure its at the correct version 
    126                     if versions.has_key(title): 
    127                         (id, ver) = versions[title] 
    128                     else: 
    129                         ver = 0 
    130                     if ver < new_version: 
    131                         bit = True 
    132         return bit 
    133                  
    134     def do_reports_upgrade(self): 
    135         self.log.debug( "Beginning Reports Upgrade"); 
    136         #make version hash 
    137         _versions = dbhelper.get_result_set(self.env.get_db_cnx(), 
    138                                            """ 
    139                                            SELECT report as id, version, r.title as title 
    140                                            FROM report_version 
    141                                            JOIN report r ON r.Id = report_version.report 
    142                                            WHERE tags LIKE '%T&E%' 
    143                                            """) 
    144         versions = {} 
    145         if _versions and _versions.rows: 
    146             for (id, version, title) in _versions.rows: 
    147                 versions[title] = (id, version) 
    148              
    149         biggestId = dbhelper.get_scalar(self.env.get_db_cnx(), 
    150                                         "SELECT ID FROM report ORDER BY ID DESC LIMIT 1") 
    151         def insert_report_version(id, ver, tag): 
    152             sql = "DELETE FROM report_version WHERE report = %s;" 
    153             dbhelper.execute_non_query(self.env.get_db_cnx(), sql, id  ) 
    154             sql = """ 
    155             INSERT INTO report_version (report, version, tags) 
    156             VALUES (%s, %s, %s);""" 
    157             # print "about to insert report_version" 
    158             dbhelper.execute_non_query(self.env.get_db_cnx(), sql, id, ver, tag ) 
    159             # print "inserted report_version" 
    160              
    161         for report_group in all_reports: 
    162             rlist = report_group["reports"] 
    163             group_title = report_group["title"] 
    164             tag = "T&E %s" % group_title 
    165             for report in rlist: 
    166                 title = report["title"] 
    167                 new_version = report["version"] 
    168                 report_id = [rid 
    169                              for (rid, map_title) in self.reportmap 
    170                              if map_title == title] 
    171                 if not report_id: 
    172                     bit = True;  
    173                     sql = """INSERT INTO report (id,author,title,query,description)  
    174                              VALUES (%s,'Timing and Estimation Plugin',%s,%s,'') """ 
    175                     biggestId += 1 
    176                     dbhelper.execute_non_query(self.env.get_db_cnx(), sql, 
    177                                                biggestId, title, report["sql"]) 
    178                     insert_report_version(biggestId, new_version, tag) 
    179  
    180                     report["reportnumber"] = biggestId 
    181                     self.reportmap.extend([(biggestId,title)]) 
    182                 else: 
    183                     report_id = report_id[0] 
    184                     report["reportnumber"] = report_id 
    185                      # If we had a report make sure its at the correct version 
    186                     if versions.has_key(title): 
    187                         ( _ , ver) = versions[title] 
    188                     else: 
    189                         ver = 0 
    190                     if not ver: 
    191                         sql = """ 
    192                         UPDATE report 
    193                         SET query=%s  
    194                         WHERE id = %s """ 
    195                         print "updating report: %s" % title 
    196                         dbhelper.execute_non_query(self.env.get_db_cnx(), sql, 
    197                                                    report["sql"], report_id ) 
    198                         insert_report_version( report_id, new_version, tag ) 
    199                     elif ver < new_version: 
    200                         sql = """ 
    201                         UPDATE report 
    202                         SET query=%s  
    203                         WHERE id = %s """ 
    204                         print "updating report to new version: %s" % title 
    205