Django 1.8: declare positional arguments in management commands

(imported from commit d9efca1376de92c8187d25f546c79fece8d2d8c6)
This commit is contained in:
Reid Barton
2015-08-20 17:10:41 -07:00
parent ecc07333af
commit ae0ae3dde8
28 changed files with 285 additions and 274 deletions

View File

@@ -17,6 +17,10 @@ python manage.py client_activity
python manage.py client_activity zulip.com python manage.py client_activity zulip.com
python manage.py client_activity jesstess@zulip.com""" python manage.py client_activity jesstess@zulip.com"""
def add_arguments(self, parser):
parser.add_argument('arg', metavar='<arg>', type=str, nargs='?', default=None,
help="realm or user to estimate client activity for")
def compute_activity(self, user_activity_objects): def compute_activity(self, user_activity_objects):
# Report data from the past week. # Report data from the past week.
# #
@@ -49,21 +53,22 @@ python manage.py client_activity jesstess@zulip.com"""
def handle(self, *args, **options): def handle(self, *args, **options):
if len(args) == 0: if options['arg'] is None:
# Report global activity. # Report global activity.
self.compute_activity(UserActivity.objects.all()) self.compute_activity(UserActivity.objects.all())
elif len(args) == 1: else:
arg = options['arg']
try: try:
# Report activity for a user. # Report activity for a user.
user_profile = get_user_profile_by_email(args[0]) user_profile = get_user_profile_by_email(arg)
self.compute_activity(UserActivity.objects.filter( self.compute_activity(UserActivity.objects.filter(
user_profile=user_profile)) user_profile=user_profile))
except UserProfile.DoesNotExist: except UserProfile.DoesNotExist:
try: try:
# Report activity for a realm. # Report activity for a realm.
realm = get_realm(args[0]) realm = get_realm(arg)
self.compute_activity(UserActivity.objects.filter( self.compute_activity(UserActivity.objects.filter(
user_profile__realm=realm)) user_profile__realm=realm))
except Realm.DoesNotExist: except Realm.DoesNotExist:
print "Unknown user or domain %s" % (args[0],) print "Unknown user or domain %s" % (arg,)
exit(1) exit(1)

View File

@@ -16,6 +16,10 @@ human_messages = Message.objects.filter(sending_client__name__in=HUMAN_CLIENT_LI
class Command(BaseCommand): class Command(BaseCommand):
help = "Generate statistics on realm activity." help = "Generate statistics on realm activity."
def add_arguments(self, parser):
parser.add_argument('realms', metavar='<realm>', type=str, nargs='*',
help="realm to generate statistics for")
def active_users(self, realm): def active_users(self, realm):
# Has been active (on the website, for now) in the last 7 days. # Has been active (on the website, for now) in the last 7 days.
activity_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=7) activity_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=7)
@@ -64,9 +68,9 @@ class Command(BaseCommand):
print "%.2f%% of" % (fraction * 100,), text print "%.2f%% of" % (fraction * 100,), text
def handle(self, *args, **options): def handle(self, *args, **options):
if args: if options['realms']:
try: try:
realms = [Realm.objects.get(domain=domain) for domain in args] realms = [Realm.objects.get(domain=domain) for domain in options['realms']]
except Realm.DoesNotExist, e: except Realm.DoesNotExist, e:
print e print e
exit(1) exit(1)

View File

@@ -7,10 +7,14 @@ from zerver.models import Realm, Stream, Message, Subscription, Recipient
class Command(BaseCommand): class Command(BaseCommand):
help = "Generate statistics on the streams for a realm." help = "Generate statistics on the streams for a realm."
def add_arguments(self, parser):
parser.add_argument('realms', metavar='<realm>', type=str, nargs='*',
help="realm to generate statistics for")
def handle(self, *args, **options): def handle(self, *args, **options):
if args: if options['realms']:
try: try:
realms = [Realm.objects.get(domain=domain) for domain in args] realms = [Realm.objects.get(domain=domain) for domain in options['realms']]
except Realm.DoesNotExist, e: except Realm.DoesNotExist, e:
print e print e
exit(1) exit(1)

View File

@@ -9,15 +9,19 @@ from zerver.models import UserProfile, Realm, Stream, Message
class Command(BaseCommand): class Command(BaseCommand):
help = "Generate statistics on user activity." help = "Generate statistics on user activity."
def add_arguments(self, parser):
parser.add_argument('realms', metavar='<realm>', type=str, nargs='*',
help="realm to generate statistics for")
def messages_sent_by(self, user, week): def messages_sent_by(self, user, week):
start = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=(week + 1)*7) start = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=(week + 1)*7)
end = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=week*7) end = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=week*7)
return Message.objects.filter(sender=user, pub_date__gt=start, pub_date__lte=end).count() return Message.objects.filter(sender=user, pub_date__gt=start, pub_date__lte=end).count()
def handle(self, *args, **options): def handle(self, *args, **options):
if args: if options['realms']:
try: try:
realms = [Realm.objects.get(domain=domain) for domain in args] realms = [Realm.objects.get(domain=domain) for domain in options['realms']]
except Realm.DoesNotExist, e: except Realm.DoesNotExist, e:
print e print e
exit(1) exit(1)

View File

@@ -6,16 +6,14 @@ from zerver.lib.actions import do_update_message_flags
from zerver.models import UserProfile, Message, get_user_profile_by_email from zerver.models import UserProfile, Message, get_user_profile_by_email
class Command(BaseCommand): class Command(BaseCommand):
help = """Bankrupt one or many users. help = """Bankrupt one or many users."""
Usage: python manage.py bankrupt_users <list of email addresses>""" def add_arguments(self, parser):
parser.add_argument('emails', metavar='<email>', type=str, nargs='+',
help='email address to bankrupt')
def handle(self, *args, **options): def handle(self, *args, **options):
if len(args) < 1: for email in options['emails']:
print "Please provide at least one e-mail address."
exit(1)
for email in args:
try: try:
user_profile = get_user_profile_by_email(email) user_profile = get_user_profile_by_email(email)
except UserProfile.DoesNotExist: except UserProfile.DoesNotExist:

View File

@@ -6,18 +6,14 @@ from zerver.lib.actions import do_change_full_name
from zerver.models import UserProfile, get_user_profile_by_email from zerver.models import UserProfile, get_user_profile_by_email
class Command(BaseCommand): class Command(BaseCommand):
help = """Change the names for many users. help = """Change the names for many users."""
Usage: python manage.py bulk_change_user_name <data file> def add_arguments(self, parser):
parser.add_argument('data_file', metavar='<data file>', type=str,
Where <data file> contains rows of the form <email>,<desired name>.""" help="file containing rows of the form <email>,<desired name>")
def handle(self, *args, **options): def handle(self, *args, **options):
if len(args) != 1: data_file = options['data_file']
print "Please provide a CSV file mapping emails to desired names."
exit(1)
data_file = args[0]
with open(data_file, "r") as f: with open(data_file, "r") as f:
for line in f: for line in f:
email, new_name = line.strip().split(",", 1) email, new_name = line.strip().split(",", 1)

View File

@@ -6,16 +6,17 @@ from zerver.lib.actions import do_change_user_email
from zerver.models import UserProfile, get_user_profile_by_email from zerver.models import UserProfile, get_user_profile_by_email
class Command(BaseCommand): class Command(BaseCommand):
help = """Change the email address for a user. help = """Change the email address for a user."""
Usage: python manage.py change_user_email <old email> <new email>""" def add_arguments(self, parser):
parser.add_argument('old_email', metavar='<old email>', type=str,
help='email address to change')
parser.add_argument('new_email', metavar='<new email>', type=str,
help='new email address')
def handle(self, *args, **options): def handle(self, *args, **options):
if len(args) != 2: old_email = options['old_email']
print "Please provide both the old and new address." new_email = options['new_email']
exit(1)
old_email, new_email = args
try: try:
user_profile = get_user_profile_by_email(old_email) user_profile = get_user_profile_by_email(old_email)
except UserProfile.DoesNotExist: except UserProfile.DoesNotExist:

View File

@@ -11,16 +11,17 @@ class Command(BaseCommand):
help = """Create a stream, and subscribe all active users (excluding bots). help = """Create a stream, and subscribe all active users (excluding bots).
This should be used for TESTING only, unless you understand the limitations of This should be used for TESTING only, unless you understand the limitations of
the command. the command."""
Usage: python manage.py create_stream <domain> <stream name>""" def add_arguments(self, parser):
parser.add_argument('domain', metavar='<domain>', type=str,
help='domain in which to create the stream')
parser.add_argument('stream_name', metavar='<stream name>', type=str,
help='name of stream to create')
def handle(self, *args, **options): def handle(self, *args, **options):
if len(args) != 2: domain = options['domain']
print "Please provide a domain and the stream name." stream_name = options['stream_name']
exit(1)
domain, stream_name = args
encoding = sys.getfilesystemencoding() encoding = sys.getfilesystemencoding()
try: try:

View File

@@ -1,7 +1,7 @@
from __future__ import absolute_import from __future__ import absolute_import
import sys import sys
from optparse import make_option import argparse
from django.core.management.base import BaseCommand, CommandError from django.core.management.base import BaseCommand, CommandError
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
@@ -18,19 +18,24 @@ class Command(BaseCommand):
A user MUST have ALREADY accepted the Terms of Service before creating their A user MUST have ALREADY accepted the Terms of Service before creating their
account this way. account this way.
Omit both <email> and <full name> for interactive user creation.
""" """
option_list = BaseCommand.option_list + ( def add_arguments(self, parser):
make_option('--this-user-has-accepted-the-tos', parser.add_argument('--this-user-has-accepted-the-tos',
dest='tos', dest='tos',
action="store_true", action="store_true",
default=False, default=False,
help='Acknowledgement that the user has already accepted the ToS.'), help='Acknowledgement that the user has already accepted the ToS.')
make_option('--domain', parser.add_argument('--domain',
dest='domain', dest='domain',
type='str', type=str,
help='The name of the existing realm to which to add the user.'), help='The name of the existing realm to which to add the user.')
) parser.add_argument('email', metavar='<email>', type=str, nargs='?', default=argparse.SUPPRESS,
help='email address of new user')
parser.add_argument('full_name', metavar='<full name>', type=str, nargs='?', default=argparse.SUPPRESS,
help='full name of new user')
def handle(self, *args, **options): def handle(self, *args, **options):
if not options["tos"]: if not options["tos"]:
@@ -46,13 +51,14 @@ Terms of Service by passing --this-user-has-accepted-the-tos.""")
raise CommandError("Realm does not exist.") raise CommandError("Realm does not exist.")
try: try:
email, full_name = args email = options['email']
full_name = options['full_name']
try: try:
validators.validate_email(email) validators.validate_email(email)
except ValidationError: except ValidationError:
raise CommandError("Invalid email address.") raise CommandError("Invalid email address.")
except ValueError: except KeyError:
if len(args) != 0: if 'email' in options or 'full_name' in options:
raise CommandError("""Either specify an email and full name as two raise CommandError("""Either specify an email and full name as two
parameters, or specify no parameters for interactive user creation.""") parameters, or specify no parameters for interactive user creation.""")
else: else:

View File

@@ -10,20 +10,17 @@ from zerver.models import get_user_profile_by_email, UserProfile
class Command(BaseCommand): class Command(BaseCommand):
help = "Deactivate a user, including forcibly logging them out." help = "Deactivate a user, including forcibly logging them out."
option_list = BaseCommand.option_list + ( def add_arguments(self, parser):
make_option('-f', '--for-real', parser.add_argument('-f', '--for-real',
dest='for_real', dest='for_real',
action='store_true', action='store_true',
default=False, default=False,
help="Actually deactivate the user. Default is a dry run."), help="Actually deactivate the user. Default is a dry run.")
) parser.add_argument('email', metavar='<email>', type=str,
help='email of user to deactivate')
def handle(self, *args, **options): def handle(self, *args, **options):
if not args: user_profile = get_user_profile_by_email(options['email'])
print "Please specify an e-mail address."
exit(1)
user_profile = get_user_profile_by_email(args[0])
print "Deactivating %s (%s) - %s" % (user_profile.full_name, print "Deactivating %s (%s) - %s" % (user_profile.full_name,
user_profile.email, user_profile.email,

View File

@@ -134,8 +134,12 @@ def main():
class Command(BaseCommand): class Command(BaseCommand):
help = __doc__ help = __doc__
def add_arguments(self, parser):
parser.add_argument('recipient', metavar='<recipient>', type=str, nargs='?', default=None,
help="original recipient")
def handle(self, *args, **options): def handle(self, *args, **options):
rcpt_to = os.environ.get("ORIGINAL_RECIPIENT", args[0] if len(args) else None) rcpt_to = os.environ.get("ORIGINAL_RECIPIENT", options['recipient'])
if rcpt_to is not None: if rcpt_to is not None:
if is_missed_message_address(rcpt_to): if is_missed_message_address(rcpt_to):
try: try:

View File

@@ -18,17 +18,18 @@ fields, the second of which is a JSON payload. (The latter is to accomodate
the format of error files written by queue workers that catch exceptions--their the format of error files written by queue workers that catch exceptions--their
first field is a timestamp that we ignore.) first field is a timestamp that we ignore.)
Usage: python manage.py enqueue_file <queue_name> <file_name>
You can use "-" to represent stdin. You can use "-" to represent stdin.
""" """
def handle(self, *args, **options): def add_arguments(self, parser):
if len(args) != 2: parser.add_argument('queue_name', metavar='<queue>', type=str,
print "Please provide a queue and file name." help="name of worker queue to enqueue to")
exit(1) parser.add_argument('file_name', metavar='<file>', type=str,
help="name of file containing JSON lines")
queue_name, file_name = args def handle(self, *args, **options):
queue_name = options['queue_name']
file_name = options['file_name']
if file_name == '-': if file_name == '-':
f = sys.stdin f = sys.stdin

View File

@@ -53,13 +53,16 @@ def expunge(filename):
class Command(BaseCommand): class Command(BaseCommand):
help = ('Expunge old entries from one or more log files, ' help = ('Expunge old entries from one or more log files, '
+ 'according to the retention policy.') + 'according to the retention policy.')
args = '<log file> <log file> ...'
def handle(self, *args, **kwargs): def add_arguments(self, parser):
if len(args) == 0: parser.add_argument('log_files', metavar='<log file>', type=str, nargs='*',
help='file to expunge entries from')
def handle(self, *args, **options):
if len(options['log_files']) == 0:
print >>sys.stderr, 'WARNING: No log files specified; doing nothing.' print >>sys.stderr, 'WARNING: No log files specified; doing nothing.'
for infile in args: for infile in options['log_files']:
try: try:
expunge(infile) expunge(infile)
except KeyboardInterrupt: except KeyboardInterrupt:

View File

@@ -1,7 +1,5 @@
from __future__ import absolute_import from __future__ import absolute_import
from optparse import make_option
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from confirmation.models import Confirmation from confirmation.models import Confirmation
from zerver.models import UserProfile, PreregistrationUser, \ from zerver.models import UserProfile, PreregistrationUser, \
@@ -10,21 +8,22 @@ from zerver.models import UserProfile, PreregistrationUser, \
class Command(BaseCommand): class Command(BaseCommand):
help = "Generate activation links for users and print them to stdout." help = "Generate activation links for users and print them to stdout."
option_list = BaseCommand.option_list + ( def add_arguments(self, parser):
make_option('--domain', parser.add_argument('--domain',
dest='domain', dest='domain',
type='str', type=str,
help='The realm in which to generate the invites (use for open realms).'), help='The realm in which to generate the invites (use for open realms).')
make_option('--force', parser.add_argument('--force',
dest='force', dest='force',
action="store_true", action="store_true",
default=False, default=False,
help='Override that the domain is restricted to external users.'), help='Override that the domain is restricted to external users.')
) parser.add_argument('emails', metavar='<email>', type=str, nargs='*',
help='email of user to generate an activation link for')
def handle(self, *args, **options): def handle(self, *args, **options):
duplicates = False duplicates = False
for email in args: for email in options['emails']:
try: try:
get_user_profile_by_email(email) get_user_profile_by_email(email)
print email + ": There is already a user registered with that address." print email + ": There is already a user registered with that address."
@@ -45,7 +44,7 @@ class Command(BaseCommand):
print "Don't forget default streams!" print "Don't forget default streams!"
exit(1) exit(1)
for email in args: for email in options['emails']:
if realm: if realm:
if realm.restricted_to_domain and \ if realm.restricted_to_domain and \
domain.lower() != email.split("@", 1)[-1].lower() and \ domain.lower() != email.split("@", 1)[-1].lower() and \

View File

@@ -12,17 +12,18 @@ class Command(BaseCommand):
email addresses are specified, use the Gravatar for the first and upload the image email addresses are specified, use the Gravatar for the first and upload the image
for both email addresses.""" for both email addresses."""
def handle(self, *args, **kwargs): def add_arguments(self, parser):
if len(args) == 0: parser.add_argument('old_email', metavar='<old email>', type=str,
raise CommandError("You must specify a user") help="user whose Gravatar should be migrated")
if len(args) > 2: parser.add_argument('new_email', metavar='<new email>', type=str, nargs='?', default=None,
raise CommandError("Too many positional arguments") help="user to copy the Gravatar to")
old_email = args[0] def handle(self, *args, **options):
old_email = options['old_email']
if len(args) == 2: if options['new_email']:
new_email = args[1] new_email = options['new_email']
elif len(args) == 1: else:
new_email = old_email new_email = old_email
gravatar_url = "https://secure.gravatar.com/avatar/%s?d=identicon" % (gravatar_hash(old_email),) gravatar_url = "https://secure.gravatar.com/avatar/%s?d=identicon" % (gravatar_hash(old_email),)

View File

@@ -1,7 +1,5 @@
from __future__ import absolute_import from __future__ import absolute_import
from optparse import make_option
from django.core.management.base import BaseCommand, CommandError from django.core.management.base import BaseCommand, CommandError
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
@@ -15,24 +13,22 @@ class Command(BaseCommand):
ONLY perform this on customer request from an authorized person. ONLY perform this on customer request from an authorized person.
""" """
option_list = BaseCommand.option_list + ( def add_arguments(self, parser):
make_option('-f', '--for-real', parser.add_argument('-f', '--for-real',
dest='ack', dest='ack',
action="store_true", action="store_true",
default=False, default=False,
help='Acknowledgement that this is done according to policy.'), help='Acknowledgement that this is done according to policy.')
make_option('--revoke', parser.add_argument('--revoke',
dest='grant', dest='grant',
action="store_false", action="store_false",
default=True, default=True,
help='Remove an administrator\'s rights.'), help='Remove an administrator\'s rights.')
) parser.add_argument('email', metavar='<email>', type=str,
help="email of user to knight")
def handle(self, *args, **options): def handle(self, *args, **options):
try: email = options['email']
email = args[0]
except ValueError:
raise CommandError("""Please specify a user.""")
try: try:
profile = UserProfile.objects.get(email=email) profile = UserProfile.objects.get(email=email)
except ValidationError: except ValidationError:

View File

@@ -9,20 +9,19 @@ import signal
import logging import logging
class Command(BaseCommand): class Command(BaseCommand):
args = "<queue name> [<worker number>]" def add_arguments(self, parser):
parser.add_argument('queue_name', metavar='<queue name>', type=str,
help="queue to process")
parser.add_argument('worker_num', metavar='<worker number>', type=int, nargs='?', default=0,
help="worker label")
help = "Runs a queue processing worker" help = "Runs a queue processing worker"
def handle(self, *args, **options): def handle(self, *args, **options):
logging.basicConfig() logging.basicConfig()
logger = logging.getLogger('process_queue') logger = logging.getLogger('process_queue')
if len(args) not in (1, 2): queue_name = options['queue_name']
raise CommandError("Wrong number of arguments") worker_num = options['worker_num']
queue_name = args[0]
if len(args) > 1:
worker_num = int(args[1])
else:
worker_num = 0
def signal_handler(signal, frame): def signal_handler(signal, frame):
logger.info("Worker %d disconnecting from queue %s" % (worker_num, queue_name)) logger.info("Worker %d disconnecting from queue %s" % (worker_num, queue_name))

View File

@@ -5,13 +5,13 @@ from django.core.management import CommandError
from zerver.lib.queue import SimpleQueueClient from zerver.lib.queue import SimpleQueueClient
class Command(BaseCommand): class Command(BaseCommand):
args = "<queue name>" def add_arguments(self, parser):
parser.add_argument('queue_name', metavar='<queue name>', type=str,
help="queue to purge")
help = "Discards all messages from the given queue" help = "Discards all messages from the given queue"
def handle(self, *args, **options): def handle(self, *args, **options):
if len(args) != 1: queue_name = options['queue_name']
raise CommandError("Wrong number of arguments")
queue_name = args[0]
queue = SimpleQueueClient() queue = SimpleQueueClient()
queue.ensure_queue(queue_name, lambda: None) queue.ensure_queue(queue_name, lambda: None)
queue.channel.queue_purge(queue_name) queue.channel.queue_purge(queue_name)

View File

@@ -10,11 +10,8 @@ from django_auth_ldap.backend import LDAPBackend, _LDAPUser
# Run this on a cronjob to pick up on name changes. # Run this on a cronjob to pick up on name changes.
def query_ldap(*args): def query_ldap(**options):
if len(args) != 1: email = options['email']
print "Usage: query_ldap <email address>"
sys.exit(1)
email = args[0]
for backend in get_backends(): for backend in get_backends():
if isinstance(backend, LDAPBackend): if isinstance(backend, LDAPBackend):
ldap_attrs = _LDAPUser(backend, backend.django_to_ldap_username(email)).attrs ldap_attrs = _LDAPUser(backend, backend.django_to_ldap_username(email)).attrs
@@ -25,5 +22,9 @@ def query_ldap(*args):
print "%s: %s" % (django_field, ldap_attrs[ldap_field]) print "%s: %s" % (django_field, ldap_attrs[ldap_field])
class Command(BaseCommand): class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument('email', metavar='<email>', type=str,
help="email of user to query")
def handle(self, *args, **options): def handle(self, *args, **options):
query_ldap(*args) query_ldap(**options)

View File

@@ -7,38 +7,33 @@ from django.core.management.base import BaseCommand
from optparse import make_option from optparse import make_option
class Command(BaseCommand): class Command(BaseCommand):
help = """Manually block or unblock a user from accessing the API help = """Manually block or unblock a user from accessing the API"""
Usage: ./manage.py rate_limit [--all-bots] [--domain all] [--seconds 60] [--api-key bf4sds] [--email f@b.com] block/unblock""" def add_arguments(self, parser):
parser.add_argument('-e', '--email',
option_list = BaseCommand.option_list + ( dest='email',
make_option('-e', '--email', help="Email account of user.")
dest='email', parser.add_argument('-a', '--api-key',
help="Email account of user."), dest='api_key',
make_option('-a', '--api-key', help="API key of user.")
dest='api_key', parser.add_argument('-s', '--seconds',
help="API key of user."), dest='seconds',
make_option('-s', '--seconds', default=60,
dest='seconds', type=int,
default=60, help="Seconds to block for.")
type=int, parser.add_argument('-d', '--domain',
help="Seconds to block for."), dest='domain',
make_option('-d', '--domain', default='all',
dest='domain', help="Rate-limiting domain. Defaults to 'all'.")
default='all', parser.add_argument('-b', '--all-bots',
help="Rate-limiting domain. Defaults to 'all'."), dest='bots',
make_option('-b', '--all-bots', action='store_true',
dest='bots', default=False,
action='store_true', help="Whether or not to also block all bots for this user.")
default=False, parser.add_argument('operation', metavar='<operation>', type=str, choices=['block', 'unblock'],
help="Whether or not to also block all bots for this user."), help="operation to perform (block or unblock)")
)
def handle(self, *args, **options): def handle(self, *args, **options):
if len(args) == 0 or args[0] not in ('block', 'unblock'):
print "Please pass either 'block' or 'unblock"
exit(1)
if (not options['api_key'] and not options['email']) or \ if (not options['api_key'] and not options['email']) or \
(options['api_key'] and options['email']): (options['api_key'] and options['email']):
print "Please enter either an email or API key to manage" print "Please enter either an email or API key to manage"
@@ -58,7 +53,7 @@ class Command(BaseCommand):
users.extend(bot for bot in UserProfile.objects.filter(is_bot=True, users.extend(bot for bot in UserProfile.objects.filter(is_bot=True,
bot_owner=user_profile)) bot_owner=user_profile))
operation = args[0] operation = options['operation']
for user in users: for user in users:
print "Applying operation to User ID: %s: %s" % (user.id, operation) print "Applying operation to User ID: %s: %s" % (user.id, operation)

View File

@@ -1,5 +1,4 @@
from __future__ import absolute_import from __future__ import absolute_import
from optparse import make_option
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from zerver.models import Realm, RealmAlias, get_realm from zerver.models import Realm, RealmAlias, get_realm
@@ -7,29 +6,23 @@ from zerver.lib.actions import realm_aliases
import sys import sys
class Command(BaseCommand): class Command(BaseCommand):
help = """Manage aliases for the specified realm help = """Manage aliases for the specified realm"""
Usage: python manage.py realm_alias --realm=foo.com --op=[add|remove|show] bar.com def add_arguments(self, parser):
parser.add_argument('-r', '--realm',
""" dest='domain',
type=str,
option_list = BaseCommand.option_list + ( required=True,
make_option('-r', '--realm', help='The name of the realm.')
dest='domain', parser.add_argument('--op',
type='str', dest='op',
help='The name of the realm.'), type=str,
make_option('--op', default="show",
dest='op', help='What operation to do (add, show, remove).')
type='str', parser.add_argument('alias', metavar='<alias>', type=str, nargs='?',
default="show", help="alias to add or remove")
help='What operation to do (add, show, remove).'),
)
def handle(self, *args, **options): def handle(self, *args, **options):
if "domain" not in options or options['domain'] is None:
self.print_help("python manage.py", "realm_alias")
sys.exit(1)
realm = Realm.objects.get(domain=options["domain"]) realm = Realm.objects.get(domain=options["domain"])
if options["op"] == "show": if options["op"] == "show":
print "Aliases for %s:" % (realm.domain,) print "Aliases for %s:" % (realm.domain,)
@@ -37,11 +30,7 @@ Usage: python manage.py realm_alias --realm=foo.com --op=[add|remove|show] bar.c
print alias print alias
sys.exit(0) sys.exit(0)
if not args: alias = options['alias']
self.print_help("python manage.py", "realm_alias")
sys.exit(1)
alias = args[0]
if options["op"] == "add": if options["op"] == "add":
if get_realm(alias) is not None: if get_realm(alias) is not None:
print "A Realm already exists for this domain, cannot add it as an alias for another realm!" print "A Realm already exists for this domain, cannot add it as an alias for another realm!"

View File

@@ -1,5 +1,4 @@
from __future__ import absolute_import from __future__ import absolute_import
from optparse import make_option
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from zerver.models import Realm from zerver.models import Realm
@@ -9,43 +8,44 @@ import sys
class Command(BaseCommand): class Command(BaseCommand):
help = """Manage emoji for the specified realm help = """Manage emoji for the specified realm
Usage: python manage.py realm_emoji foo.com NAME IMG_URL
Example: python manage.py realm_emoji --realm=zulip.com --op=add robotheart https://humbug-user-avatars.s3.amazonaws.com/95ffa70fe0e7aea3c052ba91b38a28d8779f5705 Example: python manage.py realm_emoji --realm=zulip.com --op=add robotheart https://humbug-user-avatars.s3.amazonaws.com/95ffa70fe0e7aea3c052ba91b38a28d8779f5705
Example: python manage.py realm_emoji --realm=zulip.com --op=remove robotheart Example: python manage.py realm_emoji --realm=zulip.com --op=remove robotheart
Example: python manage.py realm_emoji --realm=zulip.com --op=show Example: python manage.py realm_emoji --realm=zulip.com --op=show
""" """
option_list = BaseCommand.option_list + ( def add_arguments(self, parser):
make_option('-r', '--realm', parser.add_argument('-r', '--realm',
dest='domain', dest='domain',
type='str', type=str,
help='The name of the realm.'), required=True,
make_option('--op', help='The name of the realm.')
dest='op', parser.add_argument('--op',
type='str', dest='op',
default="show", type=str,
help='What operation to do (add, show, remove).'), default="show",
) help='What operation to do (add, show, remove).')
parser.add_argument('name', metavar='<name>', type=str, nargs='?', default=None,
help="name of the emoji")
parser.add_argument('img_url', metavar='<image url>', type=str, nargs='?',
help="URL of image to display for the emoji")
def handle(self, *args, **options): def handle(self, *args, **options):
if "domain" not in options:
self.print_help("python manage.py", "realm_emoji")
sys.exit(1)
realm = Realm.objects.get(domain=options["domain"]) realm = Realm.objects.get(domain=options["domain"])
if options["op"] == "show": if options["op"] == "show":
for name, url in realm.get_emoji().iteritems(): for name, url in realm.get_emoji().iteritems():
print name, url print name, url
sys.exit(0) sys.exit(0)
if not args: name = options['name']
if name is None:
self.print_help("python manage.py", "realm_emoji") self.print_help("python manage.py", "realm_emoji")
sys.exit(1) sys.exit(1)
name = args[0]
if options["op"] == "add": if options["op"] == "add":
img_url = args[1] img_url = options['img_url']
if img_url is None:
self.print_help("python manage.py", "realm_emoji")
sys.exit(1)
do_add_realm_emoji(realm, name, img_url) do_add_realm_emoji(realm, name, img_url)
sys.exit(0) sys.exit(0)
elif options["op"] == "remove": elif options["op"] == "remove":

View File

@@ -7,9 +7,7 @@ from zerver.lib.actions import do_add_realm_filter, do_remove_realm_filter
import sys import sys
class Command(BaseCommand): class Command(BaseCommand):
help = """Create a realm for the specified domain. help = """Create a link filter rule for the specified domain.
Usage: python manage.py realm_filters foo.com PATTERN URLPATTERN
NOTE: Regexes must be simple enough that they can be easily translated to JavaScript NOTE: Regexes must be simple enough that they can be easily translated to JavaScript
RegExp syntax. In addition to JS-compatible syntax, the following features are available: RegExp syntax. In addition to JS-compatible syntax, the following features are available:
@@ -22,35 +20,38 @@ Example: python manage.py realm_filters --realm=zulip.com --op=remove '#(?P<id>[
Example: python manage.py realm_filters --realm=zulip.com --op=show Example: python manage.py realm_filters --realm=zulip.com --op=show
""" """
option_list = BaseCommand.option_list + ( def add_arguments(self, parser):
make_option('-r', '--realm', parser.add_argument('-r', '--realm',
dest='domain', dest='domain',
type='str', type=str,
help='The name of the realm to adjust filters for.'), required=True,
make_option('--op', help='The name of the realm to adjust filters for.')
dest='op', parser.add_argument('--op',
type='str', dest='op',
default="show", type=str,
help='What operation to do (add, show, remove).'), default="show",
) help='What operation to do (add, show, remove).')
parser.add_argument('pattern', metavar='<pattern>', type=str, nargs='?', default=None,
help="regular expression to match")
parser.add_argument('url_format_string', metavar='<url pattern>', type=str, nargs='?',
help="format string to substitute")
def handle(self, *args, **options): def handle(self, *args, **options):
if "domain" not in options:
self.print_help("python manage.py", "realm_filters")
sys.exit(1)
realm = Realm.objects.get(domain=options["domain"]) realm = Realm.objects.get(domain=options["domain"])
if options["op"] == "show": if options["op"] == "show":
print "%s: %s" % (realm.domain, all_realm_filters().get(realm.domain, "")) print "%s: %s" % (realm.domain, all_realm_filters().get(realm.domain, ""))
sys.exit(0) sys.exit(0)
if not args: pattern = options['pattern']
if not pattern:
self.print_help("python manage.py", "realm_filters") self.print_help("python manage.py", "realm_filters")
sys.exit(1) sys.exit(1)
pattern = args[0]
if options["op"] == "add": if options["op"] == "add":
url_format_string = args[1] url_format_string = options['url_format_string']
if not url_format_string:
self.print_help("python manage.py", "realm_filters")
sys.exit(1)
do_add_realm_filter(realm, pattern, url_format_string) do_add_realm_filter(realm, pattern, url_format_string)
sys.exit(0) sys.exit(0)
elif options["op"] == "remove": elif options["op"] == "remove":

View File

@@ -8,16 +8,20 @@ from zerver.models import Realm, get_realm
import sys import sys
class Command(BaseCommand): class Command(BaseCommand):
help = """Change the stream name for a realm. help = """Change the stream name for a realm."""
Usage: python manage.py rename_stream <domain> <old name> <new name>""" def add_arguments(self, parser):
parser.add_argument('domain', metavar='<domain>', type=str,
help="domain to operate on")
parser.add_argument('old_name', metavar='<old name>', type=str,
help='name of stream to be renamed')
parser.add_argument('new_name', metavar='<new name>', type=str,
help='new name to rename the stream to')
def handle(self, *args, **options): def handle(self, *args, **options):
if len(args) != 3: domain = options['domain']
print "Please provide a domain and the old and new names." old_name = options['old_name']
exit(1) new_name = options['new_name']
domain, old_name, new_name = args
encoding = sys.getfilesystemencoding() encoding = sys.getfilesystemencoding()
try: try:

View File

@@ -4,18 +4,19 @@ from django.core.management.base import BaseCommand
from django.conf import settings from django.conf import settings
class Command(BaseCommand): class Command(BaseCommand):
help = """Send some stats to statsd. help = """Send some stats to statsd."""
Usage: python manage.py send_stats [incr|decr|timing|timer|gauge] name val""" def add_arguments(self, parser):
parser.add_argument('operation', metavar='<operation>', type=str,
choices=['incr', 'decr', 'timing', 'timer', 'gauge'],
help="incr|decr|timing|timer|gauge")
parser.add_argument('name', metavar='<name>', type=str)
parser.add_argument('val', metavar='<val>', type=str)
def handle(self, *args, **options): def handle(self, *args, **options):
if len(args) != 3: operation = options['operation']
print "Usage: python manage.py send_stats [incr|decr|timing|timer|gauge] name val" name = options['name']
exit(1) val = options['val']
operation = args[0]
name = args[1]
val = args[2]
if settings.USING_STATSD: if settings.USING_STATSD:
from statsd import statsd from statsd import statsd

View File

@@ -5,17 +5,14 @@ from zerver.models import Realm
import sys import sys
class Command(BaseCommand): class Command(BaseCommand):
help = """Show the admins in a realm. help = """Show the admins in a realm."""
Usage: ./manage.py show_admins <realm domain> def add_arguments(self, parser):
""" parser.add_argument('realm', metavar='<realm>', type=str,
help="realm to show admins for")
def handle(self, *args, **options): def handle(self, *args, **options):
try: realm = options['realm']
realm = args[0]
except IndexError:
print 'Please specify a realm.'
sys.exit(1)
try: try:
realm = Realm.objects.get(domain=realm) realm = Realm.objects.get(domain=realm)

View File

@@ -6,17 +6,17 @@ from zerver.lib.actions import send_referral_event
from zerver.models import get_user_profile_by_email from zerver.models import get_user_profile_by_email
class Command(BaseCommand): class Command(BaseCommand):
help = """Grants a user invites and resets the number of invites they've used. help = """Grants a user invites and resets the number of invites they've used."""
Usage: python manage.py grant_invites <email> <num invites>""" def add_arguments(self, parser):
parser.add_argument('email', metavar='<email>', type=str,
help="user to grant invites to")
parser.add_argument('num_invites', metavar='<num invites>', type=int,
help="number of invites to grant")
def handle(self, *args, **kwargs): def handle(self, *args, **options):
if len(args) != 2: email = options['email']
print "Please provide an email address and the number of invites." num_invites = options['num_invites']
exit(1)
email = args[0]
num_invites = int(args[1])
user_profile = get_user_profile_by_email(email) user_profile = get_user_profile_by_email(email)
user_profile.invites_granted = num_invites user_profile.invites_granted = num_invites

View File

@@ -9,9 +9,13 @@ class Command(BaseCommand):
fmt = '%-30s %-16s %-32s' fmt = '%-30s %-16s %-32s'
def add_arguments(self, parser):
parser.add_argument('emails', metavar='<email>', type=str, nargs='*',
help="email of user to show password and API key for")
def handle(self, *args, **options): def handle(self, *args, **options):
print self.fmt % ('email', 'password', 'API key') print self.fmt % ('email', 'password', 'API key')
for email in args: for email in options['emails']:
if '@' not in email: if '@' not in email:
print 'ERROR: %s does not look like an email address' % (email,) print 'ERROR: %s does not look like an email address' % (email,)
continue continue