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 

14 

15from django.core.management.base import BaseCommand 

16 

17from distro_tracker.core.models import PackageName 

18from distro_tracker.core.utils import get_or_none 

19 

20 

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") 

29 

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 ) 

53 

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)) 

57 

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)) 

72 

73 output_format = 'default' 

74 if kwargs['json']: 

75 output_format = 'json' 

76 elif kwargs.get('udd_format', False): 

77 output_format = 'udd' 

78 

79 return self.render_packages(output_format) 

80 

81 def output_package(self, package, inactive=False): 

82 """ 

83 Includes the subscribers of the given package in the output. 

84 

85 :param package: Package whose subscribers should be output 

86 :type package: :py:class:`Package <distro_tracker.core.models.Package>` 

87 

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 ] 

96 

97 def render_packages(self, output_format): 

98 """ 

99 Prints the packages and their subscribers to the output stream. 

100 

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 + ' ]')