Changeset 16834
- Timestamp:
- Sep 29, 2017, 5:40:18 PM (8 years ago)
- Location:
- backlogplugin/trunk
- Files:
-
- 4 deleted
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
backlogplugin/trunk/backlog/__init__.py
r12005 r16834 1 import pkg_resources 2 pkg_resources.require('Trac >= 1.0') -
backlogplugin/trunk/backlog/db.py
r13758 r16834 8 8 # you should have received as part of this distribution. 9 9 10 from trac.core import *10 from trac.core import Component, implements 11 11 from trac.db.schema import Table, Column 12 12 from trac.env import IEnvironmentSetupParticipant … … 23 23 Column('owner'), 24 24 Column('description')], 25 #Tickets in backlogs26 25 Table('backlog_ticket', key=('bklg_id', 'tkt_id'))[ 27 26 Column('bklg_id', type='int'), … … 30 29 ] 31 30 31 32 32 # Hard-coded backlogs, which will be replaced by an Admin panel 33 BACKLOGS = [(1, 'Product and Community'), 34 (2, 'Sales and Business Intelligence'), 35 (3, 'Business Development'), 36 (4, 'System Engineering')] 33 BACKLOGS = [(1, 'Product and Community'), 34 (2, 'Sales and Business Intelligence'), 35 (3, 'Business Development'), 36 (4, 'System Engineering')] 37 37 38 38 39 def to_sql(env, table): 39 40 """ Convenience function to get the to_sql for the active connector.""" 40 41 from trac.db.api import DatabaseManager 41 dc = DatabaseManager(env). _get_connector()[0]42 dc = DatabaseManager(env).get_connector()[0] 42 43 return dc.to_sql(table) 43 44 44 def create_ordering_table(db): 45 cursor = db.cursor() 46 try: 47 cursor.execute("SELECT count(*) FROM backlog_ticket") 48 except: 49 cursor.execute(""" 45 46 def create_ordering_table(env): 47 for count, in env.db_query(""" 48 SELECT count(*) FROM backlog_ticket 49 """): 50 break 51 else: 52 env.db_transaction(""" 50 53 CREATE TABLE backlog_ticket (bklg_id INTEGER NOT NULL, 51 54 tkt_id INTEGER NOT NULL, tkt_order REAL, 52 55 PRIMARY KEY(bklg_id, tkt_id))""") 53 56 54 def create_tables(env, db): 57 58 def create_tables(env): 55 59 """ Creates the basic tables as defined by SCHEMA. 56 60 using the active database connector. """ 57 cursor = db.cursor() 58 for table in SCHEMA: 59 for stmt in to_sql(env, table): 60 cursor.execute(stmt) 61 cursor.executemany('INSERT INTO backlog (id, name) VALUES (%s, %s)', BACKLOGS) 62 cursor.execute("INSERT into system values ('backlog_version', %s)", (db_version,)) 61 with env.db_transaction as db: 62 for table in SCHEMA: 63 for stmt in to_sql(env, table): 64 db(stmt) 65 db.executemany(""" 66 INSERT INTO backlog (id, name) VALUES (%s, %s) 67 """, BACKLOGS) 68 db("INSERT into system values ('backlog_version', %s)", (db_version,)) 69 63 70 64 71 def add_custom_fields(env): … … 73 80 config.save() 74 81 75 # Upgrades76 77 pass78 79 # Component that deals with database setup80 82 81 83 class BacklogSetup(Component): … … 84 86 implements(IEnvironmentSetupParticipant) 85 87 86 def environment_created(self ):88 def environment_created(self, db=None): 87 89 """Called when a new Trac environment is created.""" 88 90 pass 89 91 90 def environment_needs_upgrade(self, db ):92 def environment_needs_upgrade(self, db=None): 91 93 """Called when Trac checks whether the environment needs to be upgraded. 92 94 Returns `True` if upgrade is needed, `False` otherwise.""" 93 return self._get_version( db) < db_version95 return self._get_version() < db_version 94 96 95 def upgrade_environment(self, db ):97 def upgrade_environment(self, db=None): 96 98 """Actually perform an environment upgrade, but don't commit as 97 that is done by the common upgrade procedure when all plugins are done.""" 98 if self._get_version(db) == 0: 99 create_tables(self.env, db) 99 that is done by the common upgrade procedure when all plugins are done. 100 """ 101 if self._get_version() == 0: 102 create_tables(self.env) 100 103 add_custom_fields(self.env) 101 104 else: … … 103 106 pass 104 107 105 def _get_version(self, db): 106 cursor = db.cursor() 107 try: 108 sql = "SELECT value FROM system WHERE name='backlog_version'" 109 self.log.debug(sql) 110 cursor.execute(sql) 111 for row in cursor: 112 return int(row[0]) 113 return 0 114 except: 115 return 0 108 def _get_version(self): 109 for row in self.env.db_query(""" 110 SELECT value FROM system WHERE name='backlog_version' 111 """): 112 return int(row[0]) 113 return 0 -
backlogplugin/trunk/backlog/model.py
r13759 r16834 8 8 # you should have received as part of this distribution. 9 9 10 import sys,traceback10 import traceback 11 11 12 12 HARD_DEADLINE_FIELD = 'hard_deadline1' … … 14 14 NO_BACKLOG = 'no backlog' 15 15 16 class BacklogException(Exception): pass 16 17 class BacklogException(Exception): 18 pass 19 17 20 18 21 class Backlog(object): … … 30 33 """ 31 34 self.env = env 32 self.db = self.env.get_db_cnx() 33 34 if name == NO_BACKLOG:name = None35 36 if name == NO_BACKLOG: 37 name = None 35 38 if id: 36 39 self._fetch_by_id(id) … … 48 51 self.name = name 49 52 self.id = self._get_free_id() 50 if(not self.id): return None 51 return self._create() 52 53 def _create(self): 54 "Performs actual insert in DB" 55 try: 56 cursor = self.db.cursor() 57 id = self._get_free_id() 58 sql = "INSERT INTO backlog (id, name) VALUES (%s, %s)" 59 cursor.execute(sql, (self.id, self.name,)) 60 self.db.commit() 61 except: 62 self.env.log.error(traceback.format_exc()) 63 raise BacklogException("Failed to create new backlog") 53 if not self.id: 54 return None 55 self.env.db_transaction(""" 56 INSERT INTO backlog (id, name) VALUES (%s, %s) 57 """, (self.id, self.name,)) 64 58 65 59 return self … … 69 63 Auto-increment emulation, as some DBs don't have it. 70 64 """ 71 try: 72 cursor = self.db.cursor() 73 sql = "SELECT max(id) FROM backlog" 74 cursor.execute(sql) 75 id = cursor.fetchone()[0] + 1 76 except: 77 self.env.log.error(traceback.format_exc()) 78 raise BacklogException("Failed to obtain next free id") 79 return id 65 for id, in self.env.db_query(""" 66 SELECT max(id) FROM backlog 67 """): 68 return id + 1 80 69 81 70 def _fetch_by_id(self, id): … … 84 73 @param id: numeric id of the backlog 85 74 """ 86 assert id, 'id not set'87 75 self.id = int(id) 88 try: 89 cursor = self.db.cursor() 90 sql = "SELECT name, owner, description FROM backlog WHERE id = %s" 91 cursor.execute(sql, (self.id,)) 92 self.name, self.owner, self.description = cursor.fetchone() 93 except: 94 self.env.log.error(traceback.format_exc()) 95 raise BacklogException("Failed to retrieve backlog with id=%s" % self.id) 76 for name, owner, description in self.env.db_query(""" 77 SELECT name, owner, description FROM backlog WHERE id = %s 78 """, (self.id,)): 79 self.name = name 80 self.owner = owner 81 self.description = description 96 82 97 83 def _fetch_by_name(self, name): … … 100 86 @param name: textual name of the backlog 101 87 """ 102 try: 103 cursor = self.db.cursor() 104 sql = "SELECT id FROM backlog WHERE name = %s" 105 cursor.execute(sql, (name,)) 106 self.id = cursor.fetchone()[0] 107 except: 108 self.env.log.error(traceback.format_exc()) 109 raise BacklogException("Failed to retrieve backlog with name=%s" % name) 88 for id, in self.env.db_query(""" 89 SELECT id FROM backlog WHERE name = %s 90 """, (name,)): 91 self.id = id 110 92 self._fetch_by_id(self.id) 111 93 … … 117 99 @param all_in_one: should all tickets be returned in one list 118 100 """ 119 try: 120 cursor = self.db.cursor() 121 #get name 122 columns = ['id', 'summary', 'component', 'description', 'version', 'type', 'milestone', 'owner', 'status', 'time', 'tkt_order', 'keywords'] 123 sql = """SELECT %s,tc.value as hard_deadline, tc2.value as impact 124 FROM backlog_ticket b, ticket t 125 LEFT OUTER JOIN ticket_custom tc 126 ON t.id = tc.ticket 127 AND tc.name = '%s' 128 LEFT OUTER JOIN ticket_custom tc2 129 ON t.id = tc2.ticket 130 AND tc2.name = '%s' 131 WHERE t.id = b.tkt_id 132 AND b.bklg_id = %%s 133 AND (b.tkt_order IS NULL OR b.tkt_order > -1) 134 ORDER BY b.tkt_order, t.time DESC""" % (','.join(columns), HARD_DEADLINE_FIELD, IMPACT_FIELD) 135 columns.extend(('hard_deadline', 'impact')) 136 self.env.log.info('GET_TICKETS sql = """%s"""' % sql) 137 cursor.execute(sql, (self.id,)) 138 all_tickets = [dict(zip(columns, ticket)) for ticket in cursor] #creating list of column:value dictionaries 139 #self.env.log.info('ALL_TICKETS = %s'%all_tickets) 140 141 except: 142 self.env.log.error(traceback.format_exc()) 143 raise BacklogException("Failed to retrieve ticket data for backlog %s" % self.name) 101 columns = ['id', 'summary', 'component', 'description', 'version', 102 'type', 'milestone', 'owner', 'status', 'time', 103 'tkt_order', 'keywords'] 104 sql = """SELECT %s,tc.value as hard_deadline, tc2.value as impact 105 FROM backlog_ticket b, ticket t 106 LEFT OUTER JOIN ticket_custom tc 107 ON t.id = tc.ticket 108 AND tc.name = '%s' 109 LEFT OUTER JOIN ticket_custom tc2 110 ON t.id = tc2.ticket 111 AND tc2.name = '%s' 112 WHERE t.id = b.tkt_id 113 AND b.bklg_id = %%s 114 AND (b.tkt_order IS NULL OR b.tkt_order > -1) 115 ORDER BY b.tkt_order, t.time DESC 116 """ % (','.join(columns), HARD_DEADLINE_FIELD, IMPACT_FIELD) 117 columns.extend(('hard_deadline', 'impact')) 118 all_tickets = [dict(zip(columns, ticket)) 119 for ticket in self.env.db_query(sql, (self.id,))] 144 120 145 121 if all_in_one: 146 122 return all_tickets 147 123 148 # splitting ordered and unordered124 # Splitting ordered and unordered 149 125 ordered_tickets, unordered_tickets = [], [] 150 126 for ticket in all_tickets: … … 161 137 """ 162 138 assert self.id, 'id not set' 163 order = [ (self.id, int(tkt_id), tkt_order + 1) for (tkt_order, tkt_id) in enumerate(order)]164 # print 'order', order165 try:166 cursor = self.db.cursor()167 cursor.executemany('REPLACE INTO backlog_ticket (bklg_id, tkt_id, tkt_order) VALUES (%s, %s, %s)', order)168 self.db.commit()169 except:170 self.env.log.error(traceback.format_exc())171 raise BacklogException("Failed to save order for backlog %s" % self.name)139 order = [(tkt_order + 1, self.id, int(tkt_id)) 140 for (tkt_order, tkt_id) in enumerate(order)] 141 print(order) 142 with self.env.db_transaction as db: 143 db.executemany(""" 144 UPDATE backlog_ticket 145 SET tkt_order=%s, bklg_id=%s 146 WHERE tkt_id=%s 147 """, order) 172 148 173 149 def add_ticket(self, tkt_id): 174 150 """ 175 adds the ticket to this backlog, also removing it from previous backlog if any 151 adds the ticket to this backlog, also removing it from previous 152 backlog if any 176 153 @param tkt_id: ticket's ID 177 154 """ 178 try: 179 cursor = self.db.cursor() 180 cursor.execute('DELETE FROM backlog_ticket WHERE tkt_id = %s', (tkt_id,)) 181 cursor.execute('INSERT INTO backlog_ticket (bklg_id, tkt_id) VALUES (%s, %s)', (self.id, tkt_id)) 182 self.db.commit() 183 except: 184 self.env.log.error(traceback.format_exc()) 185 raise BacklogException("Failed to add ticket %s to backlog %s" 186 % (tkt_id, getattr(self, 'name', None))) 155 with self.env.db_transaction as db: 156 db(""" 157 DELETE FROM backlog_ticket WHERE tkt_id=%s 158 """, (tkt_id,)) 159 db(""" 160 INSERT INTO backlog_ticket (bklg_id, tkt_id) 161 VALUES (%s, %s) 162 """, (self.id, tkt_id)) 187 163 188 164 def reset_priority(self, tkt_id, only_if_deleted=False): … … 190 166 resets the ticket's priority to NULL (unordered) 191 167 @param tkt_id: ID or sequence of IDs of ticket(s) 192 @param only_if_deleted: reset the priority only if ticket was deleted as closed (archived) 193 """ 168 @param only_if_deleted: reset the priority only if ticket was deleted 169 as closed (archived) 170 """ 171 sql = "UPDATE backlog_ticket SET tkt_order = NULL WHERE tkt_id=%s" 172 if only_if_deleted: 173 sql += " AND tkt_order = -1" 194 174 try: 195 cursor = self.db.cursor() 196 sql = 'UPDATE backlog_ticket SET tkt_order = NULL WHERE tkt_id = %s' 197 if(only_if_deleted): 198 sql += ' AND tkt_order = -1' 199 try: 200 tkt_ids = [(id,) for id in tkt_id] # trying to iterate to see if it's a list 201 cursor.executemany(sql, tkt_ids) 202 except TypeError: #single id 203 cursor.execute(sql, (tkt_id,)) 204 self.db.commit() 205 except: 206 self.env.log.error(traceback.format_exc()) 207 raise BacklogException("Failed to reset priority for ticket(s) %s " % (tkt_id,)) 175 tkt_ids = [(id,) for id in tkt_id] # List 176 except TypeError: # Single id 177 self.env.db_transaction(sql, (tkt_id,)) 178 else: 179 with self.env.db_transaction as db: 180 db.executemany(sql, tkt_ids) 208 181 209 182 def delete_ticket(self, tkt_id): … … 212 185 @param tkt_id: ID of ticket 213 186 """ 214 if(not getattr(self, 'id')): 215 self.env.log.warn('trying to delete ticket from uninitialized backlog') 187 if not getattr(self, 'id'): 188 self.env.log.warn("Attempt to delete ticket from uninitialized " 189 "backlog") 216 190 return 217 try: 218 cursor = self.db.cursor() 219 cursor.execute('DELETE FROM backlog_ticket WHERE bklg_id = %s AND tkt_id = %s', (self.id, tkt_id)) 220 self.db.commit() 221 except: 222 self.env.log.error(traceback.format_exc()) 223 raise BacklogException("Failed to delete ticket %s from backlog" % (tkt_id,)) 191 self.env.db_transaction(""" 192 DELETE FROM backlog_ticket WHERE bklg_id = %s AND tkt_id = %s 193 """, (self.id, tkt_id)) 224 194 225 195 def remove_closed_tickets(self): … … 228 198 """ 229 199 assert self.id, 'id not set' 230 sql = """UPDATE backlog_ticket SET tkt_order = -1 231 WHERE bklg_id = %s 232 AND tkt_id IN (SELECT id FROM ticket 233 WHERE status = 'closed')""" 234 try: 235 cursor = self.db.cursor() 236 cursor.execute(sql, (self.id,)) 237 self.db.commit() 238 except: 239 self.env.log.error(traceback.format_exc()) 240 raise BacklogException("Failed to clean up closed tickets in backlog %s" % (tkt_id, self.name)) 200 self.env.db_transaction(""" 201 UPDATE backlog_ticket SET tkt_order = -1 202 WHERE bklg_id = %s 203 AND tkt_id IN (SELECT id FROM ticket WHERE status = 'closed') 204 """, (self.id,)) 241 205 242 206 def name2perm(self): 243 """ 244 c reates string appropriate for Trac's permission system from current backlog's name207 """Creates string appropriate for Trac's permission system from 208 current backlog's name 245 209 """ 246 210 import re … … 256 220 """ 257 221 self.env = env 258 try: 259 db = env.get_db_cnx() 260 cursor = db.cursor() 261 cursor.execute("SELECT id FROM backlog ORDER BY id") 262 self.backlogs = (Backlog(env, row[0]) for row in cursor) 263 except: 264 self.env.log.error(traceback.format_exc()) 265 self.backlogs = () 222 self.backlogs = [Backlog(env, row[0]) 223 for row in self.env.db_query(""" 224 SELECT id FROM backlog ORDER BY id 225 """)] 266 226 267 227 def __iter__(self): -
backlogplugin/trunk/backlog/tests/__init__.py
r15264 r16834 9 9 from unittest import TestSuite 10 10 11 11 12 def test_suite(): 12 13 suite = TestSuite() -
backlogplugin/trunk/backlog/tests/web_ui.py
r15264 r16834 11 11 from backlog.web_ui import BacklogModule 12 12 13 13 14 class BacklogRequestHandlerTestCase(unittest.TestCase): 14 15 … … 22 23 pass 23 24 25 24 26 def test_suite(): 25 27 suite = unittest.TestSuite() … … 27 29 return suite 28 30 31 29 32 if __name__ == '__main__': 30 unit est.main(defaultTest='test_suite')33 unittest.main(defaultTest='test_suite') -
backlogplugin/trunk/backlog/ticketchangelistener.py
r13759 r16834 13 13 from model import * 14 14 15 15 16 class BacklogTicketChangeListener(Component): 16 " Listens to the changes of tickets and updates backlogs if necessary"17 """Listens to the changes of tickets and updates backlogs if necessary""" 17 18 18 19 implements(ITicketChangeListener) … … 30 31 pass 31 32 32 33 33 def ticket_changed(self, ticket, comment, author, old_values): 34 34 """Called when a ticket is modified. Adds and removes tickets … … 40 40 if 'backlog' in old_values.keys(): 41 41 if backlog_name == NO_BACKLOG: 42 if old_values['backlog'] and old_values['backlog'] != NO_BACKLOG: 42 if old_values['backlog'] and \ 43 old_values['backlog'] != NO_BACKLOG: 43 44 Backlog(self.env, name=old_values['backlog']).delete_ticket(ticket.id) 44 45 else: -
backlogplugin/trunk/backlog/web_ui.py
r13758 r16834 8 8 # you should have received as part of this distribution. 9 9 10 from genshi.builder import tag11 from trac import __version__ as trac_version12 10 from trac.admin import IAdminPanelProvider 13 11 from trac.core import Component, TracError, implements 14 from trac.perm import IPermissionRequestor, PermissionCache, PermissionError 15 from trac.ticket.api import ITicketChangeListener, TicketSystem 12 from trac.perm import IPermissionRequestor 13 from trac.ticket.api import TicketSystem 14 from trac.util.html import html as tag 16 15 from trac.util.translation import _ 17 from trac.web import IRequestHandler16 from trac.web.api import IRequestHandler 18 17 from trac.web.chrome import ( 19 18 INavigationContributor, ITemplateProvider, add_stylesheet, add_script, … … 40 39 enum_cls = type(str(enum_col), (AbstractEnum,), {}) 41 40 enum_cls.type = enum_col 42 db = self.env.get_db_cnx() 43 field['options'] = [val.name for val in enum_cls.select(self.env, db=db)] 41 field['options'] = [val.name for val in enum_cls.select(self.env)] 44 42 45 43 return fields … … 99 97 def process_request(self, req): 100 98 req.perm.require('BACKLOG_VIEW') 101 db = self.env.get_db_cnx() 102 create_ordering_table(db) 99 create_ordering_table(self.env) 103 100 backlog_id = req.args.get('backlog_id') 104 101 if req.method == 'POST': … … 106 103 req.redirect(req.href.backlog(backlog_id)) 107 104 108 self._add_jquery_ui(req)105 Chrome(self.env).add_jquery_ui(req) 109 106 add_stylesheet(req, 'backlog/css/backlog.css') 110 107 … … 113 110 else: 114 111 return self._show_backlog_list(req) 115 116 def _add_jquery_ui(self, req):117 if hasattr(Chrome, 'add_jquery_ui'):118 Chrome(self.env).add_jquery_ui(req)119 return120 121 from pkg_resources import parse_version122 if parse_version(trac_version) >= parse_version('0.12'):123 add_script(req, 'backlog/js/jquery-ui-1.8.23.custom.min.js')124 else:125 add_script(req, 'backlog/js/jquery-ui-1.6.min.js')126 add_stylesheet(req, 'backlog/css/jquery-ui.custom.css')127 112 128 113 def _show_backlog(self, req, backlog_id): … … 141 126 142 127 def _show_backlog_list(self, req): 143 db = self.env.get_db_cnx()144 backlog_id = req.args.get('backlog_id', None)145 146 128 columns = ['id', 'name', 'owner', 'description'] 147 148 cursor = db.cursor()149 sql = """SELECT %s, 0 as total, 0 as active150 FROM backlog151 """ % (','.join(columns))152 cursor.execute(sql)153 154 columns.extend(['total', 'active'])155 156 129 data = {} 157 data['backlogs'] = dict([(backlog[0], (dict(zip(columns, backlog)))) for backlog in cursor]) 130 data['backlogs'] = \ 131 dict([(backlog[0], 132 (dict(zip(columns + ['total', 'active'], backlog)))) 133 for backlog in self.env.db_query(""" 134 SELECT %s, 0 as total, 0 as active FROM backlog 135 """ % (','.join(columns)))]) 158 136 159 137 # get total of tickets in each backlog 160 sql = """SELECT bklg_id, count(*) as total 161 FROM backlog_ticket 162 WHERE tkt_order IS NULL OR tkt_order > -1 163 GROUP BY bklg_id 164 """ 165 cursor.execute(sql) 166 167 for id, total in cursor: 138 for id, total in self.env.db_query(""" 139 SELECT bklg_id, COUNT(*) as total FROM backlog_ticket 140 WHERE tkt_order IS NULL OR tkt_order > -1 141 GROUP BY bklg_id 142 """): 168 143 data['backlogs'][id]['total'] = total 169 144 data['backlogs'][id]['closed'] = 0 … … 171 146 172 147 # get total of tickets by status in each backlog 173 sql = """SELECT bt.bklg_id, t.status, count(*) as total 174 FROM backlog_ticket bt, ticket t 175 WHERE t.id = bt.tkt_id 148 for id, status, total in self.env.db_query(""" 149 SELECT bt.bklg_id, t.status, COUNT(*) as total 150 FROM backlog_ticket bt, ticket t 151 WHERE t.id = bt.tkt_id 176 152 AND (bt.tkt_order IS NULL OR bt.tkt_order > -1) 177 GROUP BY bklg_id, status 178 """ 179 cursor.execute(sql) 180 181 for id, status, total in cursor: 182 if(status == 'closed'): 153 GROUP BY bklg_id, status 154 """): 155 if status == 'closed': 183 156 data['backlogs'][id]['closed'] += total 184 157 else: … … 191 164 req.perm.require('BACKLOG_MODIFY') 192 165 backlog = Backlog(self.env, backlog_id) 193 #db = self.env.get_db_cnx() 194 #cursor = db.cursor() 166 print(req.args) 195 167 if req.args.get('remove_tickets'): 196 168 backlog.remove_closed_tickets() 197 169 if req.args.get('ticket_order'): 198 170 ticket_order = req.args.get('ticket_order').split(',') 199 ticket_order = [int(tkt_id.split('_')[1]) for tkt_id in ticket_order] 171 ticket_order = [int(tkt_id.split('_')[1]) 172 for tkt_id in ticket_order] 200 173 backlog.set_ticket_order(ticket_order) 201 #ticket_order = [ (bklg_id, int(tkt_id.split('_')[1]), int(tkt_order)) for (tkt_order, tkt_id) in enumerate(ticket_order)]202 #cursor.executemany('REPLACE INTO backlog_tkt (bklg_id, tkt_id, tkt_order) VALUES (%s, %s, %s)', ticket_order)203 174 if req.args.get('tickets_out'): 204 175 tickets_out = req.args.get('tickets_out').split(',') 205 176 tickets_out = [int(tkt_id.split('_')[1]) for tkt_id in tickets_out] 206 177 backlog.reset_priority(tickets_out) 207 #cursor.executemany('DELETE FROM backlog_ticket WHERE bklg_id=%s AND tkt_id=%s', tickets_out)208 #db.commit()209 178 210 179 # IPermissionRequestor methods -
backlogplugin/trunk/setup.cfg
r13758 r16834 1 1 [egg_info] 2 2 tag_build = dev 3 tag_svn_revision = true -
backlogplugin/trunk/setup.py
r13758 r16834 10 10 11 11 from setuptools import find_packages, setup 12 import sys13 12 14 13 name = 'BacklogPlugin' 15 version = '0.2' 16 min_trac_version = '0.11.1' 17 18 # Check for minimum required Trac version 19 try: 20 import trac 21 if trac.__version__ < min_trac_version: 22 print "%s %s requires Trac >= %s" % (name, version, min_trac_version) 23 sys.exit(1) 24 except ImportError: 25 print "Trac not found" 26 sys.exit(1) 14 version = '0.3' 27 15 28 16 setup( … … 34 22 maintainer='Ryan J Ollos', 35 23 maintainer_email='ryan.j.ollos@gmail.com', 36 url='http ://trac-hacks.org/wiki/BacklogPlugin',24 url='https://trac-hacks.org/wiki/BacklogPlugin', 37 25 license='BSD', 38 26 description="""Organize tickets within backlogs.""",
Note: See TracChangeset
for help on using the changeset viewer.