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

« back to all changes in this revision

Viewing changes to generate-team-bzr

  • Committer: Łukasz 'sil2100' Zemczak
  • Date: 2021-02-26 12:18:18 UTC
  • mfrom: (234.2.2 master)
  • Revision ID: lukasz.zemczak@canonical.com-20210226121818-m9rkvplqtxs27is1
Merge Balint's generate-team-bzr script.

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
# copied from component-mismatches
 
46
def ensure_tempdir():
 
47
    global tempdir
 
48
    if not tempdir:
 
49
        tempdir = tempfile.mkdtemp(prefix='component-mismatches')
 
50
        atexit.register(shutil.rmtree, tempdir)
 
51
 
 
52
 
 
53
# copied from component-mismatches
 
54
def decompress_open(tagfile):
 
55
    ensure_tempdir()
 
56
    decompressed = tempfile.mktemp(dir=tempdir)
 
57
    fin = gzip.GzipFile(filename=tagfile)
 
58
    with open(decompressed, 'wb') as fout:
 
59
        fout.write(fin.read())
 
60
    return open(decompressed, 'r')
 
61
 
 
62
 
 
63
# copied from generate-team-p-m
 
64
def get_subscribers_json(packages, subscribers_json):
 
65
    if subscribers_json is None:
 
66
        j = urlopen("http://people.canonical.com/~ubuntu-archive/package-team-mapping.json")
 
67
    else:
 
68
        j = open(subscribers_json, 'rb')
 
69
    with j:
 
70
        team_to_packages = json.loads(j.read().decode('utf-8'))
 
71
    package_to_teams = {}
 
72
    for team, team_packages in team_to_packages.items():
 
73
        for package in team_packages:
 
74
            if package in packages:
 
75
                package_to_teams.setdefault(package, []).append(team)
 
76
    return package_to_teams
 
77
 
 
78
def packages_with_bzr_repos(options):
 
79
    pkgs = {}
 
80
    for component in options.components.split(','):
 
81
        sources_path = "%s/dists/%s/%s/source/Sources.gz" % (
 
82
            options.archive_dir, options.suite, component)
 
83
        for section in apt_pkg.TagFile(decompress_open(sources_path)):
 
84
            if 'Package' in section and 'Vcs-Bzr' in section:
 
85
                pkgs[section['Package']] = section['Vcs-Bzr']
 
86
    return pkgs
 
87
 
 
88
 
 
89
def repo_url(repo):
 
90
    return re.sub('^lp:','https://code.launchpad.net/',repo)
 
91
 
 
92
def main():
 
93
    parser = argparse.ArgumentParser()
 
94
    parser.add_argument('--archive-dir', action='store', default=os.path.expanduser("~/mirror/ubuntu"))
 
95
    parser.add_argument('--components', action='store', default="main,restricted,universe,multiverse")
 
96
    parser.add_argument('--suite', action='store')
 
97
    parser.add_argument('--subscribers-json', action='store')
 
98
    parser.add_argument('output')
 
99
    args = parser.parse_args()
 
100
 
 
101
    pkgs = packages_with_bzr_repos(args)
 
102
 
 
103
    print("getting subscribers")
 
104
    subscribers = get_subscribers_json(set(pkgs.keys()), args.subscribers_json)
 
105
    for p in set(pkgs.keys()):
 
106
        if p not in subscribers:
 
107
            subscribers[p] = ['unknown']
 
108
 
 
109
    all_teams = set()
 
110
    team_to_pkgs = defaultdict(list)
 
111
    for package, teams in subscribers.items():
 
112
        all_teams |= set(teams)
 
113
        for team in teams:
 
114
            team_to_pkgs[team].append(package)
 
115
 
 
116
    team_to_attn_count = {}
 
117
    for team, packages in team_to_pkgs.items():
 
118
        team_to_attn_count[team] = len(packages)
 
119
        team_to_pkgs[team] = [(package, repo_url(pkgs[package])) for package in sorted(packages)]
 
120
 
 
121
    print("rendering")
 
122
    t = env.get_template('team-report-bzr.html')
 
123
    now = datetime.utcnow()
 
124
    with open(args.output, 'w', encoding='utf-8') as fp:
 
125
        fp.write(t.render(
 
126
            all_teams=all_teams,
 
127
            now="%s.%s.%s %d:%s:%s UTC" % (now.year, now.month, now.day, now.hour, now.minute, now.second),
 
128
            team_to_pkgs=team_to_pkgs,
 
129
            team_to_attn_count=team_to_attn_count))
 
130
 
 
131
if __name__ == '__main__':
 
132
    main()