~mabac/launchpad-work-items-tracker/fix-none-whiteboard

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
#!/usr/bin/python
# Run work item tracker for all available configurations; this is intended to
# be run from cron hourly.
# Copyright (C) 2010, 2011 Canonical Ltd.
# Author: Martin Pitt <martin.pitt@ubuntu.com>
# License: GPL-3

import datetime
import glob
import optparse
import os
import shutil
import subprocess
import sys


def collect(source_dir, db_file, config_file, extra_args):
    return run_collect_script(source_dir, db_file, config_file, extra_args,
                              "collect")


def collect_roadmap(source_dir, db_file, config_file, extra_args):
    return run_collect_script(source_dir, db_file, config_file, extra_args,
                              "collect_roadmap")


def run_collect_script(source_dir, db_file, config_file, extra_args,
                       collect_script):
    args = [os.path.join(source_dir, collect_script)]
    args.extend(["-d", db_file])
    args.extend(["-c", config_file])
    args += extra_args
    proc = subprocess.Popen(args)
    proc.communicate()
    return proc.returncode == 0


def publish_new_db(project_name, project_output_dir, db_file):
    if not os.path.exists(project_output_dir):
        os.makedirs(project_output_dir)
    target_file = os.path.join(project_output_dir, "%s.db" % project_name)
    temp_file = target_file + ".new"
    shutil.copyfile(db_file, temp_file)
    os.rename(temp_file, target_file)


def generate_reports(project_output_dir, config_file, db_file, source_dir,
        extra_args, debug=False):
    stdout = None
    if not debug:
        stdout = subprocess.PIPE
    args = [os.path.join(source_dir, "generate-all")]
    args.extend(["-c", config_file])
    args.extend(["-d", db_file])
    args.extend(["-o", project_output_dir])
    args += extra_args
    proc = subprocess.Popen(args, stdout=stdout)
    proc.communicate()
    assert proc.returncode == 0, "generate-all failed for %s" % config_file


def backup_db(project_name, project_output_dir, current_time):
    project_db = os.path.join(project_output_dir, "%s.db" % project_name)
    if os.path.exists(project_db):
        shutil.copyfile(project_db,
                project_db + ".%s" % current_time.strftime("%Y%m%d"))


def main():
    parser = optparse.OptionParser(usage="%prog <database dir> <www root dir> [www root url]")
    parser.add_option("--config-dir", dest="config_dir", default="config")
    parser.add_option("--roadmap-config-file", dest="roadmap_config_file",
                      default="roadmap-config")
    parser.add_option("--debug", dest="debug", action="store_true")
    parser.add_option("--kanban-token-file", dest="kanban_token_file")
    parser.add_option("--papyrs-token-file", dest="papyrs_token_file")
    opts, args = parser.parse_args()

    if os.environ.get("DEBUG", None) is not None:
        opts.debug = True

    if len(args) < 2:
        parser.error("You must specify database dir and www root dir")
    if len(args) > 3:
        parser.error("You can only specify database dir, www root dir and www root url")

    db_dir = args[0]
    output_dir = args[1]
    url_root = None
    if len(args) > 2:
        url_root = args[2]

    source_dir = os.path.dirname(__file__)

    if not os.path.isdir(db_dir):
        parser.error("database dir must exist and be a directory: %s" % db_dir)
    if not os.path.isdir(output_dir):
        parser.error("output dir must exist and be a directory: %s" % output_dir)

    valid_config_suffix = ".cfg"

    filenames = glob.glob(
        os.path.join(source_dir, opts.config_dir, "*%s" % valid_config_suffix))

    for config_file in filenames:
        project_name = os.path.basename(config_file)[:-len(valid_config_suffix)]
        project_output_dir = os.path.join(output_dir, project_name)
        db_file = os.path.join(db_dir, "%s.db" % project_name)
        now = datetime.datetime.now()
        extra_collect_args = []
        extra_generate_args = []
        if now.hour == 0:
            extra_collect_args.append("--refresh")
            extra_generate_args.append("--all-milestones")
            backup_db(project_name, project_output_dir, now)

        if url_root is not None:
            extra_generate_args.extend(
                ["--root", os.path.join(url_root, project_name)])

        if opts.debug:
            extra_collect_args.append("--debug")
        else:
            extra_collect_args.append("--mail")

        if not collect(source_dir, db_file, config_file, extra_collect_args):
            sys.stderr.write("collect failed for %s" % project_name)
            continue

        extra_collect_roadmap_args = []
        extra_collect_roadmap_args.extend(["--board", '10721'])
        if opts.kanban_token_file is not None:
            with open(opts.kanban_token_file) as token_file:
                token = token_file.read()
                extra_collect_roadmap_args.extend(["--kanbantoken", token])
        else:
            sys.stderr.write("No Kanbantool API token given to "
                             "collect_roadmap for %s" % project_name)
        if opts.papyrs_token_file is not None:
            with open(opts.papyrs_token_file) as token_file:
                token = token_file.read()
                extra_collect_roadmap_args.extend(["--papyrstoken", token])
        else:
            sys.stderr.write("No Papyrs API token given to "
                             "collect_roadmap for %s" % project_name)

        if not collect_roadmap(source_dir, db_file, opts.roadmap_config_file,
                               extra_collect_roadmap_args):
            sys.stderr.write("collect_roadmap failed for %s" % project_name)

        publish_new_db(project_name, project_output_dir, db_file)
        generate_reports(project_output_dir, config_file, db_file,
            source_dir, extra_generate_args, debug=opts.debug)


if __name__ == "__main__":
    main()