~lool/launchpad-work-items-tracker/backlog-timestamp-in-2099

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#!/usr/bin/python
#
# Create HTML/JSON reports and burndown charts for all teams and milestones
# from a configuration file
#
# Copyright (C) 2010, 2011 Canonical Ltd.
# License: GPL-3

import optparse, os.path, sys, errno

import report_tools

#
# main
#

# argv parsing
optparser = optparse.OptionParser()
optparser.add_option('-d', '--database',
        help='Path to database', dest='database', metavar='PATH')
optparser.add_option('-c', '--config',
        help='Path to configuration file (if given, this can read adjusted trend lines start values)',
        dest='config', metavar='PATH')
optparser.add_option('-o', '--output', metavar='DIRECTORY',
        help='Output directory', dest='output_dir')
optparser.add_option('-a', '--all-milestones',
        help='Regnerate all milestones, even those that were due before today',
        dest='all_milestones', default=False, action='store_true')
optparser.add_option('--root', dest="root", help="Root URL for the pages.")

(opts, args) = optparser.parse_args()
if not opts.database:
    optparser.error('No database given')
if not opts.output_dir:
    optparser.error('No output directory given')
if not os.path.isdir(opts.output_dir):
    optparser.error('output directory does not exist')

if opts.config:
    cfg = report_tools.load_config(opts.config)
    trend_starts = cfg.get('trend_start', {})
    burnup_chart_teams = cfg.get('burnup_chart_teams', [])
    primary_team = cfg.get("primary_team", None)
else:
    cfg = None
    trend_starts = {}
    burnup_chart_teams = []
    primary_team = None

lock_path = opts.database + ".lock"
lock_f = open(lock_path, "wb")
if report_tools.lock_file(lock_f) is None:
    print "Another instance is already running"
    sys.exit(0)

store = report_tools.get_store(opts.database)

# get milestones and teams
if opts.all_milestones:
    result = store.execute('SELECT name FROM milestones')
else:
    result = store.execute("SELECT name FROM milestones WHERE due_date >= date('now')")
milestones = [i[0] for i in result]
print 'regenerating milestones: %s' % ','.join(milestones)
result = store.execute('SELECT DISTINCT team FROM teams WHERE team IS NOT NULL')
teams = [i[0] for i in result]
result = store.execute('SELECT DISTINCT name FROM teams')
users = [i[0] for i in result]
result = store.execute('SELECT DISTINCT name FROM spec_groups')
groups = [i[0] for i in result]

my_path = os.path.dirname(sys.argv[0])

usersubdir = os.path.join(opts.output_dir, 'u')
try:
    os.mkdir(usersubdir)
except OSError as exc:
    if exc.errno == errno.EEXIST:
        pass
    else:
        raise

groupssubdir = os.path.join(opts.output_dir, 'group')
try:
    os.mkdir(groupssubdir)
except OSError as exc:
    if exc.errno == errno.EEXIST:
        pass
    else:
        raise

lanessubdir = os.path.join(opts.output_dir, '..', 'lane')
try:
    os.mkdir(lanessubdir)
except OSError as exc:
    if exc.errno == errno.EEXIST:
        pass
    else:
        raise

cardssubdir = os.path.join(opts.output_dir, '..', 'card')
try:
    os.mkdir(cardssubdir)
except OSError as exc:
    if exc.errno == errno.EEXIST:
        pass
    else:
        raise

for u in users:
    for m in milestones:
        target = u + '-' + m
        basename = os.path.join(usersubdir, target)
        report_tools.run_reports(my_path, opts.database, basename, opts.config, milestone=m, user=u, trend_starts=trend_starts, burnup=u in burnup_chart_teams, root=opts.root)
    # entire cycle report for user
    basename = os.path.join(usersubdir, u)
    report_tools.run_reports(my_path, opts.database, basename, opts.config, milestone=None, user=u, trend_starts=trend_starts, burnup=u in burnup_chart_teams, root=opts.root)

# per team/milestone reports
for t in teams:
    for m in milestones:
        basename = os.path.join(opts.output_dir, '%s-%s' % (t, m))
        report_tools.run_reports(my_path, opts.database, basename, opts.config, milestone=m, team=t, trend_starts=trend_starts, burnup=t in burnup_chart_teams, root=opts.root)

    # entire cycle report for team
    basename = os.path.join(opts.output_dir, t)
    report_tools.run_reports(my_path, opts.database, basename, opts.config, milestone=None, team=t, trend_starts=trend_starts, root=opts.root)

# all teams per-milestone
for m in milestones:
    basename = os.path.join(opts.output_dir, 'all-%s' % m)
    if ('all', m) in trend_starts:
        report_tools.run_reports(my_path, opts.database, basename, opts.config, milestone=m, team=None, trend_override=str(trend_starts[('all', m)]), root=opts.root)
    else:
        report_tools.run_reports(my_path, opts.database, basename, opts.config, milestone=m, team=None, root=opts.root)

# date-based milestone view
for mg in report_tools.milestone_groups(store, team=primary_team):
    due_date_str = mg.due_date_str
    basename = os.path.join(opts.output_dir, due_date_str)
    report_tools.run_reports(my_path, opts.database, basename, opts.config, team=primary_team, root=opts.root, date=due_date_str)

# groups
for g in groups:
    basename = os.path.join(groupssubdir, g)
    report_tools.group_overview(my_path, opts.database, basename, opts.config, g, root=opts.root)


# global report
basename = os.path.join(opts.output_dir, 'all')
if 'all' in trend_starts:
    report_tools.run_reports(my_path, opts.database, basename, opts.config, trend_override=str(trend_starts['all']), root=opts.root)
else:
    report_tools.run_reports(my_path, opts.database, basename, opts.config, root=opts.root)

# team list
basename = os.path.join(opts.output_dir, "teams")
report_tools.team_list_page(my_path, opts.database, basename, opts.config, root=opts.root)

# individuals list
basename = os.path.join(opts.output_dir, "people")
report_tools.person_list_page(my_path, opts.database, basename, opts.config, root=opts.root)

# milestone list
basename = os.path.join(opts.output_dir, "milestones")
report_tools.milestone_list_page(my_path, opts.database, basename, opts.config, root=opts.root)

# about page
basename = os.path.join(opts.output_dir, "about")
report_tools.about_page(my_path, opts.database, basename, opts.config, root=opts.root)

# workitems in status pages
for status in report_tools.valid_states:
    basename = os.path.join(opts.output_dir, status)
    report_tools.workitem_list(my_path, opts.database, basename, opts.config, status, root=opts.root)

# front page
basename = os.path.join(opts.output_dir, 'index')
report_tools.status_overview(my_path, opts.database, basename, opts.config, root=opts.root)

# roadmap lanes
for lane in report_tools.lanes(store):
    basename = os.path.join(lanessubdir, lane.name)
    report_tools.roadmap_pages(my_path, opts.database, basename, opts.config,
                               lane, root=opts.root)

# roadmap cards
for card in report_tools.cards(store):
    if card.roadmap_id != '':
        page_name = card.roadmap_id
    else:
        page_name = str(card.card_id)
    basename = os.path.join(cardssubdir, page_name)
    report_tools.roadmap_cards(my_path, opts.database, basename, opts.config,
                               card, root=opts.root)

def copy_files(source_dir):
    for filename in os.listdir(source_dir):
        dest = open(os.path.join(opts.output_dir, filename), 'w')
        src = open(os.path.join(source_dir, filename))
        dest.write(src.read())
        src.close()
        dest.close()


def copy_base_files(from_dir):
    copy_files(os.path.join(my_path, from_dir))


def copy_theme_files(theme, base_dir):
    copy_files(os.path.join(my_path, "themes", theme, base_dir))


# put JS in place
copy_base_files('js')

# put CSS in place
copy_base_files('css')

# put images in place
copy_base_files('images')

theme = "linaro"
if cfg is not None:
    theme = cfg.get("theme", "linaro")

copy_theme_files(theme, "css")
copy_theme_files(theme, "images")

os.unlink(lock_path)