1# Copyright 2013-2016 The Distro Tracker Developers
2# See the COPYRIGHT file at the top-level directory of this distribution and
3# at https://deb.li/DTAuthors
4#
5# This file is part of Distro Tracker. It is subject to the license terms
6# in the LICENSE file found in the top-level directory of this
7# distribution and at https://deb.li/DTLicense. No part of Distro Tracker,
8# including this file, may be copied, modified, propagated, or distributed
9# except according to the terms contained in the LICENSE file.
10"""
11Implements the command which outputs all subscribers for given packages.
12"""
13import json
15from django.core.management.base import BaseCommand
17from distro_tracker.core.models import PackageName
18from distro_tracker.core.utils import get_or_none
21class Command(BaseCommand):
22 """
23 A Django management command which outputs all subscribers for the given
24 packages or for all packages, depending on the input parameters.
25 emails.
26 """
27 help = ("Get the subscribers for the given packages.\n" # noqa
28 "Outputs subscribers to all packges if no arguments are given")
30 def add_arguments(self, parser):
31 parser.add_argument('packages', nargs='*')
32 parser.add_argument(
33 '--inactive',
34 action='store_true',
35 dest='inactive',
36 default=False,
37 help='Show inactive (non-confirmed) subscriptions'
38 )
39 parser.add_argument(
40 '--json',
41 action='store_true',
42 dest='json',
43 default=False,
44 help='Output the result encoded as a JSON object'
45 )
46 parser.add_argument(
47 '--udd-format',
48 action='store_true',
49 dest='udd_format',
50 default=False,
51 help='Output the result in a UDD compatible format'
52 )
54 def warning(self, msg, *args):
55 if self.verbose: 55 ↛ exitline 55 didn't return from function 'warning', because the condition on line 55 was never false
56 self.stderr.write("Warning: {}".format(msg % args))
58 def handle(self, *args, **kwargs):
59 self.verbose = int(kwargs.get('verbosity', 1)) > 1
60 inactive = kwargs['inactive']
61 self.out_packages = {}
62 if len(kwargs['packages']) == 0:
63 for package in PackageName.objects.all():
64 self.output_package(package, inactive)
65 else:
66 for package_name in kwargs['packages']:
67 package = get_or_none(PackageName, name=package_name)
68 if package: 68 ↛ 69line 68 didn't jump to line 69, because the condition on line 68 was never true
69 self.output_package(package, inactive)
70 else:
71 self.warning("%s does not exist.", str(package_name))
73 output_format = 'default'
74 if kwargs['json']:
75 output_format = 'json'
76 elif kwargs.get('udd_format', False):
77 output_format = 'udd'
79 return self.render_packages(output_format)
81 def output_package(self, package, inactive=False):
82 """
83 Includes the subscribers of the given package in the output.
85 :param package: Package whose subscribers should be output
86 :type package: :py:class:`Package <distro_tracker.core.models.Package>`
88 :param inactive: Signals whether inactive or active subscriptions
89 should be output.
90 """
91 subscriptions = package.subscription_set.filter(active=not inactive)
92 self.out_packages[package.name] = [
93 str(sub.email_settings.user_email)
94 for sub in subscriptions
95 ]
97 def render_packages(self, output_format):
98 """
99 Prints the packages and their subscribers to the output stream.
101 :param use_json: If ``True`` the output is rendered as JSON.
102 Otherwise, a legacy format is used.
103 :type use_json: Boolean
104 """
105 if output_format == 'json':
106 self.stdout.write(json.dumps(self.out_packages))
107 elif output_format == 'udd':
108 for package, subscribers in self.out_packages.items():
109 subscriber_out = ', '.join(str(email) for email in subscribers)
110 self.stdout.write("{}\t{}".format(package, subscriber_out))
111 else:
112 for package, subscribers in self.out_packages.items():
113 subscriber_out = ' '.join(str(email) for email in subscribers)
114 self.stdout.write(package + ' => [ ' + subscriber_out + ' ]')