Skip to content
This repository
Browse code

Added subticket data check script.

  • Loading branch information...
commit cb202beeee50d6524462846d9487505bf7b1bb75 1 parent 3380c51
itota authored
3  setup.py
@@ -52,6 +52,9 @@
52 52 'tracsubtickets.api = tracsubtickets.api',
53 53 'tracsubtickets.web_ui = tracsubtickets.web_ui',
54 54 ],
  55 + 'console_scripts': [
  56 + 'check-trac-subtickets = tracsubtickets.checker:main',
  57 + ],
55 58 },
56 59 )
57 60
11 tracsubtickets/api.py
@@ -38,14 +38,15 @@
38 38 import db_default
39 39
40 40
  41 +NUMBERS_RE = re.compile(r'\d+', re.U)
  42 +
  43 +
41 44 class SubTicketsSystem(Component):
42 45
43 46 implements(IEnvironmentSetupParticipant,
44 47 ITicketChangeListener,
45 48 ITicketManipulator)
46 49
47   - NUMBERS_RE = re.compile(r'\d+', re.U)
48   -
49 50 # IEnvironmentSetupParticipant methods
50 51 def environment_created(self):
51 52 self.found_db_version = 0
@@ -118,8 +119,8 @@ def ticket_changed(self, ticket, comment, author, old_values):
118 119 return
119 120
120 121 old_parents = old_values.get('parents', '') or ''
121   - old_parents = set(self.NUMBERS_RE.findall(old_parents))
122   - new_parents = set(self.NUMBERS_RE.findall(ticket['parents'] or ''))
  122 + old_parents = set(NUMBERS_RE.findall(old_parents))
  123 + new_parents = set(NUMBERS_RE.findall(ticket['parents'] or ''))
123 124
124 125 if new_parents == old_parents:
125 126 return
@@ -154,7 +155,7 @@ def validate_ticket(self, req, ticket):
154 155
155 156 try:
156 157 ids = []
157   - _ids = set(self.NUMBERS_RE.findall(ticket['parents'] or ''))
  158 + _ids = set(NUMBERS_RE.findall(ticket['parents'] or ''))
158 159 myid = str(ticket.id)
159 160 for id in _ids:
160 161 if id == myid:
97 tracsubtickets/checker.py
... ... @@ -0,0 +1,97 @@
  1 +#!/usr/bin/python
  2 +#
  3 +# Copyright (c) 2010, Takashi Ito
  4 +# All rights reserved.
  5 +#
  6 +# Redistribution and use in source and binary forms, with or without
  7 +# modification, are permitted provided that the following conditions
  8 +# are met:
  9 +# 1. Redistributions of source code must retain the above copyright
  10 +# notice, this list of conditions and the following disclaimer.
  11 +# 2. Redistributions in binary form must reproduce the above copyright
  12 +# notice, this list of conditions and the following disclaimer in the
  13 +# documentation and/or other materials provided with the distribution.
  14 +# 3. Neither the name of the authors nor the names of its contributors
  15 +# may be used to endorse or promote products derived from this software
  16 +# without specific prior written permission.
  17 +#
  18 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19 +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20 +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21 +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  22 +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  23 +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  24 +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  25 +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  26 +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27 +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  28 +# POSSIBILITY OF SUCH DAMAGE.
  29 +
  30 +import sys
  31 +from optparse import OptionParser
  32 +from trac.env import open_environment
  33 +
  34 +from api import NUMBERS_RE
  35 +
  36 +
  37 +def check_subtickets(env):
  38 + db = env.get_db_cnx()
  39 + cursor = db.cursor()
  40 +
  41 + cfield = {}
  42 + cursor.execute("SELECT ticket, value FROM ticket_custom WHERE name='parents'")
  43 + for row in cursor:
  44 + id = row[0]
  45 + parents = [int(x) for x in NUMBERS_RE.findall(row[1])]
  46 + cfield[id] = parents
  47 +
  48 + subtickets = {}
  49 + cursor.execute("SELECT parent, child FROM subtickets")
  50 + for row in cursor:
  51 + parent = int(row[0])
  52 + child = int(row[1])
  53 + if child in subtickets:
  54 + subtickets[child] += [parent]
  55 + else:
  56 + subtickets[child] = [parent]
  57 +
  58 + for id in set(cfield.keys() + subtickets.keys()):
  59 + result = False
  60 + if id in cfield and id in subtickets:
  61 + cfield_values = set(cfield[id])
  62 + subtickets_values = set(subtickets[id])
  63 + if cfield_values == subtickets_values:
  64 + result = True
  65 + elif id not in subtickets:
  66 + if not cfield.get(id):
  67 + result = True
  68 +
  69 + if not result:
  70 + print "Mismatch in ticket #%i" % id
  71 + print " custom field :", cfield.get(id, '--')
  72 + print " subtickets :", subtickets.get(id, '--')
  73 +
  74 +
  75 +def main(args=sys.argv[1:]):
  76 + parser = OptionParser('%prog [options] project <project2> <project3> ...')
  77 + options, args = parser.parse_args(args)
  78 +
  79 + # if no projects, print usage
  80 + if not args:
  81 + parser.print_help()
  82 + sys.exit(0)
  83 +
  84 + # get the environments
  85 + envs = []
  86 + for arg in args:
  87 + env = open_environment(arg)
  88 + envs.append(env)
  89 +
  90 + # check all the environments
  91 + for env in envs:
  92 + check_subtickets(env)
  93 +
  94 +
  95 +if __name__ == '__main__':
  96 + main()
  97 +
8 tracsubtickets/web_ui.py
@@ -35,7 +35,7 @@
35 35 from genshi.builder import tag
36 36 from genshi.filters import Transformer
37 37
38   -from api import SubTicketsSystem
  38 +from api import NUMBERS_RE
39 39
40 40
41 41 class SubTicketsModule(Component):
@@ -45,8 +45,6 @@ class SubTicketsModule(Component):
45 45 ITicketManipulator,
46 46 ITemplateStreamFilter)
47 47
48   - NUMBERS_RE = SubTicketsSystem.NUMBERS_RE
49   -
50 48 # ITemplateProvider methods
51 49 def get_htdocs_dirs(self):
52 50 from pkg_resources import resource_filename
@@ -65,7 +63,7 @@ def post_process_request(self, req, template, data, content_type):
65 63 # get parents data
66 64 ticket = data['ticket']
67 65 parents = ticket['parents'] or ''
68   - ids = set(self.NUMBERS_RE.findall(parents))
  66 + ids = set(NUMBERS_RE.findall(parents))
69 67
70 68 if len(parents) > 0:
71 69 self._append_parent_links(req, data, ids)
@@ -125,7 +123,7 @@ def validate_ticket(self, req, ticket):
125 123 yield None, 'Child ticket #%s has not been closed yet' % child
126 124
127 125 elif action == 'reopen':
128   - ids = set(self.NUMBERS_RE.findall(ticket['parents'] or ''))
  126 + ids = set(NUMBERS_RE.findall(ticket['parents'] or ''))
129 127 for id in ids:
130 128 if Ticket(self.env, id)['status'] == 'closed':
131 129 yield None, 'Parent ticket #%s is closed' % id

0 comments on commit cb202be

Please sign in to comment.
Something went wrong with that request. Please try again.