~ubuntu-archive/ubuntu-archive-scripts/trunk

« back to all changes in this revision

Viewing changes to generate-team-bzr

  • Committer: Łukasz 'sil2100' Zemczak
  • Date: 2022-04-19 17:02:10 UTC
  • Revision ID: lukasz.zemczak@canonical.com-20220419170210-3nmi5ryi84lf3zm8
...run ben as ubuntu using sudo, as the previous approach doesn't work

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python3
 
2
# -*- coding: utf-8 -*-
 
3
 
 
4
# Copyright (C) 2018 Canonical Ltd
 
5
 
 
6
# This program is free software; you can redistribute it and/or
 
7
# modify it under the terms of the GNU General Public License
 
8
# as published by the Free Software Foundation; either version 2
 
9
# of the License, or (at your option) any later version.
 
10
#
 
11
# This program is distributed in the hope that it will be useful,
 
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
# GNU General Public License for more details.
 
15
#
 
16
# A copy of the GNU General Public License version 2 is in LICENSE.
 
17
 
 
18
import apt_pkg
 
19
import argparse
 
20
import atexit
 
21
from collections import defaultdict
 
22
from datetime import datetime
 
23
import gzip
 
24
import json
 
25
import os
 
26
import re
 
27
import shutil
 
28
import tempfile
 
29
from textwrap import dedent
 
30
from urllib.request import urlopen
 
31
 
 
32
import attr
 
33
from jinja2 import Environment, FileSystemLoader
 
34
import yaml
 
35
 
 
36
env = Environment(
 
37
    loader=FileSystemLoader(os.path.dirname(os.path.abspath(__file__)) + '/templates'),
 
38
    autoescape=True,
 
39
    extensions=['jinja2.ext.i18n'],
 
40
)
 
41
env.install_null_translations(True)
 
42
 
 
43
tempdir = None
 
44
 
 
45
 
 
46
# copied from component-mismatches
 
47
def ensure_tempdir():
 
48
    global tempdir
 
49
    if not tempdir:
 
50
        tempdir = tempfile.mkdtemp(prefix='component-mismatches')
 
51
        atexit.register(shutil.rmtree, tempdir)
 
52
 
 
53
 
 
54
# copied from component-mismatches
 
55
def decompress_open(tagfile):
 
56
    ensure_tempdir()
 
57
    decompressed = tempfile.mktemp(dir=tempdir)
 
58
    fin = gzip.GzipFile(filename=tagfile)
 
59
    with open(decompressed, 'wb') as fout:
 
60
        fout.write(fin.read())
 
61
    return open(decompressed, 'r')
 
62
 
 
63
 
 
64
# copied from generate-team-p-m
 
65
def get_subscribers_json(packages, subscribers_json):
 
66
    if subscribers_json is None:
 
67
        j = urlopen("http://people.canonical.com/~ubuntu-archive/package-team-mapping.json")
 
68
    else:
 
69
        j = open(subscribers_json, 'rb')
 
70
    with j:
 
71
        team_to_packages = json.loads(j.read().decode('utf-8'))
 
72
    package_to_teams = {}
 
73
    for team, team_packages in team_to_packages.items():
 
74
        for package in team_packages:
 
75
            if package in packages:
 
76
                package_to_teams.setdefault(package, []).append(team)
 
77
    return package_to_teams
 
78
 
 
79
 
 
80
def packages_with_bzr_repos(options):
 
81
    pkgs = {}
 
82
    for component in options.components.split(','):
 
83
        sources_path = "%s/dists/%s/%s/source/Sources.gz" % (
 
84
            options.archive_dir, options.suite, component)
 
85
        for section in apt_pkg.TagFile(decompress_open(sources_path)):
 
86
            if 'Package' in section and 'Vcs-Bzr' in section:
 
87
                pkgs[section['Package']] = section['Vcs-Bzr']
 
88
    return pkgs
 
89
 
 
90
 
 
91
def repo_url(repo):
 
92
    return re.sub('^lp:', 'https://code.launchpad.net/', repo)
 
93
 
 
94
 
 
95
def main():
 
96
    parser = argparse.ArgumentParser()
 
97
    parser.add_argument('--archive-dir', action='store', default=os.path.expanduser("~/mirror/ubuntu"))
 
98
    parser.add_argument('--components', action='store', default="main,restricted,universe,multiverse")
 
99
    parser.add_argument('--suite', action='store')
 
100
    parser.add_argument('--subscribers-json', action='store')
 
101
    parser.add_argument('output')
 
102
    args = parser.parse_args()
 
103
 
 
104
    pkgs = packages_with_bzr_repos(args)
 
105
 
 
106
    print("getting subscribers")
 
107
    subscribers = get_subscribers_json(set(pkgs.keys()), args.subscribers_json)
 
108
    for p in set(pkgs.keys()):
 
109
        if p not in subscribers:
 
110
            subscribers[p] = ['unknown']
 
111
 
 
112
    all_teams = set()
 
113
    team_to_pkgs = defaultdict(list)
 
114
    for package, teams in subscribers.items():
 
115
        all_teams |= set(teams)
 
116
        for team in teams:
 
117
            team_to_pkgs[team].append(package)
 
118
 
 
119
    team_to_attn_count = {}
 
120
    for team, packages in team_to_pkgs.items():
 
121
        team_to_attn_count[team] = len(packages)
 
122
        team_to_pkgs[team] = [(package, repo_url(pkgs[package])) for package in sorted(packages)]
 
123
 
 
124
    print("rendering")
 
125
    t = env.get_template('team-report-bzr.html')
 
126
    now = datetime.utcnow()
 
127
    with open(args.output, 'w', encoding='utf-8') as fp:
 
128
        fp.write(t.render(
 
129
            all_teams=all_teams,
 
130
            now="%s UTC" % now.strftime("%Y-%m-%d %H:%M:%S"),
 
131
            team_to_pkgs=team_to_pkgs,
 
132
            team_to_attn_count=team_to_attn_count))
 
133
 
 
134
 
 
135
if __name__ == '__main__':
 
136
    main()