1
- import structlog
2
1
import sys
3
2
from pathlib import Path
4
3
from pprint import pprint
5
4
5
+ import structlog
6
6
from django .conf import settings
7
7
from django .contrib .auth import get_user_model
8
8
from django .core .management .base import BaseCommand
@@ -31,10 +31,16 @@ class Command(BaseCommand):
31
31
32
32
Email and send an ephemeral (disappears after shown once) notification to all owners of the "readthedocs" organization::
33
33
34
- django-admin contact_owners --email email.md --notification notification.md --organization readthedocs # noqa
34
+ django-admin contact_owners --email email.md --notification notification.md --organization readthedocs
35
+
36
+ Send a sticky notifications to multiple users::
35
37
36
- Where ``email.md`` is a markdown file with the first line as the subject, and the rest is the content.
37
- ``user`` and ``domain`` are available in the context.
38
+ django-admin contact_owners --notification notification.md --sticky --usernames usernames.txt
39
+
40
+ * ``usernames.txt`` is a text file containing one username per line.
41
+ * ``notifications.md`` is a Markdown file containing the message to be included in the notification.
42
+ * ``email.md`` is a Markdown file with the first line as the subject, and the rest is the content.
43
+ Note that ``user`` and ``domain`` are available in the context.
38
44
39
45
.. code:: markdown
40
46
@@ -50,7 +56,7 @@ class Command(BaseCommand):
50
56
add the ``--production`` flag to actually send the email/notification.
51
57
"""
52
58
53
- help = ' Send an email or sticky notification from a file (markdown ) to all owners.'
59
+ help = " Send an email or sticky notification from a file (Markdown ) to users."
54
60
55
61
def add_arguments (self , parser ):
56
62
parser .add_argument (
@@ -92,16 +98,24 @@ def add_arguments(self, parser):
92
98
'--project' ,
93
99
help = 'Project slug to filter by.' ,
94
100
)
101
+ parser .add_argument (
102
+ "--usernames" ,
103
+ help = "Path to a file with the one username per line to filter by." ,
104
+ )
95
105
96
106
def handle (self , * args , ** options ):
97
107
if not options ['email' ] and not options ['notification' ]:
98
108
print ("--email or --notification is required." )
99
109
sys .exit (1 )
100
110
101
- project = options ['project' ]
102
- organization = options ['organization' ]
103
- if project and organization :
104
- print ("--project and --organization can\' t be used together." )
111
+ project = options ["project" ]
112
+ organization = options ["organization" ]
113
+ usernames = options ["usernames" ]
114
+ if (
115
+ len ([item for item in [project , organization , usernames ] if bool (item )])
116
+ >= 2
117
+ ):
118
+ print ("--project, --organization and --usernames can't be used together." )
105
119
sys .exit (1 )
106
120
107
121
if project :
@@ -116,6 +130,15 @@ def handle(self, *args, **options):
116
130
.filter (organizationowner__organization__disabled = False )
117
131
.distinct ()
118
132
)
133
+ elif usernames :
134
+ file = Path (usernames )
135
+ with file .open () as f :
136
+ usernames = f .readlines ()
137
+
138
+ # remove "\n" from lines
139
+ usernames = [line .strip () for line in usernames ]
140
+
141
+ users = User .objects .filter (username__in = usernames )
119
142
else :
120
143
users = (
121
144
User .objects
@@ -124,16 +147,17 @@ def handle(self, *args, **options):
124
147
)
125
148
126
149
print (
127
- ' len(owners)={} production={} email={} notification={}' .format (
150
+ " len(owners)={} production={} email={} notification={} sticky={}" .format (
128
151
users .count (),
129
- bool (options ['production' ]),
130
- options ['email' ],
131
- options ['notification' ],
152
+ bool (options ["production" ]),
153
+ options ["email" ],
154
+ options ["notification" ],
155
+ options ["sticky" ],
132
156
)
133
157
)
134
158
135
- if input (' Continue? y/n: ' ) != 'y' :
136
- print (' Aborting run.' )
159
+ if input (" Continue? y/N: " ) != "y" :
160
+ print (" Aborting run." )
137
161
return
138
162
139
163
notification_content = ''
0 commit comments