mirror of
https://github.com/zulip/zulip.git
synced 2025-11-02 21:13:36 +00:00
Annotate most Zulip management commands.
This commit is contained in:
@@ -2,6 +2,7 @@ from __future__ import absolute_import
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from zerver.models import UserPresence, UserActivity
|
from zerver.models import UserPresence, UserActivity
|
||||||
from zerver.lib.utils import statsd, statsd_key
|
from zerver.lib.utils import statsd, statsd_key
|
||||||
@@ -15,6 +16,7 @@ class Command(BaseCommand):
|
|||||||
Run as a cron job that runs every 10 minutes."""
|
Run as a cron job that runs every 10 minutes."""
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
# Get list of all active users in the last 1 week
|
# Get list of all active users in the last 1 week
|
||||||
cutoff = datetime.now() - timedelta(minutes=30, hours=168)
|
cutoff = datetime.now() - timedelta(minutes=30, hours=168)
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import datetime
|
|||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
|
from typing import Any
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from zerver.lib.statistics import activity_averages_during_day
|
from zerver.lib.statistics import activity_averages_during_day
|
||||||
|
|
||||||
@@ -16,6 +17,7 @@ class Command(BaseCommand):
|
|||||||
help="Day to query in format 2013-12-05. Default is yesterday"),)
|
help="Day to query in format 2013-12-05. Default is yesterday"),)
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
if options["date"] is None:
|
if options["date"] is None:
|
||||||
date = datetime.datetime.now() - datetime.timedelta(days=1)
|
date = datetime.datetime.now() - datetime.timedelta(days=1)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from zerver.models import Recipient, Message
|
from zerver.models import Recipient, Message
|
||||||
@@ -10,6 +12,7 @@ import time
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
def compute_stats(log_level):
|
def compute_stats(log_level):
|
||||||
|
# type: (int) -> None
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
logger.setLevel(log_level)
|
logger.setLevel(log_level)
|
||||||
|
|
||||||
@@ -76,6 +79,7 @@ class Command(BaseCommand):
|
|||||||
help = "Compute statistics on MIT Zephyr usage."
|
help = "Compute statistics on MIT Zephyr usage."
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
level = logging.INFO
|
level = logging.INFO
|
||||||
if options["verbose"]:
|
if options["verbose"]:
|
||||||
level = logging.DEBUG
|
level = logging.DEBUG
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ from __future__ import absolute_import
|
|||||||
from __future__ import division
|
from __future__ import division
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
from zerver.lib.statistics import seconds_usage_between
|
from zerver.lib.statistics import seconds_usage_between
|
||||||
|
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
@@ -11,6 +13,7 @@ import datetime
|
|||||||
from django.utils.timezone import utc
|
from django.utils.timezone import utc
|
||||||
|
|
||||||
def analyze_activity(options):
|
def analyze_activity(options):
|
||||||
|
# type: (Dict[str, Any]) -> None
|
||||||
day_start = datetime.datetime.strptime(options["date"], "%Y-%m-%d").replace(tzinfo=utc)
|
day_start = datetime.datetime.strptime(options["date"], "%Y-%m-%d").replace(tzinfo=utc)
|
||||||
day_end = day_start + datetime.timedelta(days=options["duration"])
|
day_end = day_start + datetime.timedelta(days=options["duration"])
|
||||||
|
|
||||||
@@ -56,4 +59,5 @@ is shown for all realms"""
|
|||||||
)
|
)
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
analyze_activity(options)
|
analyze_activity(options)
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.db.models import Count
|
from django.db.models import Count, QuerySet
|
||||||
|
|
||||||
from zerver.models import UserActivity, UserProfile, Realm, \
|
from zerver.models import UserActivity, UserProfile, Realm, \
|
||||||
get_realm, get_user_profile_by_email
|
get_realm, get_user_profile_by_email
|
||||||
@@ -19,10 +22,12 @@ 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):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('arg', metavar='<arg>', type=str, nargs='?', default=None,
|
parser.add_argument('arg', metavar='<arg>', type=str, nargs='?', default=None,
|
||||||
help="realm or user to estimate client activity for")
|
help="realm or user to estimate client activity for")
|
||||||
|
|
||||||
def compute_activity(self, user_activity_objects):
|
def compute_activity(self, user_activity_objects):
|
||||||
|
# type: (QuerySet) -> None
|
||||||
# Report data from the past week.
|
# Report data from the past week.
|
||||||
#
|
#
|
||||||
# This is a rough report of client activity because we inconsistently
|
# This is a rough report of client activity because we inconsistently
|
||||||
@@ -54,6 +59,7 @@ python manage.py client_activity jesstess@zulip.com"""
|
|||||||
|
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
if options['arg'] is None:
|
if options['arg'] is None:
|
||||||
# Report global activity.
|
# Report global activity.
|
||||||
self.compute_activity(UserActivity.objects.all())
|
self.compute_activity(UserActivity.objects.all())
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ from __future__ import absolute_import
|
|||||||
from __future__ import division
|
from __future__ import division
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
import datetime
|
import datetime
|
||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
@@ -19,10 +22,12 @@ class Command(BaseCommand):
|
|||||||
help = "Generate statistics on realm activity."
|
help = "Generate statistics on realm activity."
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('realms', metavar='<realm>', type=str, nargs='*',
|
parser.add_argument('realms', metavar='<realm>', type=str, nargs='*',
|
||||||
help="realm to generate statistics for")
|
help="realm to generate statistics for")
|
||||||
|
|
||||||
def active_users(self, realm):
|
def active_users(self, realm):
|
||||||
|
# type: (Realm) -> List[UserProfile]
|
||||||
# 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)
|
||||||
return [activity.user_profile for activity in \
|
return [activity.user_profile for activity in \
|
||||||
@@ -33,36 +38,44 @@ class Command(BaseCommand):
|
|||||||
client__name="website")]
|
client__name="website")]
|
||||||
|
|
||||||
def messages_sent_by(self, user, days_ago):
|
def messages_sent_by(self, user, days_ago):
|
||||||
|
# type: (UserProfile, int) -> int
|
||||||
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
|
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
|
||||||
return human_messages.filter(sender=user, pub_date__gt=sent_time_cutoff).count()
|
return human_messages.filter(sender=user, pub_date__gt=sent_time_cutoff).count()
|
||||||
|
|
||||||
def total_messages(self, realm, days_ago):
|
def total_messages(self, realm, days_ago):
|
||||||
|
# type: (Realm, int) -> int
|
||||||
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
|
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
|
||||||
return Message.objects.filter(sender__realm=realm, pub_date__gt=sent_time_cutoff).count()
|
return Message.objects.filter(sender__realm=realm, pub_date__gt=sent_time_cutoff).count()
|
||||||
|
|
||||||
def human_messages(self, realm, days_ago):
|
def human_messages(self, realm, days_ago):
|
||||||
|
# type: (Realm, int) -> int
|
||||||
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
|
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
|
||||||
return human_messages.filter(sender__realm=realm, pub_date__gt=sent_time_cutoff).count()
|
return human_messages.filter(sender__realm=realm, pub_date__gt=sent_time_cutoff).count()
|
||||||
|
|
||||||
def api_messages(self, realm, days_ago):
|
def api_messages(self, realm, days_ago):
|
||||||
|
# type: (Realm, int) -> int
|
||||||
return (self.total_messages(realm, days_ago) - self.human_messages(realm, days_ago))
|
return (self.total_messages(realm, days_ago) - self.human_messages(realm, days_ago))
|
||||||
|
|
||||||
def stream_messages(self, realm, days_ago):
|
def stream_messages(self, realm, days_ago):
|
||||||
|
# type: (Realm, int) -> int
|
||||||
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
|
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
|
||||||
return human_messages.filter(sender__realm=realm, pub_date__gt=sent_time_cutoff,
|
return human_messages.filter(sender__realm=realm, pub_date__gt=sent_time_cutoff,
|
||||||
recipient__type=Recipient.STREAM).count()
|
recipient__type=Recipient.STREAM).count()
|
||||||
|
|
||||||
def private_messages(self, realm, days_ago):
|
def private_messages(self, realm, days_ago):
|
||||||
|
# type: (Realm, int) -> int
|
||||||
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
|
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
|
||||||
return human_messages.filter(sender__realm=realm, pub_date__gt=sent_time_cutoff).exclude(
|
return human_messages.filter(sender__realm=realm, pub_date__gt=sent_time_cutoff).exclude(
|
||||||
recipient__type=Recipient.STREAM).exclude(recipient__type=Recipient.HUDDLE).count()
|
recipient__type=Recipient.STREAM).exclude(recipient__type=Recipient.HUDDLE).count()
|
||||||
|
|
||||||
def group_private_messages(self, realm, days_ago):
|
def group_private_messages(self, realm, days_ago):
|
||||||
|
# type: (Realm, int) -> int
|
||||||
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
|
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
|
||||||
return human_messages.filter(sender__realm=realm, pub_date__gt=sent_time_cutoff).exclude(
|
return human_messages.filter(sender__realm=realm, pub_date__gt=sent_time_cutoff).exclude(
|
||||||
recipient__type=Recipient.STREAM).exclude(recipient__type=Recipient.PERSONAL).count()
|
recipient__type=Recipient.STREAM).exclude(recipient__type=Recipient.PERSONAL).count()
|
||||||
|
|
||||||
def report_percentage(self, numerator, denominator, text):
|
def report_percentage(self, numerator, denominator, text):
|
||||||
|
# type: (float, float, str) -> None
|
||||||
if not denominator:
|
if not denominator:
|
||||||
fraction = 0.0
|
fraction = 0.0
|
||||||
else:
|
else:
|
||||||
@@ -70,6 +83,7 @@ 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):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
if options['realms']:
|
if options['realms']:
|
||||||
try:
|
try:
|
||||||
realms = [get_realm(domain) for domain in options['realms']]
|
realms = [get_realm(domain) for domain in options['realms']]
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from zerver.models import Realm, Stream, Message, Subscription, Recipient, get_realm
|
from zerver.models import Realm, Stream, Message, Subscription, Recipient, get_realm
|
||||||
@@ -9,10 +12,12 @@ 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):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('realms', metavar='<realm>', type=str, nargs='*',
|
parser.add_argument('realms', metavar='<realm>', type=str, nargs='*',
|
||||||
help="realm to generate statistics for")
|
help="realm to generate statistics for")
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
if options['realms']:
|
if options['realms']:
|
||||||
try:
|
try:
|
||||||
realms = [get_realm(domain) for domain in options['realms']]
|
realms = [get_realm(domain) for domain in options['realms']]
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
import datetime
|
import datetime
|
||||||
import pytz
|
import pytz
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from zerver.models import UserProfile, Realm, Stream, Message, get_realm
|
from zerver.models import UserProfile, Realm, Stream, Message, get_realm
|
||||||
@@ -12,15 +14,18 @@ class Command(BaseCommand):
|
|||||||
help = "Generate statistics on user activity."
|
help = "Generate statistics on user activity."
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('realms', metavar='<realm>', type=str, nargs='*',
|
parser.add_argument('realms', metavar='<realm>', type=str, nargs='*',
|
||||||
help="realm to generate statistics for")
|
help="realm to generate statistics for")
|
||||||
|
|
||||||
def messages_sent_by(self, user, week):
|
def messages_sent_by(self, user, week):
|
||||||
|
# type: (UserProfile, int) -> int
|
||||||
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):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
if options['realms']:
|
if options['realms']:
|
||||||
try:
|
try:
|
||||||
realms = [get_realm(domain) for domain in options['realms']]
|
realms = [get_realm(domain) for domain in options['realms']]
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
__revision__ = '$Id: cleanupconfirmation.py 5 2008-11-18 09:10:12Z jarek.zgoda $'
|
__revision__ = '$Id: cleanupconfirmation.py 5 2008-11-18 09:10:12Z jarek.zgoda $'
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.core.management.base import NoArgsCommand
|
from django.core.management.base import NoArgsCommand
|
||||||
|
|
||||||
@@ -14,4 +15,5 @@ class Command(NoArgsCommand):
|
|||||||
help = 'Delete expired confirmations from database'
|
help = 'Delete expired confirmations from database'
|
||||||
|
|
||||||
def handle_noargs(self, **options):
|
def handle_noargs(self, **options):
|
||||||
|
# type: (**Any) -> None
|
||||||
Confirmation.objects.delete_expired_confirmations()
|
Confirmation.objects.delete_expired_confirmations()
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ from __future__ import print_function
|
|||||||
|
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
from zerver.lib.actions import create_stream_if_needed, do_add_subscription
|
from zerver.lib.actions import create_stream_if_needed, do_add_subscription
|
||||||
@@ -32,6 +34,7 @@ class Command(BaseCommand):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def handle(self, **options):
|
def handle(self, **options):
|
||||||
|
# type: (**Any) -> None
|
||||||
if options["domain"] is None or options["streams"] is None or \
|
if options["domain"] is None or options["streams"] is None or \
|
||||||
(options["users"] is None and options["all_users"] is None):
|
(options["users"] is None and options["all_users"] is None):
|
||||||
self.print_help("python manage.py", "add_users_to_streams")
|
self.print_help("python manage.py", "add_users_to_streams")
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
from zerver.lib.actions import do_update_message_flags
|
from zerver.lib.actions import do_update_message_flags
|
||||||
@@ -10,10 +13,12 @@ class Command(BaseCommand):
|
|||||||
help = """Bankrupt one or many users."""
|
help = """Bankrupt one or many users."""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('emails', metavar='<email>', type=str, nargs='+',
|
parser.add_argument('emails', metavar='<email>', type=str, nargs='+',
|
||||||
help='email address to bankrupt')
|
help='email address to bankrupt')
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
for email in options['emails']:
|
for email in options['emails']:
|
||||||
try:
|
try:
|
||||||
user_profile = get_user_profile_by_email(email)
|
user_profile = get_user_profile_by_email(email)
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
from zerver.lib.actions import do_change_full_name
|
from zerver.lib.actions import do_change_full_name
|
||||||
@@ -10,10 +13,12 @@ class Command(BaseCommand):
|
|||||||
help = """Change the names for many users."""
|
help = """Change the names for many users."""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('data_file', metavar='<data file>', type=str,
|
parser.add_argument('data_file', metavar='<data file>', type=str,
|
||||||
help="file containing 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):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
data_file = options['data_file']
|
data_file = options['data_file']
|
||||||
with open(data_file, "r") as f:
|
with open(data_file, "r") as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
from zerver.lib.actions import do_change_user_email
|
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
|
||||||
|
|
||||||
@@ -10,12 +12,14 @@ class Command(BaseCommand):
|
|||||||
help = """Change the email address for a user."""
|
help = """Change the email address for a user."""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('old_email', metavar='<old email>', type=str,
|
parser.add_argument('old_email', metavar='<old email>', type=str,
|
||||||
help='email address to change')
|
help='email address to change')
|
||||||
parser.add_argument('new_email', metavar='<new email>', type=str,
|
parser.add_argument('new_email', metavar='<new email>', type=str,
|
||||||
help='new email address')
|
help='new email address')
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
old_email = options['old_email']
|
old_email = options['old_email']
|
||||||
new_email = options['new_email']
|
new_email = options['new_email']
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from zerver.lib.push_notifications import check_apns_feedback
|
from zerver.lib.push_notifications import check_apns_feedback
|
||||||
|
|
||||||
@@ -10,4 +12,5 @@ class Command(BaseCommand):
|
|||||||
Usage: ./manage.py check_apns_tokens"""
|
Usage: ./manage.py check_apns_tokens"""
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
check_apns_feedback()
|
check_apns_feedback()
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any, Callable, Optional
|
||||||
|
|
||||||
from zerver.models import get_user_profile_by_id
|
from zerver.models import get_user_profile_by_id
|
||||||
from zerver.lib.rate_limiter import client, max_api_calls, max_api_window
|
from zerver.lib.rate_limiter import client, max_api_calls, max_api_window
|
||||||
|
|
||||||
@@ -24,6 +26,7 @@ class Command(BaseCommand):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def _check_within_range(self, key, count_func, trim_func=None):
|
def _check_within_range(self, key, count_func, trim_func=None):
|
||||||
|
# type: ignore # should be (str, Callable[[], int], Optional[Callable[[str, int], None]]) -> None
|
||||||
user_id = int(key.split(':')[1])
|
user_id = int(key.split(':')[1])
|
||||||
try:
|
try:
|
||||||
user = get_user_profile_by_id(user_id)
|
user = get_user_profile_by_id(user_id)
|
||||||
@@ -44,6 +47,7 @@ than max_api_calls! (trying to trim) %s %s" % (key, count))
|
|||||||
trim_func(key, max_calls)
|
trim_func(key, max_calls)
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
if not settings.RATE_LIMITING:
|
if not settings.RATE_LIMITING:
|
||||||
print("This machine is not using redis or rate limiting, aborting")
|
print("This machine is not using redis or rate limiting, aborting")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ from __future__ import absolute_import
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@@ -11,7 +12,8 @@ class Command(BaseCommand):
|
|||||||
help = """Checks your Zulip Voyager Django configuration for issues."""
|
help = """Checks your Zulip Voyager Django configuration for issues."""
|
||||||
|
|
||||||
option_list = BaseCommand.option_list + ()
|
option_list = BaseCommand.option_list + ()
|
||||||
def handle(self, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
for (setting_name, default) in settings.REQUIRED_SETTINGS:
|
for (setting_name, default) in settings.REQUIRED_SETTINGS:
|
||||||
try:
|
try:
|
||||||
if settings.__getattr__(setting_name) != default:
|
if settings.__getattr__(setting_name) != default:
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ from __future__ import absolute_import
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from zerver.lib.actions import do_create_realm, set_default_streams
|
from zerver.lib.actions import do_create_realm, set_default_streams
|
||||||
@@ -40,6 +42,7 @@ Usage: python manage.py create_realm --domain=foo.com --name='Foo, Inc.'"""
|
|||||||
)
|
)
|
||||||
|
|
||||||
def validate_domain(self, domain):
|
def validate_domain(self, domain):
|
||||||
|
# type: (str) -> None
|
||||||
# Domains can't contain whitespace if they are to be used in memcached
|
# Domains can't contain whitespace if they are to be used in memcached
|
||||||
# keys. Seems safer to leave that as the default case regardless of
|
# keys. Seems safer to leave that as the default case regardless of
|
||||||
# which backing store we use.
|
# which backing store we use.
|
||||||
@@ -56,6 +59,7 @@ Usage: python manage.py create_realm --domain=foo.com --name='Foo, Inc.'"""
|
|||||||
raise ValueError("Cannot create a new realm that is already an alias for an existing realm")
|
raise ValueError("Cannot create a new realm that is already an alias for an existing realm")
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
if options["domain"] is None or options["name"] is None:
|
if options["domain"] is None or options["name"] is None:
|
||||||
print("\033[1;31mPlease provide both a domain and name.\033[0m\n", file=sys.stderr)
|
print("\033[1;31mPlease provide both a domain and name.\033[0m\n", file=sys.stderr)
|
||||||
self.print_help("python manage.py", "create_realm")
|
self.print_help("python manage.py", "create_realm")
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
from zerver.lib.actions import do_create_stream
|
from zerver.lib.actions import do_create_stream
|
||||||
from zerver.models import Realm, get_realm
|
from zerver.models import Realm, get_realm
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
@@ -15,12 +18,14 @@ This should be used for TESTING only, unless you understand the limitations of
|
|||||||
the command."""
|
the command."""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('domain', metavar='<domain>', type=str,
|
parser.add_argument('domain', metavar='<domain>', type=str,
|
||||||
help='domain in which to create the stream')
|
help='domain in which to create the stream')
|
||||||
parser.add_argument('stream_name', metavar='<stream name>', type=str,
|
parser.add_argument('stream_name', metavar='<stream name>', type=str,
|
||||||
help='name of stream to create')
|
help='name of stream to create')
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
domain = options['domain']
|
domain = options['domain']
|
||||||
stream_name = options['stream_name']
|
stream_name = options['stream_name']
|
||||||
encoding = sys.getfilesystemencoding()
|
encoding = sys.getfilesystemencoding()
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
@@ -25,6 +27,7 @@ Omit both <email> and <full name> for interactive user creation.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (argparse.ArgumentParser) -> None
|
||||||
parser.add_argument('--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",
|
||||||
@@ -40,6 +43,7 @@ Omit both <email> and <full name> for interactive user creation.
|
|||||||
help='full name of new user')
|
help='full name of new user')
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
if not options["tos"]:
|
if not options["tos"]:
|
||||||
raise CommandError("""You must confirm that this user has accepted the
|
raise CommandError("""You must confirm that this user has accepted the
|
||||||
Terms of Service by passing --this-user-has-accepted-the-tos.""")
|
Terms of Service by passing --this-user-has-accepted-the-tos.""")
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from zerver.lib.actions import do_deactivate_realm
|
from zerver.lib.actions import do_deactivate_realm
|
||||||
@@ -12,10 +15,12 @@ class Command(BaseCommand):
|
|||||||
help = """Script to deactivate a realm."""
|
help = """Script to deactivate a realm."""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('domain', metavar='<domain>', type=str,
|
parser.add_argument('domain', metavar='<domain>', type=str,
|
||||||
help='domain of realm to deactivate')
|
help='domain of realm to deactivate')
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
realm = get_realm(options["domain"])
|
realm = get_realm(options["domain"])
|
||||||
if realm is None:
|
if realm is None:
|
||||||
print("Could not find realm %s" % (options["domain"],))
|
print("Could not find realm %s" % (options["domain"],))
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
@@ -12,6 +15,7 @@ class Command(BaseCommand):
|
|||||||
help = "Deactivate a user, including forcibly logging them out."
|
help = "Deactivate a user, including forcibly logging them out."
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('-f', '--for-real',
|
parser.add_argument('-f', '--for-real',
|
||||||
dest='for_real',
|
dest='for_real',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
@@ -21,6 +25,7 @@ class Command(BaseCommand):
|
|||||||
help='email of user to deactivate')
|
help='email of user to deactivate')
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
user_profile = get_user_profile_by_email(options['email'])
|
user_profile = get_user_profile_by_email(options['email'])
|
||||||
|
|
||||||
print("Deactivating %s (%s) - %s" % (user_profile.full_name,
|
print("Deactivating %s (%s) - %s" % (user_profile.full_name,
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
from zerver.lib.actions import do_delete_old_unclaimed_attachments
|
from zerver.lib.actions import do_delete_old_unclaimed_attachments
|
||||||
@@ -12,6 +15,7 @@ class Command(BaseCommand):
|
|||||||
One week is taken as the default value."""
|
One week is taken as the default value."""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('-w', '--weeks',
|
parser.add_argument('-w', '--weeks',
|
||||||
dest='delta_weeks',
|
dest='delta_weeks',
|
||||||
default=1,
|
default=1,
|
||||||
@@ -24,7 +28,7 @@ class Command(BaseCommand):
|
|||||||
help="Actually remove the files from the storage.")
|
help="Actually remove the files from the storage.")
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
delta_weeks = options['delta_weeks']
|
delta_weeks = options['delta_weeks']
|
||||||
print("Deleting unclaimed attached files older than %s" % (delta_weeks,))
|
print("Deleting unclaimed attached files older than %s" % (delta_weeks,))
|
||||||
print("")
|
print("")
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from zerver.models import get_realm, Message, Realm, Stream, Recipient
|
from zerver.models import get_realm, Message, Realm, Stream, Recipient
|
||||||
@@ -24,6 +26,7 @@ class Command(BaseCommand):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
realm = get_realm(options["domain"])
|
realm = get_realm(options["domain"])
|
||||||
streams = Stream.objects.filter(realm=realm, invite_only=False)
|
streams = Stream.objects.filter(realm=realm, invite_only=False)
|
||||||
recipients = Recipient.objects.filter(
|
recipients = Recipient.objects.filter(
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ This script can be used via two mechanisms:
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
import email
|
import email
|
||||||
import os
|
import os
|
||||||
from email.header import decode_header
|
from email.header import decode_header
|
||||||
@@ -123,9 +126,11 @@ def login_failed(failure):
|
|||||||
return failure
|
return failure
|
||||||
|
|
||||||
def done(_):
|
def done(_):
|
||||||
|
# type: (Any) -> None
|
||||||
reactor.callLater(0, reactor.stop)
|
reactor.callLater(0, reactor.stop)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
# type: () -> None
|
||||||
imap_client = protocol.ClientCreator(reactor, imap4.IMAP4Client)
|
imap_client = protocol.ClientCreator(reactor, imap4.IMAP4Client)
|
||||||
d = imap_client.connectSSL(settings.EMAIL_GATEWAY_IMAP_SERVER, settings.EMAIL_GATEWAY_IMAP_PORT, ssl.ClientContextFactory())
|
d = imap_client.connectSSL(settings.EMAIL_GATEWAY_IMAP_SERVER, settings.EMAIL_GATEWAY_IMAP_PORT, ssl.ClientContextFactory())
|
||||||
d.addCallbacks(connected, login_failed)
|
d.addCallbacks(connected, login_failed)
|
||||||
@@ -135,10 +140,12 @@ class Command(BaseCommand):
|
|||||||
help = __doc__
|
help = __doc__
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('recipient', metavar='<recipient>', type=str, nargs='?', default=None,
|
parser.add_argument('recipient', metavar='<recipient>', type=str, nargs='?', default=None,
|
||||||
help="original recipient")
|
help="original recipient")
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
rcpt_to = os.environ.get("ORIGINAL_RECIPIENT", options['recipient'])
|
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):
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import datetime
|
|||||||
import pytz
|
import pytz
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
@@ -25,6 +27,7 @@ logger.addHandler(file_handler)
|
|||||||
|
|
||||||
VALID_DIGEST_DAYS = (1, 2, 3, 4)
|
VALID_DIGEST_DAYS = (1, 2, 3, 4)
|
||||||
def inactive_since(user_profile, cutoff):
|
def inactive_since(user_profile, cutoff):
|
||||||
|
# type: (UserProfile, datetime.datetime) -> bool
|
||||||
# Hasn't used the app in the last 24 business-day hours.
|
# Hasn't used the app in the last 24 business-day hours.
|
||||||
most_recent_visit = [row.last_visit for row in \
|
most_recent_visit = [row.last_visit for row in \
|
||||||
UserActivity.objects.filter(
|
UserActivity.objects.filter(
|
||||||
@@ -38,6 +41,7 @@ def inactive_since(user_profile, cutoff):
|
|||||||
return last_visit < cutoff
|
return last_visit < cutoff
|
||||||
|
|
||||||
def last_business_day():
|
def last_business_day():
|
||||||
|
# type: () -> datetime.datetime
|
||||||
one_day = datetime.timedelta(hours=23)
|
one_day = datetime.timedelta(hours=23)
|
||||||
previous_day = datetime.datetime.now(tz=pytz.utc) - one_day
|
previous_day = datetime.datetime.now(tz=pytz.utc) - one_day
|
||||||
while previous_day.weekday() not in VALID_DIGEST_DAYS:
|
while previous_day.weekday() not in VALID_DIGEST_DAYS:
|
||||||
@@ -47,12 +51,14 @@ def last_business_day():
|
|||||||
# Changes to this should also be reflected in
|
# Changes to this should also be reflected in
|
||||||
# zerver/worker/queue_processors.py:DigestWorker.consume()
|
# zerver/worker/queue_processors.py:DigestWorker.consume()
|
||||||
def queue_digest_recipient(user_profile, cutoff):
|
def queue_digest_recipient(user_profile, cutoff):
|
||||||
|
# type: (UserProfile, datetime.datetime) -> None
|
||||||
# Convert cutoff to epoch seconds for transit.
|
# Convert cutoff to epoch seconds for transit.
|
||||||
event = {"user_profile_id": user_profile.id,
|
event = {"user_profile_id": user_profile.id,
|
||||||
"cutoff": cutoff.strftime('%s')}
|
"cutoff": cutoff.strftime('%s')}
|
||||||
queue_json_publish("digest_emails", event, lambda event: None)
|
queue_json_publish("digest_emails", event, lambda event: None)
|
||||||
|
|
||||||
def domains_for_this_deployment():
|
def domains_for_this_deployment():
|
||||||
|
# type: () -> List[str]
|
||||||
if settings.ZULIP_COM:
|
if settings.ZULIP_COM:
|
||||||
# Voyager deployments don't have a Deployment entry.
|
# Voyager deployments don't have a Deployment entry.
|
||||||
# Only send zulip.com digests on staging.
|
# Only send zulip.com digests on staging.
|
||||||
@@ -69,6 +75,7 @@ def domains_for_this_deployment():
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
def should_process_digest(domain, deployment_domains):
|
def should_process_digest(domain, deployment_domains):
|
||||||
|
# type: (str, List[str]) -> bool
|
||||||
if settings.VOYAGER:
|
if settings.VOYAGER:
|
||||||
# Voyager. We ship with a zulip.com realm for the feedback bot, but
|
# Voyager. We ship with a zulip.com realm for the feedback bot, but
|
||||||
# don't try to send e-mails to it.
|
# don't try to send e-mails to it.
|
||||||
@@ -85,6 +92,7 @@ class Command(BaseCommand):
|
|||||||
in a while.
|
in a while.
|
||||||
"""
|
"""
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
# To be really conservative while we don't have user timezones or
|
# To be really conservative while we don't have user timezones or
|
||||||
# special-casing for companies with non-standard workweeks, only
|
# special-casing for companies with non-standard workweeks, only
|
||||||
# try to send mail on Tuesdays, Wednesdays, and Thursdays.
|
# try to send mail on Tuesdays, Wednesdays, and Thursdays.
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from zerver.lib.queue import queue_json_publish
|
from zerver.lib.queue import queue_json_publish
|
||||||
|
|
||||||
@@ -9,6 +12,7 @@ import ujson
|
|||||||
|
|
||||||
|
|
||||||
def error(*args):
|
def error(*args):
|
||||||
|
# type: (*Any) -> None
|
||||||
raise Exception('We cannot enqueue because settings.USING_RABBITMQ is False.')
|
raise Exception('We cannot enqueue because settings.USING_RABBITMQ is False.')
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
@@ -23,12 +27,14 @@ You can use "-" to represent stdin.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('queue_name', metavar='<queue>', type=str,
|
parser.add_argument('queue_name', metavar='<queue>', type=str,
|
||||||
help="name of worker queue to enqueue to")
|
help="name of worker queue to enqueue to")
|
||||||
parser.add_argument('file_name', metavar='<file>', type=str,
|
parser.add_argument('file_name', metavar='<file>', type=str,
|
||||||
help="name of file containing JSON lines")
|
help="name of file containing JSON lines")
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
queue_name = options['queue_name']
|
queue_name = options['queue_name']
|
||||||
file_name = options['file_name']
|
file_name = options['file_name']
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from zerver.lib.cache_helpers import fill_remote_cache, cache_fillers
|
from zerver.lib.cache_helpers import fill_remote_cache, cache_fillers
|
||||||
@@ -10,8 +12,10 @@ class Command(BaseCommand):
|
|||||||
help = "Populate the memcached cache of messages."
|
help = "Populate the memcached cache of messages."
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
if options["cache"] is not None:
|
if options["cache"] is not None:
|
||||||
return fill_remote_cache(options["cache"])
|
fill_remote_cache(options["cache"])
|
||||||
|
return
|
||||||
|
|
||||||
for cache in cache_fillers.keys():
|
for cache in cache_fillers.keys():
|
||||||
fill_remote_cache(cache)
|
fill_remote_cache(cache)
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
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,6 +13,7 @@ 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."
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('--domain',
|
parser.add_argument('--domain',
|
||||||
dest='domain',
|
dest='domain',
|
||||||
type=str,
|
type=str,
|
||||||
@@ -23,6 +27,7 @@ class Command(BaseCommand):
|
|||||||
help='email of user to generate an activation link for')
|
help='email of user to generate an activation link for')
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
duplicates = False
|
duplicates = False
|
||||||
for email in options['emails']:
|
for email in options['emails']:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
import requests
|
import requests
|
||||||
from zerver.models import get_user_profile_by_email, UserProfile
|
from zerver.models import get_user_profile_by_email, UserProfile
|
||||||
from zerver.lib.avatar import gravatar_hash
|
from zerver.lib.avatar import gravatar_hash
|
||||||
@@ -13,12 +16,14 @@ email addresses are specified, use the Gravatar for the first and upload the ima
|
|||||||
for both email addresses."""
|
for both email addresses."""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('old_email', metavar='<old email>', type=str,
|
parser.add_argument('old_email', metavar='<old email>', type=str,
|
||||||
help="user whose Gravatar should be migrated")
|
help="user whose Gravatar should be migrated")
|
||||||
parser.add_argument('new_email', metavar='<new email>', type=str, nargs='?', default=None,
|
parser.add_argument('new_email', metavar='<new email>', type=str, nargs='?', default=None,
|
||||||
help="user to copy the Gravatar to")
|
help="user to copy the Gravatar to")
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
old_email = options['old_email']
|
old_email = options['old_email']
|
||||||
|
|
||||||
if options['new_email']:
|
if options['new_email']:
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
from typing import Any, Iterable, Tuple
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
@@ -14,6 +16,7 @@ from optparse import make_option
|
|||||||
settings.TORNADO_SERVER = None
|
settings.TORNADO_SERVER = None
|
||||||
|
|
||||||
def create_users(name_list, bot_type=None):
|
def create_users(name_list, bot_type=None):
|
||||||
|
# type: (Iterable[Tuple[str, str]], int) -> None
|
||||||
realms = {}
|
realms = {}
|
||||||
for realm in Realm.objects.all():
|
for realm in Realm.objects.all():
|
||||||
realms[realm.domain] = realm
|
realms[realm.domain] = realm
|
||||||
@@ -35,7 +38,8 @@ class Command(BaseCommand):
|
|||||||
help='The number of extra users to create'),
|
help='The number of extra users to create'),
|
||||||
)
|
)
|
||||||
|
|
||||||
def handle(self, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
Realm.objects.create(domain="zulip.com")
|
Realm.objects.create(domain="zulip.com")
|
||||||
|
|
||||||
names = [(settings.FEEDBACK_BOT_NAME, settings.FEEDBACK_BOT)]
|
names = [(settings.FEEDBACK_BOT_NAME, settings.FEEDBACK_BOT)]
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
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,6 +18,7 @@ ONLY perform this on customer request from an authorized person.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('-f', '--for-real',
|
parser.add_argument('-f', '--for-real',
|
||||||
dest='ack',
|
dest='ack',
|
||||||
action="store_true",
|
action="store_true",
|
||||||
@@ -34,6 +38,7 @@ ONLY perform this on customer request from an authorized person.
|
|||||||
help="email of user to knight")
|
help="email of user to knight")
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
email = options['email']
|
email = options['email']
|
||||||
try:
|
try:
|
||||||
profile = UserProfile.objects.get(email=email)
|
profile = UserProfile.objects.get(email=email)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
@@ -24,6 +25,7 @@ class Command(BaseCommand):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
if options["realm"]:
|
if options["realm"]:
|
||||||
realm = get_realm(options["realm"])
|
realm = get_realm(options["realm"])
|
||||||
delete_realm_user_sessions(realm)
|
delete_realm_user_sessions(realm)
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ http://stackoverflow.com/questions/2090717/getting-translation-strings-for-jinja
|
|||||||
"""
|
"""
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
from typing import Any, Dict, Iterable, Mapping, Set, Tuple
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import glob
|
import glob
|
||||||
@@ -53,6 +56,7 @@ regexes = ['{{#tr .*?}}(.*?){{/tr}}',
|
|||||||
frontend_compiled_regexes = [re.compile(regex) for regex in regexes]
|
frontend_compiled_regexes = [re.compile(regex) for regex in regexes]
|
||||||
|
|
||||||
def strip_whitespaces(src):
|
def strip_whitespaces(src):
|
||||||
|
# type: (str) -> str
|
||||||
src = strip_whitespace_left.sub(r'\1', src)
|
src = strip_whitespace_left.sub(r'\1', src)
|
||||||
src = strip_whitespace_right.sub(r'\1', src)
|
src = strip_whitespace_right.sub(r'\1', src)
|
||||||
return src
|
return src
|
||||||
@@ -60,6 +64,7 @@ def strip_whitespaces(src):
|
|||||||
class Command(makemessages.Command):
|
class Command(makemessages.Command):
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
super(Command, self).add_arguments(parser)
|
super(Command, self).add_arguments(parser)
|
||||||
parser.add_argument('--frontend-source', type=str,
|
parser.add_argument('--frontend-source', type=str,
|
||||||
default='static/templates',
|
default='static/templates',
|
||||||
@@ -72,10 +77,12 @@ class Command(makemessages.Command):
|
|||||||
help='Namespace of the frontend locale file')
|
help='Namespace of the frontend locale file')
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
self.handle_django_locales(*args, **options)
|
self.handle_django_locales(*args, **options)
|
||||||
self.handle_frontend_locales(*args, **options)
|
self.handle_frontend_locales(*args, **options)
|
||||||
|
|
||||||
def handle_frontend_locales(self, *args, **options):
|
def handle_frontend_locales(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
self.frontend_source = options.get('frontend_source')
|
self.frontend_source = options.get('frontend_source')
|
||||||
self.frontend_output = options.get('frontend_output')
|
self.frontend_output = options.get('frontend_output')
|
||||||
self.frontend_namespace = options.get('frontend_namespace')
|
self.frontend_namespace = options.get('frontend_namespace')
|
||||||
@@ -87,6 +94,7 @@ class Command(makemessages.Command):
|
|||||||
self.write_translation_strings(translation_strings)
|
self.write_translation_strings(translation_strings)
|
||||||
|
|
||||||
def handle_django_locales(self, *args, **options):
|
def handle_django_locales(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
old_endblock_re = trans_real.endblock_re
|
old_endblock_re = trans_real.endblock_re
|
||||||
old_block_re = trans_real.block_re
|
old_block_re = trans_real.block_re
|
||||||
old_constant_re = trans_real.constant_re
|
old_constant_re = trans_real.constant_re
|
||||||
@@ -117,7 +125,8 @@ class Command(makemessages.Command):
|
|||||||
trans_real.constant_re = old_constant_re
|
trans_real.constant_re = old_constant_re
|
||||||
|
|
||||||
def extract_strings(self, data):
|
def extract_strings(self, data):
|
||||||
translation_strings = {}
|
# type: (str) -> Dict[str, str]
|
||||||
|
translation_strings = {} # type: Dict[str, str]
|
||||||
for regex in frontend_compiled_regexes:
|
for regex in frontend_compiled_regexes:
|
||||||
for match in regex.findall(data):
|
for match in regex.findall(data):
|
||||||
translation_strings[match] = ""
|
translation_strings[match] = ""
|
||||||
@@ -125,6 +134,7 @@ class Command(makemessages.Command):
|
|||||||
return translation_strings
|
return translation_strings
|
||||||
|
|
||||||
def get_translation_strings(self):
|
def get_translation_strings(self):
|
||||||
|
# type: () -> Dict[str, str]
|
||||||
translation_strings = {} # type: Dict[str, str]
|
translation_strings = {} # type: Dict[str, str]
|
||||||
dirname = self.get_template_dir()
|
dirname = self.get_template_dir()
|
||||||
|
|
||||||
@@ -137,13 +147,16 @@ class Command(makemessages.Command):
|
|||||||
return translation_strings
|
return translation_strings
|
||||||
|
|
||||||
def get_template_dir(self):
|
def get_template_dir(self):
|
||||||
|
# type: () -> str
|
||||||
return self.frontend_source
|
return self.frontend_source
|
||||||
|
|
||||||
|
|
||||||
def get_namespace(self):
|
def get_namespace(self):
|
||||||
|
# type: () -> str
|
||||||
return self.frontend_namespace
|
return self.frontend_namespace
|
||||||
|
|
||||||
def get_locales(self):
|
def get_locales(self):
|
||||||
|
# type: () -> Iterable[str]
|
||||||
locale = self.frontend_locale
|
locale = self.frontend_locale
|
||||||
exclude = self.frontend_exclude
|
exclude = self.frontend_exclude
|
||||||
process_all = self.frontend_all
|
process_all = self.frontend_all
|
||||||
@@ -159,9 +172,11 @@ class Command(makemessages.Command):
|
|||||||
return set(locales) - set(exclude)
|
return set(locales) - set(exclude)
|
||||||
|
|
||||||
def get_base_path(self):
|
def get_base_path(self):
|
||||||
|
# type: () -> str
|
||||||
return self.frontend_output
|
return self.frontend_output
|
||||||
|
|
||||||
def get_output_paths(self):
|
def get_output_paths(self):
|
||||||
|
# type: () -> Iterable[str]
|
||||||
base_path = self.get_base_path()
|
base_path = self.get_base_path()
|
||||||
locales = self.get_locales()
|
locales = self.get_locales()
|
||||||
for path in [os.path.join(base_path, locale) for locale in locales]:
|
for path in [os.path.join(base_path, locale) for locale in locales]:
|
||||||
@@ -171,17 +186,19 @@ class Command(makemessages.Command):
|
|||||||
yield os.path.join(path, self.get_namespace())
|
yield os.path.join(path, self.get_namespace())
|
||||||
|
|
||||||
def get_new_strings(self, old_strings, translation_strings):
|
def get_new_strings(self, old_strings, translation_strings):
|
||||||
|
# type: (Mapping[str, str], Iterable[str]) -> Dict[str, str]
|
||||||
"""
|
"""
|
||||||
Missing strings are removed, new strings are added and already
|
Missing strings are removed, new strings are added and already
|
||||||
translated strings are not touched.
|
translated strings are not touched.
|
||||||
"""
|
"""
|
||||||
new_strings = {}
|
new_strings = {} # Dict[str, str]
|
||||||
for k in translation_strings:
|
for k in translation_strings:
|
||||||
new_strings[k] = old_strings.get(k, k)
|
new_strings[k] = old_strings.get(k, k)
|
||||||
|
|
||||||
return new_strings
|
return new_strings
|
||||||
|
|
||||||
def write_translation_strings(self, translation_strings):
|
def write_translation_strings(self, translation_strings):
|
||||||
|
# type: (Iterable[str]) -> None
|
||||||
for locale, output_path in zip(self.get_locales(), self.get_output_paths()):
|
for locale, output_path in zip(self.get_locales(), self.get_output_paths()):
|
||||||
self.stdout.write("[frontend] processing locale {}".format(locale))
|
self.stdout.write("[frontend] processing locale {}".format(locale))
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Shows backlog count of ScheduledJobs of type Email
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
@@ -25,7 +26,6 @@ Usage: python manage.py print_email_delivery_backlog
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
print(len(ScheduledJob.objects.filter(type=ScheduledJob.EMAIL,
|
print(len(ScheduledJob.objects.filter(type=ScheduledJob.EMAIL,
|
||||||
scheduled_timestamp__lte=datetime.utcnow()-timedelta(minutes=1))))
|
scheduled_timestamp__lte=datetime.utcnow()-timedelta(minutes=1))))
|
||||||
return
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.core.management import CommandError
|
from django.core.management import CommandError
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@@ -11,6 +14,7 @@ import threading
|
|||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('--queue_name', metavar='<queue name>', type=str,
|
parser.add_argument('--queue_name', metavar='<queue name>', type=str,
|
||||||
help="queue to process")
|
help="queue to process")
|
||||||
parser.add_argument('--worker_num', metavar='<worker number>', type=int, nargs='?', default=0,
|
parser.add_argument('--worker_num', metavar='<worker number>', type=int, nargs='?', default=0,
|
||||||
@@ -20,6 +24,7 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
help = "Runs a queue processing worker"
|
help = "Runs a queue processing worker"
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
logging.basicConfig()
|
logging.basicConfig()
|
||||||
logger = logging.getLogger('process_queue')
|
logger = logging.getLogger('process_queue')
|
||||||
|
|
||||||
@@ -51,10 +56,12 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
class Threaded_worker(threading.Thread):
|
class Threaded_worker(threading.Thread):
|
||||||
def __init__(self, queue_name):
|
def __init__(self, queue_name):
|
||||||
|
# type: (str) -> None
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
self.worker = get_worker(queue_name)
|
self.worker = get_worker(queue_name)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
# type: () -> None
|
||||||
self.worker.setup()
|
self.worker.setup()
|
||||||
logging.debug('starting consuming ' + self.worker.queue_name)
|
logging.debug('starting consuming ' + self.worker.queue_name)
|
||||||
self.worker.start()
|
self.worker.start()
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.core.management import CommandError
|
from django.core.management import CommandError
|
||||||
from zerver.lib.queue import SimpleQueueClient
|
from zerver.lib.queue import SimpleQueueClient
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('queue_name', metavar='<queue name>', type=str,
|
parser.add_argument('queue_name', metavar='<queue name>', type=str,
|
||||||
help="queue to purge")
|
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):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
queue_name = options['queue_name']
|
queue_name = options['queue_name']
|
||||||
queue = SimpleQueueClient()
|
queue = SimpleQueueClient()
|
||||||
queue.ensure_queue(queue_name, lambda: None)
|
queue.ensure_queue(queue_name, lambda: None)
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from django.contrib.auth import authenticate, login, get_backends
|
from django.contrib.auth import authenticate, login, get_backends
|
||||||
@@ -12,6 +15,7 @@ from django_auth_ldap.backend import LDAPBackend, _LDAPUser
|
|||||||
|
|
||||||
# Quick tool to test whether you're correctly authenticating to LDAP
|
# Quick tool to test whether you're correctly authenticating to LDAP
|
||||||
def query_ldap(**options):
|
def query_ldap(**options):
|
||||||
|
# type: (**str) -> None
|
||||||
email = options['email']
|
email = options['email']
|
||||||
for backend in get_backends():
|
for backend in get_backends():
|
||||||
if isinstance(backend, LDAPBackend):
|
if isinstance(backend, LDAPBackend):
|
||||||
@@ -24,8 +28,10 @@ def query_ldap(**options):
|
|||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('email', metavar='<email>', type=str,
|
parser.add_argument('email', metavar='<email>', type=str,
|
||||||
help="email of user to query")
|
help="email of user to query")
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
query_ldap(**options)
|
query_ldap(**options)
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from zerver.models import UserProfile, get_user_profile_by_email
|
from zerver.models import UserProfile, get_user_profile_by_email
|
||||||
from zerver.lib.rate_limiter import block_user, unblock_user
|
from zerver.lib.rate_limiter import block_user, unblock_user
|
||||||
|
|
||||||
@@ -11,6 +14,7 @@ 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"""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('-e', '--email',
|
parser.add_argument('-e', '--email',
|
||||||
dest='email',
|
dest='email',
|
||||||
help="Email account of user.")
|
help="Email account of user.")
|
||||||
@@ -35,6 +39,7 @@ class Command(BaseCommand):
|
|||||||
help="operation to perform (block or unblock)")
|
help="operation to perform (block or unblock)")
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
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")
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
@@ -12,10 +15,12 @@ class Command(BaseCommand):
|
|||||||
help = """Script to reactivate a deactivated realm."""
|
help = """Script to reactivate a deactivated realm."""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('domain', metavar='<domain>', type=str,
|
parser.add_argument('domain', metavar='<domain>', type=str,
|
||||||
help='domain of realm to reactivate')
|
help='domain of realm to reactivate')
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
realm = get_realm(options["domain"])
|
realm = get_realm(options["domain"])
|
||||||
if realm is None:
|
if realm is None:
|
||||||
print("Could not find realm %s" % (options["domain"],))
|
print("Could not find realm %s" % (options["domain"],))
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
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
|
||||||
from zerver.lib.actions import realm_aliases
|
from zerver.lib.actions import realm_aliases
|
||||||
@@ -10,6 +13,7 @@ class Command(BaseCommand):
|
|||||||
help = """Manage aliases for the specified realm"""
|
help = """Manage aliases for the specified realm"""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('-r', '--realm',
|
parser.add_argument('-r', '--realm',
|
||||||
dest='domain',
|
dest='domain',
|
||||||
type=str,
|
type=str,
|
||||||
@@ -24,6 +28,7 @@ class Command(BaseCommand):
|
|||||||
help="alias to add or remove")
|
help="alias to add or remove")
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
realm = get_realm(options["domain"])
|
realm = get_realm(options["domain"])
|
||||||
if options["op"] == "show":
|
if options["op"] == "show":
|
||||||
print("Aliases for %s:" % (realm.domain,))
|
print("Aliases for %s:" % (realm.domain,))
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from zerver.models import Realm, get_realm
|
from zerver.models import Realm, get_realm
|
||||||
from zerver.lib.actions import check_add_realm_emoji, do_remove_realm_emoji
|
from zerver.lib.actions import check_add_realm_emoji, do_remove_realm_emoji
|
||||||
@@ -16,6 +19,7 @@ Example: python manage.py realm_emoji --realm=zulip.com --op=show
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('-r', '--realm',
|
parser.add_argument('-r', '--realm',
|
||||||
dest='domain',
|
dest='domain',
|
||||||
type=str,
|
type=str,
|
||||||
@@ -32,6 +36,7 @@ Example: python manage.py realm_emoji --realm=zulip.com --op=show
|
|||||||
help="URL of image to display for the emoji")
|
help="URL of image to display for the emoji")
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
realm = get_realm(options["domain"])
|
realm = get_realm(options["domain"])
|
||||||
if options["op"] == "show":
|
if options["op"] == "show":
|
||||||
for name, url in six.iteritems(realm.get_emoji()):
|
for name, url in six.iteritems(realm.get_emoji()):
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
@@ -22,6 +26,7 @@ Example: python manage.py realm_filters --realm=zulip.com --op=show
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('-r', '--realm',
|
parser.add_argument('-r', '--realm',
|
||||||
dest='domain',
|
dest='domain',
|
||||||
type=str,
|
type=str,
|
||||||
@@ -38,6 +43,7 @@ Example: python manage.py realm_filters --realm=zulip.com --op=show
|
|||||||
help="format string to substitute")
|
help="format string to substitute")
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
realm = get_realm(options["domain"])
|
realm = get_realm(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, [])))
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
@@ -33,6 +36,7 @@ class Command(BaseCommand):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def handle(self, **options):
|
def handle(self, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
if options["domain"] is None or options["stream"] is None or \
|
if options["domain"] is None or options["stream"] is None or \
|
||||||
(options["users"] is None and options["all_users"] is None):
|
(options["users"] is None and options["all_users"] is None):
|
||||||
self.print_help("python manage.py", "remove_users_from_stream")
|
self.print_help("python manage.py", "remove_users_from_stream")
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
from zerver.lib.actions import do_rename_stream
|
from zerver.lib.actions import do_rename_stream
|
||||||
@@ -12,6 +15,7 @@ class Command(BaseCommand):
|
|||||||
help = """Change the stream name for a realm."""
|
help = """Change the stream name for a realm."""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('domain', metavar='<domain>', type=str,
|
parser.add_argument('domain', metavar='<domain>', type=str,
|
||||||
help="domain to operate on")
|
help="domain to operate on")
|
||||||
parser.add_argument('old_name', metavar='<old name>', type=str,
|
parser.add_argument('old_name', metavar='<old name>', type=str,
|
||||||
@@ -20,6 +24,7 @@ class Command(BaseCommand):
|
|||||||
help='new name to rename the stream to')
|
help='new name to rename the stream to')
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
domain = options['domain']
|
domain = options['domain']
|
||||||
old_name = options['old_name']
|
old_name = options['old_name']
|
||||||
new_name = options['new_name']
|
new_name = options['new_name']
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
# Wrapper around Django's runserver to allow filtering logs.
|
# Wrapper around Django's runserver to allow filtering logs.
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.core.servers.basehttp import WSGIRequestHandler
|
from django.core.servers.basehttp import WSGIRequestHandler
|
||||||
orig_log_message = WSGIRequestHandler.log_message
|
orig_log_message = WSGIRequestHandler.log_message
|
||||||
def log_message_monkey(self, format, *args):
|
def log_message_monkey(self, format, *args):
|
||||||
|
# type: (Any, str, *Any) -> None
|
||||||
# Filter output for 200 or 304 responses.
|
# Filter output for 200 or 304 responses.
|
||||||
if args[1] == '200' or args[1] == '304':
|
if args[1] == '200' or args[1] == '304':
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
settings.RUNNING_INSIDE_TORNADO = True
|
settings.RUNNING_INSIDE_TORNADO = True
|
||||||
# We must call zerver.lib.tornado_ioloop_logging.instrument_tornado_ioloop
|
# We must call zerver.lib.tornado_ioloop_logging.instrument_tornado_ioloop
|
||||||
@@ -12,6 +14,7 @@ from zerver.lib.tornado_ioloop_logging import instrument_tornado_ioloop
|
|||||||
instrument_tornado_ioloop()
|
instrument_tornado_ioloop()
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
|
from django.http import HttpRequest, HttpResponse
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@@ -55,6 +58,7 @@ class Command(BaseCommand):
|
|||||||
args = '[optional port number or ipaddr:port]\n (use multiple ports to start multiple servers)'
|
args = '[optional port number or ipaddr:port]\n (use multiple ports to start multiple servers)'
|
||||||
|
|
||||||
def handle(self, addrport, **options):
|
def handle(self, addrport, **options):
|
||||||
|
# type: (str, **bool) -> None
|
||||||
# setup unbuffered I/O
|
# setup unbuffered I/O
|
||||||
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
|
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
|
||||||
sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', 0)
|
sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', 0)
|
||||||
@@ -83,6 +87,7 @@ class Command(BaseCommand):
|
|||||||
format='%(asctime)s %(levelname)-8s %(message)s')
|
format='%(asctime)s %(levelname)-8s %(message)s')
|
||||||
|
|
||||||
def inner_run():
|
def inner_run():
|
||||||
|
# type: () -> None
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
translation.activate(settings.LANGUAGE_CODE)
|
translation.activate(settings.LANGUAGE_CODE)
|
||||||
@@ -139,6 +144,7 @@ class AsyncDjangoHandler(tornado.web.RequestHandler, base.BaseHandler):
|
|||||||
initLock = Lock()
|
initLock = Lock()
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
super(AsyncDjangoHandler, self).__init__(*args, **kwargs)
|
super(AsyncDjangoHandler, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
# Set up middleware if needed. We couldn't do this earlier, because
|
# Set up middleware if needed. We couldn't do this earlier, because
|
||||||
@@ -155,9 +161,11 @@ class AsyncDjangoHandler(tornado.web.RequestHandler, base.BaseHandler):
|
|||||||
allocate_handler_id(self)
|
allocate_handler_id(self)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
# type: () -> str
|
||||||
return "AsyncDjangoHandler<%s, %s>" % (self.handler_id, get_descriptor_by_handler_id(self.handler_id))
|
return "AsyncDjangoHandler<%s, %s>" % (self.handler_id, get_descriptor_by_handler_id(self.handler_id))
|
||||||
|
|
||||||
def get(self, *args, **kwargs):
|
def get(self, *args, **kwargs):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
environ = WSGIContainer.environ(self.request)
|
environ = WSGIContainer.environ(self.request)
|
||||||
environ['PATH_INFO'] = urllib.parse.unquote(environ['PATH_INFO'])
|
environ['PATH_INFO'] = urllib.parse.unquote(environ['PATH_INFO'])
|
||||||
request = WSGIRequest(environ)
|
request = WSGIRequest(environ)
|
||||||
@@ -186,21 +194,26 @@ class AsyncDjangoHandler(tornado.web.RequestHandler, base.BaseHandler):
|
|||||||
|
|
||||||
|
|
||||||
def head(self, *args, **kwargs):
|
def head(self, *args, **kwargs):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
self.get(*args, **kwargs)
|
self.get(*args, **kwargs)
|
||||||
|
|
||||||
def post(self, *args, **kwargs):
|
def post(self, *args, **kwargs):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
self.get(*args, **kwargs)
|
self.get(*args, **kwargs)
|
||||||
|
|
||||||
def delete(self, *args, **kwargs):
|
def delete(self, *args, **kwargs):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
self.get(*args, **kwargs)
|
self.get(*args, **kwargs)
|
||||||
|
|
||||||
def on_connection_close(self):
|
def on_connection_close(self):
|
||||||
|
# type: () -> None
|
||||||
client_descriptor = get_descriptor_by_handler_id(self.handler_id)
|
client_descriptor = get_descriptor_by_handler_id(self.handler_id)
|
||||||
if client_descriptor is not None:
|
if client_descriptor is not None:
|
||||||
client_descriptor.disconnect_handler(client_closed=True)
|
client_descriptor.disconnect_handler(client_closed=True)
|
||||||
|
|
||||||
# Based on django.core.handlers.base: get_response
|
# Based on django.core.handlers.base: get_response
|
||||||
def get_response(self, request):
|
def get_response(self, request):
|
||||||
|
# type: (HttpRequest) -> HttpResponse
|
||||||
"Returns an HttpResponse object for the given HttpRequest"
|
"Returns an HttpResponse object for the given HttpRequest"
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
@@ -325,6 +338,7 @@ class AsyncDjangoHandler(tornado.web.RequestHandler, base.BaseHandler):
|
|||||||
|
|
||||||
### Copied from get_response (above in this file)
|
### Copied from get_response (above in this file)
|
||||||
def apply_response_middleware(self, request, response, resolver):
|
def apply_response_middleware(self, request, response, resolver):
|
||||||
|
# type: (HttpRequest, HttpResponse, urlresolvers.RegexURLResolver) -> HttpResponse
|
||||||
try:
|
try:
|
||||||
# Apply response middleware, regardless of the response
|
# Apply response middleware, regardless of the response
|
||||||
for middleware_method in self._response_middleware:
|
for middleware_method in self._response_middleware:
|
||||||
@@ -337,6 +351,7 @@ class AsyncDjangoHandler(tornado.web.RequestHandler, base.BaseHandler):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
def zulip_finish(self, response, request, apply_markdown):
|
def zulip_finish(self, response, request, apply_markdown):
|
||||||
|
# type: (HttpResponse, HttpRequest, bool) -> None
|
||||||
# Make sure that Markdown rendering really happened, if requested.
|
# Make sure that Markdown rendering really happened, if requested.
|
||||||
# This is a security issue because it's where we escape HTML.
|
# This is a security issue because it's where we escape HTML.
|
||||||
# c.f. ticket #64
|
# c.f. ticket #64
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
@@ -7,6 +10,7 @@ class Command(BaseCommand):
|
|||||||
help = """Send some stats to statsd."""
|
help = """Send some stats to statsd."""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('operation', metavar='<operation>', type=str,
|
parser.add_argument('operation', metavar='<operation>', type=str,
|
||||||
choices=['incr', 'decr', 'timing', 'timer', 'gauge'],
|
choices=['incr', 'decr', 'timing', 'timer', 'gauge'],
|
||||||
help="incr|decr|timing|timer|gauge")
|
help="incr|decr|timing|timer|gauge")
|
||||||
@@ -14,6 +18,7 @@ class Command(BaseCommand):
|
|||||||
parser.add_argument('val', metavar='<val>', type=str)
|
parser.add_argument('val', metavar='<val>', type=str)
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
operation = options['operation']
|
operation = options['operation']
|
||||||
name = options['name']
|
name = options['name']
|
||||||
val = options['val']
|
val = options['val']
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.mail import send_mail, BadHeaderError
|
from django.core.mail import send_mail, BadHeaderError
|
||||||
@@ -8,10 +11,12 @@ class Command(BaseCommand):
|
|||||||
help = """Send email to specified email address."""
|
help = """Send email to specified email address."""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('to', metavar='<to>', type=str,
|
parser.add_argument('to', metavar='<to>', type=str,
|
||||||
help="email of user to send the email")
|
help="email of user to send the email")
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
subject = "Zulip Test email"
|
subject = "Zulip Test email"
|
||||||
message = "Success! If you receive this message, you've successfully " + \
|
message = "Success! If you receive this message, you've successfully " + \
|
||||||
"configured sending email from your Zulip server."
|
"configured sending email from your Zulip server."
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import ujson
|
import ujson
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
@@ -32,6 +34,7 @@ Example:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def handle(self, **options):
|
def handle(self, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
if options['fixture'] is None or options['url'] is None:
|
if options['fixture'] is None or options['url'] is None:
|
||||||
self.print_help('python manage.py', 'send_webhook_fixture_message')
|
self.print_help('python manage.py', 'send_webhook_fixture_message')
|
||||||
exit(1)
|
exit(1)
|
||||||
@@ -47,7 +50,9 @@ Example:
|
|||||||
client.post(options['url'], json, content_type="application/json")
|
client.post(options['url'], json, content_type="application/json")
|
||||||
|
|
||||||
def _does_fixture_path_exist(self, fixture_path):
|
def _does_fixture_path_exist(self, fixture_path):
|
||||||
|
# type: (str) -> bool
|
||||||
return os.path.exists(fixture_path)
|
return os.path.exists(fixture_path)
|
||||||
|
|
||||||
def _get_fixture_as_json(self, fixture_path):
|
def _get_fixture_as_json(self, fixture_path):
|
||||||
|
# type: (str) -> str
|
||||||
return ujson.dumps(ujson.loads(open(fixture_path).read()))
|
return ujson.dumps(ujson.loads(open(fixture_path).read()))
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
from zerver.models import get_realm
|
from zerver.models import get_realm
|
||||||
@@ -36,6 +38,7 @@ python manage.py set_default_streams --domain=foo.com --streams=
|
|||||||
)
|
)
|
||||||
|
|
||||||
def handle(self, **options):
|
def handle(self, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
if options["domain"] is None or options["streams"] is None:
|
if options["domain"] is None or options["streams"] is None:
|
||||||
print("Please provide both a domain name and a default \
|
print("Please provide both a domain name and a default \
|
||||||
set of streams (which can be empty, with `--streams=`).", file=sys.stderr)
|
set of streams (which can be empty, with `--streams=`).", file=sys.stderr)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any, Iterable
|
||||||
|
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
@@ -41,6 +43,7 @@ class Command(BaseCommand):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
if not options["flag"] or not options["op"] or not options["email"]:
|
if not options["flag"] or not options["op"] or not options["email"]:
|
||||||
print("Please specify an operation, a flag and an email")
|
print("Please specify an operation, a flag and an email")
|
||||||
exit(1)
|
exit(1)
|
||||||
@@ -65,6 +68,7 @@ class Command(BaseCommand):
|
|||||||
sys.stderr.close()
|
sys.stderr.close()
|
||||||
|
|
||||||
def do_update(batch):
|
def do_update(batch):
|
||||||
|
# type: (Iterable[int]) -> None
|
||||||
msgs = UserMessage.objects.filter(id__in=batch)
|
msgs = UserMessage.objects.filter(id__in=batch)
|
||||||
if op == 'add':
|
if op == 'add':
|
||||||
msgs.update(flags=models.F('flags').bitor(flag))
|
msgs.update(flags=models.F('flags').bitor(flag))
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from zerver.models import get_realm, Realm
|
from zerver.models import get_realm, Realm
|
||||||
import sys
|
import sys
|
||||||
@@ -9,16 +12,18 @@ class Command(BaseCommand):
|
|||||||
help = """Show the admins in a realm."""
|
help = """Show the admins in a realm."""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('realm', metavar='<realm>', type=str,
|
parser.add_argument('realm', metavar='<realm>', type=str,
|
||||||
help="realm to show admins for")
|
help="realm to show admins for")
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
realm = options['realm']
|
# type: (*Any, **str) -> None
|
||||||
|
realm_name = options['realm']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
realm = get_realm(realm)
|
realm = get_realm(realm_name)
|
||||||
except Realm.DoesNotExist:
|
except Realm.DoesNotExist:
|
||||||
print('There is no realm called %s.' % (realm,))
|
print('There is no realm called %s.' % (realm_name,))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
users = realm.get_admin_users()
|
users = realm.get_admin_users()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.db.utils import IntegrityError
|
from django.db.utils import IntegrityError
|
||||||
@@ -24,6 +25,7 @@ logger.addHandler(file_handler)
|
|||||||
|
|
||||||
# Run this on a cronjob to pick up on name changes.
|
# Run this on a cronjob to pick up on name changes.
|
||||||
def sync_ldap_user_data():
|
def sync_ldap_user_data():
|
||||||
|
# type: () -> None
|
||||||
logger.info("Starting update.")
|
logger.info("Starting update.")
|
||||||
backend = ZulipLDAPUserPopulator()
|
backend = ZulipLDAPUserPopulator()
|
||||||
for u in UserProfile.objects.select_related().filter(is_active=True, is_bot=False).all():
|
for u in UserProfile.objects.select_related().filter(is_active=True, is_bot=False).all():
|
||||||
@@ -40,4 +42,5 @@ def sync_ldap_user_data():
|
|||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
sync_ldap_user_data()
|
sync_ldap_user_data()
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
@@ -23,6 +25,7 @@ class Command(BaseCommand):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def handle(self, **options):
|
def handle(self, **options):
|
||||||
|
# type: (**str) -> None
|
||||||
if options["domain"] is None and options["users"] is None:
|
if options["domain"] is None and options["users"] is None:
|
||||||
self.print_help("python manage.py", "turn_off_digests")
|
self.print_help("python manage.py", "turn_off_digests")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.db.models import get_app, get_models
|
from django.db.models import get_app, get_models
|
||||||
from django.contrib.auth.management import create_permissions
|
from django.contrib.auth.management import create_permissions
|
||||||
@@ -8,5 +10,6 @@ class Command(BaseCommand):
|
|||||||
help = "Sync newly created object permissions to the database"
|
help = "Sync newly created object permissions to the database"
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
# From http://stackoverflow.com/a/11914435/90777
|
# From http://stackoverflow.com/a/11914435/90777
|
||||||
create_permissions(get_app("zerver"), get_models(), 2)
|
create_permissions(get_app("zerver"), get_models(), 2)
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
import sys
|
import sys
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
@@ -31,6 +33,7 @@ class Command(BaseCommand):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
if None in (options["api"], options["web"], options["domain"]):
|
if None in (options["api"], options["web"], options["domain"]):
|
||||||
print("\033[1;31mYou must provide a domain, an API URL, and a web URL.\033[0m\n", file=sys.stderr)
|
print("\033[1;31mYou must provide a domain, an API URL, and a web URL.\033[0m\n", file=sys.stderr)
|
||||||
self.print_help("python manage.py", "create_realm")
|
self.print_help("python manage.py", "create_realm")
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
from zerver.lib.actions import send_referral_event
|
from zerver.lib.actions import send_referral_event
|
||||||
@@ -9,12 +12,14 @@ 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."""
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('email', metavar='<email>', type=str,
|
parser.add_argument('email', metavar='<email>', type=str,
|
||||||
help="user to grant invites to")
|
help="user to grant invites to")
|
||||||
parser.add_argument('num_invites', metavar='<num invites>', type=int,
|
parser.add_argument('num_invites', metavar='<num invites>', type=int,
|
||||||
help="number of invites to grant")
|
help="number of invites to grant")
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
email = options['email']
|
email = options['email']
|
||||||
num_invites = options['num_invites']
|
num_invites = options['num_invites']
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from zerver.models import Subscription
|
from zerver.models import Subscription
|
||||||
|
|
||||||
@@ -7,6 +9,7 @@ class Command(BaseCommand):
|
|||||||
help = """One-off script to migration users' stream notification settings."""
|
help = """One-off script to migration users' stream notification settings."""
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
for subscription in Subscription.objects.all():
|
for subscription in Subscription.objects.all():
|
||||||
subscription.desktop_notifications = subscription.notifications
|
subscription.desktop_notifications = subscription.notifications
|
||||||
subscription.audible_notifications = subscription.notifications
|
subscription.audible_notifications = subscription.notifications
|
||||||
|
|||||||
@@ -31,11 +31,12 @@ import glob
|
|||||||
import os
|
import os
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
from six.moves import range
|
from six.moves import range
|
||||||
from typing import Any, Dict, Set, Tuple
|
from typing import Any, Dict, List, IO, Iterable, Mapping, Set, Tuple
|
||||||
|
|
||||||
settings.TORNADO_SERVER = None
|
settings.TORNADO_SERVER = None
|
||||||
|
|
||||||
def create_users(realms, name_list, bot_type=None):
|
def create_users(realms, name_list, bot_type=None):
|
||||||
|
# type: (Mapping[str, Realm], Iterable[Tuple[str, str]], int) -> None
|
||||||
user_set = set()
|
user_set = set()
|
||||||
for full_name, email in name_list:
|
for full_name, email in name_list:
|
||||||
short_name = email_to_username(email)
|
short_name = email_to_username(email)
|
||||||
@@ -43,6 +44,7 @@ def create_users(realms, name_list, bot_type=None):
|
|||||||
bulk_create_users(realms, user_set, bot_type)
|
bulk_create_users(realms, user_set, bot_type)
|
||||||
|
|
||||||
def create_streams(realms, realm, stream_list):
|
def create_streams(realms, realm, stream_list):
|
||||||
|
# type: (Mapping[str, Realm], Realm, Iterable[str]) -> None
|
||||||
stream_set = set()
|
stream_set = set()
|
||||||
for stream_name in stream_list:
|
for stream_name in stream_list:
|
||||||
stream_set.add((realm.domain, stream_name))
|
stream_set.add((realm.domain, stream_name))
|
||||||
@@ -109,6 +111,7 @@ class Command(BaseCommand):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def handle(self, **options):
|
def handle(self, **options):
|
||||||
|
# type: (**Any) -> None
|
||||||
if options["percent_huddles"] + options["percent_personals"] > 100:
|
if options["percent_huddles"] + options["percent_personals"] > 100:
|
||||||
self.stderr.write("Error! More than 100% of messages allocated.\n")
|
self.stderr.write("Error! More than 100% of messages allocated.\n")
|
||||||
return
|
return
|
||||||
@@ -257,11 +260,13 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
recipient_hash = {} # type: Dict[int, Recipient]
|
recipient_hash = {} # type: Dict[int, Recipient]
|
||||||
def get_recipient_by_id(rid):
|
def get_recipient_by_id(rid):
|
||||||
|
# type: (int) -> Recipient
|
||||||
if rid in recipient_hash:
|
if rid in recipient_hash:
|
||||||
return recipient_hash[rid]
|
return recipient_hash[rid]
|
||||||
return Recipient.objects.get(id=rid)
|
return Recipient.objects.get(id=rid)
|
||||||
|
|
||||||
def restore_saved_messages():
|
def restore_saved_messages():
|
||||||
|
# type: () -> None
|
||||||
old_messages = []
|
old_messages = []
|
||||||
duplicate_suppression_hash = {} # type: Dict[str, bool]
|
duplicate_suppression_hash = {} # type: Dict[str, bool]
|
||||||
|
|
||||||
@@ -276,6 +281,7 @@ def restore_saved_messages():
|
|||||||
# First, determine all the objects our messages will need.
|
# First, determine all the objects our messages will need.
|
||||||
print(datetime.datetime.now(), "Creating realms/streams/etc...")
|
print(datetime.datetime.now(), "Creating realms/streams/etc...")
|
||||||
def process_line(line):
|
def process_line(line):
|
||||||
|
# type: (str) -> None
|
||||||
old_message_json = line.strip()
|
old_message_json = line.strip()
|
||||||
|
|
||||||
# Due to populate_db's shakespeare mode, we have a lot of
|
# Due to populate_db's shakespeare mode, we have a lot of
|
||||||
@@ -302,6 +308,7 @@ def restore_saved_messages():
|
|||||||
# Lower case emails and domains; it will screw up
|
# Lower case emails and domains; it will screw up
|
||||||
# deduplication if we don't
|
# deduplication if we don't
|
||||||
def fix_email(email):
|
def fix_email(email):
|
||||||
|
# type: (str) -> str
|
||||||
return email.strip().lower()
|
return email.strip().lower()
|
||||||
|
|
||||||
if message_type in ["stream", "huddle", "personal"]:
|
if message_type in ["stream", "huddle", "personal"]:
|
||||||
@@ -708,6 +715,7 @@ def restore_saved_messages():
|
|||||||
# - multiple messages per subject
|
# - multiple messages per subject
|
||||||
# - both single and multi-line content
|
# - both single and multi-line content
|
||||||
def send_messages(data):
|
def send_messages(data):
|
||||||
|
# type: ignore # Should be (Tuple[int, List[UserProfile], Dict[str, Any], Any]) -> int
|
||||||
(tot_messages, personals_pairs, options, output) = data
|
(tot_messages, personals_pairs, options, output) = data
|
||||||
random.seed(os.getpid())
|
random.seed(os.getpid())
|
||||||
texts = open("zilencer/management/commands/test_messages.txt", "r").readlines()
|
texts = open("zilencer/management/commands/test_messages.txt", "r").readlines()
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from zerver.lib.initial_password import initial_password
|
from zerver.lib.initial_password import initial_password
|
||||||
from zerver.models import get_user_profile_by_email
|
from zerver.models import get_user_profile_by_email
|
||||||
@@ -11,10 +14,12 @@ class Command(BaseCommand):
|
|||||||
fmt = '%-30s %-16s %-32s'
|
fmt = '%-30s %-16s %-32s'
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
# type: (ArgumentParser) -> None
|
||||||
parser.add_argument('emails', metavar='<email>', type=str, nargs='*',
|
parser.add_argument('emails', metavar='<email>', type=str, nargs='*',
|
||||||
help="email of user to show password and API key for")
|
help="email of user to show password and API key for")
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **str) -> None
|
||||||
print(self.fmt % ('email', 'password', 'API key'))
|
print(self.fmt % ('email', 'password', 'API key'))
|
||||||
for email in options['emails']:
|
for email in options['emails']:
|
||||||
if '@' not in email:
|
if '@' not in email:
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
from django.http import HttpRequest, HttpResponse
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from zerver.models import get_user_profile_by_email, UserMessage
|
from zerver.models import get_user_profile_by_email, UserMessage
|
||||||
@@ -13,10 +14,12 @@ request_logger = LogRequests()
|
|||||||
|
|
||||||
class MockSession(object):
|
class MockSession(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
# type: () -> None
|
||||||
self.modified = False
|
self.modified = False
|
||||||
|
|
||||||
class MockRequest(object):
|
class MockRequest(HttpRequest):
|
||||||
def __init__(self, email):
|
def __init__(self, email):
|
||||||
|
# type: (str) -> None
|
||||||
self.user = get_user_profile_by_email(email)
|
self.user = get_user_profile_by_email(email)
|
||||||
self.path = '/'
|
self.path = '/'
|
||||||
self.method = "POST"
|
self.method = "POST"
|
||||||
@@ -28,9 +31,11 @@ class MockRequest(object):
|
|||||||
self.session = MockSession()
|
self.session = MockSession()
|
||||||
|
|
||||||
def get_full_path(self):
|
def get_full_path(self):
|
||||||
|
# type: () -> str
|
||||||
return self.path
|
return self.path
|
||||||
|
|
||||||
def profile_request(request):
|
def profile_request(request):
|
||||||
|
# type: (HttpRequest) -> HttpResponse
|
||||||
request_logger.process_request(request)
|
request_logger.process_request(request)
|
||||||
prof = cProfile.Profile()
|
prof = cProfile.Profile()
|
||||||
prof.enable()
|
prof.enable()
|
||||||
@@ -48,4 +53,5 @@ class Command(BaseCommand):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
profile_request(MockRequest(options["email"]))
|
profile_request(MockRequest(options["email"]))
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
from zerver.models import Message
|
from zerver.models import Message
|
||||||
@@ -13,6 +15,7 @@ class Command(BaseCommand):
|
|||||||
Usage: python manage.py render_old_messages"""
|
Usage: python manage.py render_old_messages"""
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
total_rendered = 0
|
total_rendered = 0
|
||||||
while True:
|
while True:
|
||||||
messages = Message.objects.filter(rendered_content_version=None)[0:100]
|
messages = Message.objects.filter(rendered_content_version=None)[0:100]
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from zerver.models import get_user_profile_by_email, UserProfile
|
from zerver.models import get_user_profile_by_email, UserProfile
|
||||||
import os
|
import os
|
||||||
@@ -10,6 +12,7 @@ class Command(BaseCommand):
|
|||||||
help = """Sync your API key from ~/.zuliprc into your development instance"""
|
help = """Sync your API key from ~/.zuliprc into your development instance"""
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
config_file = os.path.join(os.environ["HOME"], ".zuliprc")
|
config_file = os.path.join(os.environ["HOME"], ".zuliprc")
|
||||||
if not os.path.exists(config_file):
|
if not os.path.exists(config_file):
|
||||||
raise RuntimeError("No ~/.zuliprc found")
|
raise RuntimeError("No ~/.zuliprc found")
|
||||||
|
|||||||
Reference in New Issue
Block a user