Permalink
Browse files

Added subticket data check script.

  • Loading branch information...
1 parent 3380c51 commit cb202beeee50d6524462846d9487505bf7b1bb75 @itota committed Apr 11, 2010
Showing with 109 additions and 10 deletions.
  1. +3 −0 setup.py
  2. +6 −5 tracsubtickets/api.py
  3. +97 −0 tracsubtickets/checker.py
  4. +3 −5 tracsubtickets/web_ui.py
View
3 setup.py
@@ -52,6 +52,9 @@
'tracsubtickets.api = tracsubtickets.api',
'tracsubtickets.web_ui = tracsubtickets.web_ui',
],
+ 'console_scripts': [
+ 'check-trac-subtickets = tracsubtickets.checker:main',
+ ],
},
)
View
11 tracsubtickets/api.py
@@ -38,14 +38,15 @@
import db_default
+NUMBERS_RE = re.compile(r'\d+', re.U)
+
+
class SubTicketsSystem(Component):
implements(IEnvironmentSetupParticipant,
ITicketChangeListener,
ITicketManipulator)
- NUMBERS_RE = re.compile(r'\d+', re.U)
-
# IEnvironmentSetupParticipant methods
def environment_created(self):
self.found_db_version = 0
@@ -118,8 +119,8 @@ def ticket_changed(self, ticket, comment, author, old_values):
return
old_parents = old_values.get('parents', '') or ''
- old_parents = set(self.NUMBERS_RE.findall(old_parents))
- new_parents = set(self.NUMBERS_RE.findall(ticket['parents'] or ''))
+ old_parents = set(NUMBERS_RE.findall(old_parents))
+ new_parents = set(NUMBERS_RE.findall(ticket['parents'] or ''))
if new_parents == old_parents:
return
@@ -154,7 +155,7 @@ def validate_ticket(self, req, ticket):
try:
ids = []
- _ids = set(self.NUMBERS_RE.findall(ticket['parents'] or ''))
+ _ids = set(NUMBERS_RE.findall(ticket['parents'] or ''))
myid = str(ticket.id)
for id in _ids:
if id == myid:
View
97 tracsubtickets/checker.py
@@ -0,0 +1,97 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2010, Takashi Ito
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. Neither the name of the authors nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+import sys
+from optparse import OptionParser
+from trac.env import open_environment
+
+from api import NUMBERS_RE
+
+
+def check_subtickets(env):
+ db = env.get_db_cnx()
+ cursor = db.cursor()
+
+ cfield = {}
+ cursor.execute("SELECT ticket, value FROM ticket_custom WHERE name='parents'")
+ for row in cursor:
+ id = row[0]
+ parents = [int(x) for x in NUMBERS_RE.findall(row[1])]
+ cfield[id] = parents
+
+ subtickets = {}
+ cursor.execute("SELECT parent, child FROM subtickets")
+ for row in cursor:
+ parent = int(row[0])
+ child = int(row[1])
+ if child in subtickets:
+ subtickets[child] += [parent]
+ else:
+ subtickets[child] = [parent]
+
+ for id in set(cfield.keys() + subtickets.keys()):
+ result = False
+ if id in cfield and id in subtickets:
+ cfield_values = set(cfield[id])
+ subtickets_values = set(subtickets[id])
+ if cfield_values == subtickets_values:
+ result = True
+ elif id not in subtickets:
+ if not cfield.get(id):
+ result = True
+
+ if not result:
+ print "Mismatch in ticket #%i" % id
+ print " custom field :", cfield.get(id, '--')
+ print " subtickets :", subtickets.get(id, '--')
+
+
+def main(args=sys.argv[1:]):
+ parser = OptionParser('%prog [options] project <project2> <project3> ...')
+ options, args = parser.parse_args(args)
+
+ # if no projects, print usage
+ if not args:
+ parser.print_help()
+ sys.exit(0)
+
+ # get the environments
+ envs = []
+ for arg in args:
+ env = open_environment(arg)
+ envs.append(env)
+
+ # check all the environments
+ for env in envs:
+ check_subtickets(env)
+
+
+if __name__ == '__main__':
+ main()
+
View
8 tracsubtickets/web_ui.py
@@ -35,7 +35,7 @@
from genshi.builder import tag
from genshi.filters import Transformer
-from api import SubTicketsSystem
+from api import NUMBERS_RE
class SubTicketsModule(Component):
@@ -45,8 +45,6 @@ class SubTicketsModule(Component):
ITicketManipulator,
ITemplateStreamFilter)
- NUMBERS_RE = SubTicketsSystem.NUMBERS_RE
-
# ITemplateProvider methods
def get_htdocs_dirs(self):
from pkg_resources import resource_filename
@@ -65,7 +63,7 @@ def post_process_request(self, req, template, data, content_type):
# get parents data
ticket = data['ticket']
parents = ticket['parents'] or ''
- ids = set(self.NUMBERS_RE.findall(parents))
+ ids = set(NUMBERS_RE.findall(parents))
if len(parents) > 0:
self._append_parent_links(req, data, ids)
@@ -125,7 +123,7 @@ def validate_ticket(self, req, ticket):
yield None, 'Child ticket #%s has not been closed yet' % child
elif action == 'reopen':
- ids = set(self.NUMBERS_RE.findall(ticket['parents'] or ''))
+ ids = set(NUMBERS_RE.findall(ticket['parents'] or ''))
for id in ids:
if Ticket(self.env, id)['status'] == 'closed':
yield None, 'Parent ticket #%s is closed' % id

0 comments on commit cb202be

Please sign in to comment.