Changeset 2199
- Timestamp:
- 04/26/07 15:39:48 (2 years ago)
- Files:
-
- scrumburndownplugin/burndown/burndown.py (modified) (8 diffs)
- scrumburndownplugin/burndown/templates/burndown.cs (modified) (1 diff)
- scrumburndownplugin/setup.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
scrumburndownplugin/burndown/burndown.py
r2062 r2199 10 10 11 11 import time 12 import datetime 12 13 import sys 13 14 … … 21 22 class BurndownComponent(Component): 22 23 implements(IEnvironmentSetupParticipant, INavigationContributor, 23 IRequestHandler, ITemplateProvider, IPermissionRequestor )24 IRequestHandler, ITemplateProvider, IPermissionRequestor, ITicketChangeListener) 24 25 25 26 #--------------------------------------------------------------------------- … … 30 31 31 32 def environment_needs_upgrade(self, db): 33 self.log.debug('burndown plugin - environment needs upgrade') 32 34 needsUpgrade = False 33 35 … … 112 114 for s in sqlMilestone: 113 115 cursor.execute(s) 116 117 #--------------------------------------------------------------------------- 118 # ITicketChangeListener methods 119 #--------------------------------------------------------------------------- 120 121 def ticket_created(self, ticket): 122 update_burndown_data() 123 124 def ticket_changed(self, ticket, comment, author, old_values): 125 update_burndown_data() 126 127 def ticket_deleted(self, ticket): 128 update_burndown_data() 114 129 115 130 #--------------------------------------------------------------------------- … … 117 132 #--------------------------------------------------------------------------- 118 133 def get_active_navigation_item(self, req): 119 return 'burndown' 120 134 if re.search('/burndown', req.path_info): 135 return "burndown" 136 else: 137 return "" 138 121 139 def get_navigation_items(self, req): 122 yield 'mainnav', 'burndown', Markup('<a href="%s">Burndown</a>', self.env.href.burndown()) 123 140 if req.perm.has_permission("BURNDOWN_VIEW"): 141 yield 'mainnav', 'burndown', Markup('<a href="%s">Burndown</a>', self.env.href.burndown()) 142 124 143 #--------------------------------------------------------------------------- 125 144 # IPermissionRequestor methods … … 170 189 171 190 if req.args.has_key('start'): 172 self.start Milestone(db, selected_milestone)191 self.start_milestone(db, selected_milestone) 173 192 else: 174 193 req.hdf['draw_graph'] = True 175 req.hdf['burndown_data'] = self.get BurndownData(db, selected_milestone, components, selected_component) # this will be a list of (id, hours_remaining) tuples194 req.hdf['burndown_data'] = self.get_burndown_data(db, selected_milestone, components, selected_component) # this will be a list of (id, hours_remaining) tuples 176 195 177 196 add_stylesheet(req, 'hw/css/burndown.css') 178 197 return 'burndown.cs', None 179 198 180 def get BurndownData(self, db, selected_milestone, components, selected_component):199 def get_burndown_data(self, db, selected_milestone, components, selected_component): 181 200 cursor = db.cursor() 182 201 … … 214 233 return burndown_data 215 234 216 def start Milestone(self, db, milestone):235 def start_milestone(self, db, milestone): 217 236 cursor = db.cursor() 218 237 cursor.execute("SELECT started FROM milestone WHERE name = '%s'" % milestone) … … 250 269 from pkg_resources import resource_filename 251 270 return [('hw', resource_filename(__name__, 'htdocs'))] 271 272 273 #------------------------------------------------------------------------ 274 # update_burndown_data 275 # - add up the hours remaining for the open tickets for each open milestone and put the sums into the burndown table 276 #------------------------------------------------------------------------ 277 def update_burndown_data(): 278 is_weekly = BoolOption('burndown', 'is_weekly', False, """Boolean for whether the unit of time for the burndown chart is a week or a day.""") 279 280 db = self.env.get_db_cnx() 281 cursor = db.cursor() 282 283 # today's date 284 if is_weekly: 285 today = datetime.date.today() 286 today_year = today.strftime("%Y") 287 today_week = today.strftime("%W") 288 289 # make sure that there isn't already an entry for this week in the burndown table 290 cursor.execute("SELECT id FROM burndown WHERE week = '%s' and year = '%s'" % (today_week, today_year)) 291 else: 292 today = format_date(int(time.time())) 293 294 # make sure that there isn't already an entry for today in the burndown table 295 cursor.execute("SELECT id FROM burndown WHERE date = '%s'" % today) 296 297 row = cursor.fetchone() 298 needs_update = False 299 if row: 300 print >> sys.stderr, 'update_burndown_data has already been run - update needed' 301 needs_update = True 302 else: 303 print >> sys.stderr, 'first run of update_burndown_data - insert needed' 304 305 # get arrays of the various components and milestones in the trac environment 306 cursor.execute("SELECT name AS comp FROM component") 307 components = cursor.fetchall() 308 cursor.execute("SELECT name, started, completed FROM milestone") 309 milestones = cursor.fetchall() 310 311 for mile in milestones: 312 if mile[1] and not mile[2]: # milestone started, but not completed 313 for comp in components: 314 sqlSelect = "SELECT est.value AS estimate, ts.value AS spent "\ 315 "FROM ticket t "\ 316 " LEFT OUTER JOIN ticket_custom est ON (t.id = est.ticket AND est.name = 'estimatedhours') "\ 317 " LEFT OUTER JOIN ticket_custom ts ON (t.id = ts.ticket AND ts.name = 'totalhours') "\ 318 "WHERE t.component = '%s' AND t.milestone = '%s'"\ 319 " AND status IN ('new', 'assigned', 'reopened') " 320 cursor.execute(sqlSelect % (comp[0], mile[0])) 321 322 rows = cursor.fetchall() 323 hours = 0 324 estimate = 0 325 spent = 0 326 if rows: 327 for estimate, spent in rows: 328 if not estimate: 329 estimate = 0 330 if not spent: 331 spent = 0 332 333 hours += float(estimate) - float(spent) 334 335 if needs_update: 336 if is_weekly: 337 cursor.execute("UPDATE burndown SET hours_remaining = '%f' WHERE week = '%s' AND year = '%s' AND milestone_name = '%s'"\ 338 "AND component_name = '%s'" % (hours, today_week, today_year, mile[0], comp[0])) 339 else: 340 cursor.execute("UPDATE burndown SET hours_remaining = '%f' WHERE date = '%s' AND milestone_name = '%s'"\ 341 "AND component_name = '%s'" % (hours, today, mile[0], comp[0])) 342 else: 343 if is_weekly: 344 cursor.execute("INSERT INTO burndown(id,component_name, milestone_name, week, year, hours_remaining) "\ 345 " VALUES(NULL,'%s','%s','%s','%s',%f)" % (comp[0], mile[0], today_week, today_year, hours)) 346 else: 347 cursor.execute("INSERT INTO burndown(id,component_name, milestone_name, date, hours_remaining) "\ 348 " VALUES(NULL,'%s','%s','%s',%f)" % (comp[0], mile[0], today, hours)) 349 350 db.commit() scrumburndownplugin/burndown/templates/burndown.cs
r2056 r2199 6 6 </div> 7 7 8 <form action="<?cs var:burndown.href ?>" method=" post">8 <form action="<?cs var:burndown.href ?>" method="get"> 9 9 <label for="selected_milestone">Select milestone:</label> 10 10 <select id="selected_milestone" name="selected_milestone"> scrumburndownplugin/setup.py
r2062 r2199 2 2 3 3 PACKAGE = 'TracBurndown' 4 VERSION = '01.0 7.10' # the last two decimals are meant to signify the Trac version4 VERSION = '01.08.10' # the last two decimals are meant to signify the Trac version 5 5 6 6 setup(name=PACKAGE,
