mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	zerver/lib: Remove u prefix from strings.
License: Apache-2.0 Signed-off-by: rht <rhtbot@protonmail.com>
This commit is contained in:
		@@ -151,7 +151,7 @@ def log_event(event):
 | 
			
		||||
 | 
			
		||||
    with lockfile(template % ('lock',)):
 | 
			
		||||
        with open(template % ('events',), 'a') as log:
 | 
			
		||||
            log.write(force_str(ujson.dumps(event) + u'\n'))
 | 
			
		||||
            log.write(force_str(ujson.dumps(event) + '\n'))
 | 
			
		||||
 | 
			
		||||
def can_access_stream_user_ids(stream):
 | 
			
		||||
    # type: (Stream) -> Set[int]
 | 
			
		||||
@@ -3732,7 +3732,7 @@ def user_email_is_unique(email):
 | 
			
		||||
    # type: (Text) -> None
 | 
			
		||||
    try:
 | 
			
		||||
        get_user_profile_by_email(email)
 | 
			
		||||
        raise ValidationError(u'%s already has an account' % (email,))
 | 
			
		||||
        raise ValidationError('%s already has an account' % (email,))
 | 
			
		||||
    except UserProfile.DoesNotExist:
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
@@ -3746,10 +3746,10 @@ def validate_email_for_realm(target_realm, email):
 | 
			
		||||
    if existing_user_profile is not None and existing_user_profile.is_mirror_dummy:
 | 
			
		||||
        # Mirror dummy users to be activated must be inactive
 | 
			
		||||
        if existing_user_profile.is_active:
 | 
			
		||||
            raise ValidationError(u'%s already has an account' % (email,))
 | 
			
		||||
            raise ValidationError('%s already has an account' % (email,))
 | 
			
		||||
    elif existing_user_profile:
 | 
			
		||||
        # Other users should not already exist at all.
 | 
			
		||||
        raise ValidationError(u'%s already has an account' % (email,))
 | 
			
		||||
        raise ValidationError('%s already has an account' % (email,))
 | 
			
		||||
 | 
			
		||||
def validate_email(user_profile, email):
 | 
			
		||||
    # type: (UserProfile, Text) -> Tuple[Optional[str], Optional[str]]
 | 
			
		||||
 
 | 
			
		||||
@@ -102,12 +102,12 @@ def _get_unversioned_gravatar_url(email, medium):
 | 
			
		||||
    if settings.ENABLE_GRAVATAR:
 | 
			
		||||
        gravitar_query_suffix = "&s=%s" % (MEDIUM_AVATAR_SIZE,) if medium else ""
 | 
			
		||||
        hash_key = gravatar_hash(email)
 | 
			
		||||
        return u"https://secure.gravatar.com/avatar/%s?d=identicon%s" % (hash_key, gravitar_query_suffix)
 | 
			
		||||
        return "https://secure.gravatar.com/avatar/%s?d=identicon%s" % (hash_key, gravitar_query_suffix)
 | 
			
		||||
    return settings.DEFAULT_AVATAR_URI+'?x=x'
 | 
			
		||||
 | 
			
		||||
def _get_unversioned_avatar_url(user_profile_id, avatar_source, realm_id, email=None, medium=False):
 | 
			
		||||
    # type: (int, Text, int, Optional[Text], bool) -> Text
 | 
			
		||||
    if avatar_source == u'U':
 | 
			
		||||
    if avatar_source == 'U':
 | 
			
		||||
        hash_key = user_avatar_path_from_ids(user_profile_id, realm_id)
 | 
			
		||||
        return upload_backend.get_avatar_url(hash_key, medium=medium)
 | 
			
		||||
    assert email is not None
 | 
			
		||||
 
 | 
			
		||||
@@ -119,7 +119,7 @@ def image_preview_enabled_for_realm():
 | 
			
		||||
def list_of_tlds():
 | 
			
		||||
    # type: () -> List[Text]
 | 
			
		||||
    # HACK we manually blacklist a few domains
 | 
			
		||||
    blacklist = [u'PY\n', u"MD\n"]
 | 
			
		||||
    blacklist = ['PY\n', "MD\n"]
 | 
			
		||||
 | 
			
		||||
    # tlds-alpha-by-domain.txt comes from http://data.iana.org/TLD/tlds-alpha-by-domain.txt
 | 
			
		||||
    tlds_file = os.path.join(os.path.dirname(__file__), 'tlds-alpha-by-domain.txt')
 | 
			
		||||
@@ -269,10 +269,10 @@ def fetch_tweet_data(tweet_id):
 | 
			
		||||
                return None
 | 
			
		||||
    return res
 | 
			
		||||
 | 
			
		||||
HEAD_START_RE = re.compile(u'^head[ >]')
 | 
			
		||||
HEAD_END_RE = re.compile(u'^/head[ >]')
 | 
			
		||||
META_START_RE = re.compile(u'^meta[ >]')
 | 
			
		||||
META_END_RE = re.compile(u'^/meta[ >]')
 | 
			
		||||
HEAD_START_RE = re.compile('^head[ >]')
 | 
			
		||||
HEAD_END_RE = re.compile('^/head[ >]')
 | 
			
		||||
META_START_RE = re.compile('^meta[ >]')
 | 
			
		||||
META_END_RE = re.compile('^/meta[ >]')
 | 
			
		||||
 | 
			
		||||
def fetch_open_graph_image(url):
 | 
			
		||||
    # type: (Text) -> Optional[Dict[str, Any]]
 | 
			
		||||
@@ -510,13 +510,13 @@ class InlineInterestingLinkProcessor(markdown.treeprocessors.Treeprocessor):
 | 
			
		||||
        # Build dicts for mentions
 | 
			
		||||
        for user_mention in user_mentions:
 | 
			
		||||
            screen_name = user_mention['screen_name']
 | 
			
		||||
            mention_string = u'@' + screen_name
 | 
			
		||||
            mention_string = '@' + screen_name
 | 
			
		||||
            for match in re.finditer(re.escape(mention_string), text, re.IGNORECASE):
 | 
			
		||||
                to_process.append({
 | 
			
		||||
                    'type': 'mention',
 | 
			
		||||
                    'start': match.start(),
 | 
			
		||||
                    'end': match.end(),
 | 
			
		||||
                    'url': u'https://twitter.com/' + force_text(urllib.parse.quote(force_str(screen_name))),
 | 
			
		||||
                    'url': 'https://twitter.com/' + force_text(urllib.parse.quote(force_str(screen_name))),
 | 
			
		||||
                    'text': mention_string,
 | 
			
		||||
                })
 | 
			
		||||
        # Build dicts for media
 | 
			
		||||
@@ -612,7 +612,7 @@ class InlineInterestingLinkProcessor(markdown.treeprocessors.Treeprocessor):
 | 
			
		||||
            tweet.append(p)
 | 
			
		||||
 | 
			
		||||
            span = markdown.util.etree.SubElement(tweet, 'span')
 | 
			
		||||
            span.text = u"- %s (@%s)" % (user['name'], user['screen_name'])
 | 
			
		||||
            span.text = "- %s (@%s)" % (user['name'], user['screen_name'])
 | 
			
		||||
 | 
			
		||||
            # Add image previews
 | 
			
		||||
            for media_item in media:
 | 
			
		||||
@@ -629,7 +629,7 @@ class InlineInterestingLinkProcessor(markdown.treeprocessors.Treeprocessor):
 | 
			
		||||
                    if size['h'] < self.TWITTER_MAX_IMAGE_HEIGHT:
 | 
			
		||||
                        break
 | 
			
		||||
 | 
			
		||||
                media_url = u'%s:%s' % (media_item['media_url_https'], size_name)
 | 
			
		||||
                media_url = '%s:%s' % (media_item['media_url_https'], size_name)
 | 
			
		||||
                img_div = markdown.util.etree.SubElement(tweet, 'div')
 | 
			
		||||
                img_div.set('class', 'twitter-image')
 | 
			
		||||
                img_a = markdown.util.etree.SubElement(img_div, 'a')
 | 
			
		||||
@@ -777,17 +777,17 @@ with open(path_to_codepoint_to_name) as codepoint_to_name_file:
 | 
			
		||||
# \u2b00-\u2bff         - Miscellaneous Symbols and Arrows
 | 
			
		||||
# \u3000-\u303f         - CJK Symbols and Punctuation
 | 
			
		||||
# \u3200-\u32ff         - Enclosed CJK Letters and Months
 | 
			
		||||
unicode_emoji_regex = u'(?P<syntax>['\
 | 
			
		||||
    u'\U0001F100-\U0001F64F'    \
 | 
			
		||||
    u'\U0001F680-\U0001F6FF'    \
 | 
			
		||||
    u'\U0001F900-\U0001F9FF'    \
 | 
			
		||||
    u'\u2000-\u206F'            \
 | 
			
		||||
    u'\u2300-\u27BF'            \
 | 
			
		||||
    u'\u2900-\u297F'            \
 | 
			
		||||
    u'\u2B00-\u2BFF'            \
 | 
			
		||||
    u'\u3000-\u303F'            \
 | 
			
		||||
    u'\u3200-\u32FF'            \
 | 
			
		||||
    u'])'
 | 
			
		||||
unicode_emoji_regex = '(?P<syntax>['\
 | 
			
		||||
    '\U0001F100-\U0001F64F'    \
 | 
			
		||||
    '\U0001F680-\U0001F6FF'    \
 | 
			
		||||
    '\U0001F900-\U0001F9FF'    \
 | 
			
		||||
    '\u2000-\u206F'            \
 | 
			
		||||
    '\u2300-\u27BF'            \
 | 
			
		||||
    '\u2900-\u297F'            \
 | 
			
		||||
    '\u2B00-\u2BFF'            \
 | 
			
		||||
    '\u3000-\u303F'            \
 | 
			
		||||
    '\u3200-\u32FF'            \
 | 
			
		||||
    '])'
 | 
			
		||||
# The equivalent JS regex is \ud83c[\udd00-\udfff]|\ud83d[\udc00-\ude4f]|\ud83d[\ude80-\udeff]|
 | 
			
		||||
# \ud83e[\udd00-\uddff]|[\u2000-\u206f]|[\u2300-\u27bf]|[\u2b00-\u2bff]|[\u3000-\u303f]|
 | 
			
		||||
# [\u3200-\u32ff]. See below comments for explanation. The JS regex is used by marked.js for
 | 
			
		||||
@@ -913,7 +913,7 @@ class Tex(markdown.inlinepatterns.Pattern):
 | 
			
		||||
            span.text = '$$' + match.group('body') + '$$'
 | 
			
		||||
            return span
 | 
			
		||||
 | 
			
		||||
upload_title_re = re.compile(u"^(https?://[^/]*)?(/user_uploads/\\d+)(/[^/]*)?/[^/]*/(?P<filename>[^/]*)$")
 | 
			
		||||
upload_title_re = re.compile("^(https?://[^/]*)?(/user_uploads/\\d+)(/[^/]*)?/[^/]*/(?P<filename>[^/]*)$")
 | 
			
		||||
def url_filename(url):
 | 
			
		||||
    # type: (Text) -> Text
 | 
			
		||||
    """Extract the filename if a URL is an uploaded file, or return the original URL"""
 | 
			
		||||
@@ -1011,7 +1011,7 @@ class VerbosePattern(markdown.inlinepatterns.Pattern):
 | 
			
		||||
        # Now replace with the real regex compiled with the flags we want.
 | 
			
		||||
 | 
			
		||||
        self.pattern = pattern
 | 
			
		||||
        self.compiled_re = re.compile(u"^(.*?)%s(.*?)$" % pattern,
 | 
			
		||||
        self.compiled_re = re.compile("^(.*?)%s(.*?)$" % pattern,
 | 
			
		||||
                                      re.DOTALL | re.UNICODE | re.VERBOSE)
 | 
			
		||||
 | 
			
		||||
class AutoLink(VerbosePattern):
 | 
			
		||||
@@ -1027,7 +1027,7 @@ class UListProcessor(markdown.blockprocessors.UListProcessor):
 | 
			
		||||
        '+' or '-' as a bullet character."""
 | 
			
		||||
 | 
			
		||||
    TAG = 'ul'
 | 
			
		||||
    RE = re.compile(u'^[ ]{0,3}[*][ ]+(.*)')
 | 
			
		||||
    RE = re.compile('^[ ]{0,3}[*][ ]+(.*)')
 | 
			
		||||
 | 
			
		||||
    def __init__(self, parser):
 | 
			
		||||
        # type: (Any) -> None
 | 
			
		||||
@@ -1063,8 +1063,8 @@ class BugdownUListPreprocessor(markdown.preprocessors.Preprocessor):
 | 
			
		||||
        directly after a line of text, and inserts a newline between
 | 
			
		||||
        to satisfy Markdown"""
 | 
			
		||||
 | 
			
		||||
    LI_RE = re.compile(u'^[ ]{0,3}[*][ ]+(.*)', re.MULTILINE)
 | 
			
		||||
    HANGING_ULIST_RE = re.compile(u'^.+\\n([ ]{0,3}[*][ ]+.*)', re.MULTILINE)
 | 
			
		||||
    LI_RE = re.compile('^[ ]{0,3}[*][ ]+(.*)', re.MULTILINE)
 | 
			
		||||
    HANGING_ULIST_RE = re.compile('^.+\\n([ ]{0,3}[*][ ]+.*)', re.MULTILINE)
 | 
			
		||||
 | 
			
		||||
    def run(self, lines):
 | 
			
		||||
        # type: (List[Text]) -> List[Text]
 | 
			
		||||
@@ -1221,7 +1221,7 @@ class StreamPattern(VerbosePattern):
 | 
			
		||||
            # provide more clarity to API clients.
 | 
			
		||||
            el.set('href', '/#narrow/stream/{stream_name}'.format(
 | 
			
		||||
                stream_name=urllib.parse.quote(force_str(name))))
 | 
			
		||||
            el.text = u'#{stream_name}'.format(stream_name=name)
 | 
			
		||||
            el.text = '#{stream_name}'.format(stream_name=name)
 | 
			
		||||
            return el
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
@@ -1250,7 +1250,7 @@ class AlertWordsNotificationProcessor(markdown.preprocessors.Preprocessor):
 | 
			
		||||
 | 
			
		||||
            for word in realm_words:
 | 
			
		||||
                escaped = re.escape(word.lower())
 | 
			
		||||
                match_re = re.compile(u'(?:%s)%s(?:%s)' %
 | 
			
		||||
                match_re = re.compile('(?:%s)%s(?:%s)' %
 | 
			
		||||
                                      (allowed_before_punctuation,
 | 
			
		||||
                                       escaped,
 | 
			
		||||
                                       allowed_after_punctuation))
 | 
			
		||||
@@ -1502,7 +1502,7 @@ def maybe_update_realm_filters(realm_filters_key):
 | 
			
		||||
#
 | 
			
		||||
# We also use repr() to improve reproducibility, and to escape terminal control
 | 
			
		||||
# codes, which can do surprisingly nasty things.
 | 
			
		||||
_privacy_re = re.compile(u'\\w', flags=re.UNICODE)
 | 
			
		||||
_privacy_re = re.compile('\\w', flags=re.UNICODE)
 | 
			
		||||
def privacy_clean_markdown(content):
 | 
			
		||||
    # type: (Text) -> Text
 | 
			
		||||
    return repr(_privacy_re.sub('x', content))
 | 
			
		||||
 
 | 
			
		||||
@@ -106,8 +106,8 @@ FENCE_RE = re.compile(u"""
 | 
			
		||||
    """, re.VERBOSE)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CODE_WRAP = u'<pre><code%s>%s\n</code></pre>'
 | 
			
		||||
LANG_TAG = u' class="%s"'
 | 
			
		||||
CODE_WRAP = '<pre><code%s>%s\n</code></pre>'
 | 
			
		||||
LANG_TAG = ' class="%s"'
 | 
			
		||||
 | 
			
		||||
class FencedCodeExtension(markdown.Extension):
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ from zerver.models import Realm, Stream, UserProfile, Huddle, \
 | 
			
		||||
    Subscription, Recipient, Client, RealmAuditLog, get_huddle_hash
 | 
			
		||||
from zerver.lib.create_user import create_user_profile
 | 
			
		||||
 | 
			
		||||
def bulk_create_users(realm, users_raw, bot_type=None, bot_owner=None, tos_version=None, timezone=u""):
 | 
			
		||||
def bulk_create_users(realm, users_raw, bot_type=None, bot_owner=None, tos_version=None, timezone=""):
 | 
			
		||||
    # type: (Realm, Set[Tuple[Text, Text, Text, bool]], Optional[int], Optional[UserProfile], Optional[Text], Text) -> None
 | 
			
		||||
    """
 | 
			
		||||
    Creates and saves a UserProfile with the given email.
 | 
			
		||||
 
 | 
			
		||||
@@ -61,12 +61,12 @@ def get_or_create_key_prefix():
 | 
			
		||||
        #
 | 
			
		||||
        # Having a fixed key is OK since we don't support running
 | 
			
		||||
        # multiple copies of the casper tests at the same time anyway.
 | 
			
		||||
        return u'casper_tests:'
 | 
			
		||||
        return 'casper_tests:'
 | 
			
		||||
    elif settings.TEST_SUITE:
 | 
			
		||||
        # The Python tests overwrite KEY_PREFIX on each test, but use
 | 
			
		||||
        # this codepath as well, just to save running the more complex
 | 
			
		||||
        # code below for reading the normal key prefix.
 | 
			
		||||
        return u'django_tests_unused:'
 | 
			
		||||
        return 'django_tests_unused:'
 | 
			
		||||
 | 
			
		||||
    # directory `var` should exist in production
 | 
			
		||||
    subprocess.check_call(["mkdir", "-p", os.path.join(settings.DEPLOY_ROOT, "var")])
 | 
			
		||||
@@ -102,7 +102,7 @@ KEY_PREFIX = get_or_create_key_prefix()  # type: Text
 | 
			
		||||
def bounce_key_prefix_for_testing(test_name):
 | 
			
		||||
    # type: (Text) -> None
 | 
			
		||||
    global KEY_PREFIX
 | 
			
		||||
    KEY_PREFIX = test_name + u':' + Text(os.getpid()) + u':'
 | 
			
		||||
    KEY_PREFIX = test_name + ':' + Text(os.getpid()) + ':'
 | 
			
		||||
    # We are taking the hash of the KEY_PREFIX to decrease the size of the key.
 | 
			
		||||
    # Memcached keys should have a length of less than 256.
 | 
			
		||||
    KEY_PREFIX = hashlib.sha1(KEY_PREFIX.encode('utf-8')).hexdigest()
 | 
			
		||||
@@ -316,7 +316,7 @@ def user_profile_by_email_cache_key(email):
 | 
			
		||||
    # See the comment in zerver/lib/avatar_hash.py:gravatar_hash for why we
 | 
			
		||||
    # are proactively encoding email addresses even though they will
 | 
			
		||||
    # with high likelihood be ASCII-only for the foreseeable future.
 | 
			
		||||
    return u'user_profile_by_email:%s' % (make_safe_digest(email.strip()),)
 | 
			
		||||
    return 'user_profile_by_email:%s' % (make_safe_digest(email.strip()),)
 | 
			
		||||
 | 
			
		||||
def user_profile_cache_key(email, realm):
 | 
			
		||||
    # type: (Text, Realm) -> Text
 | 
			
		||||
@@ -464,7 +464,7 @@ def flush_stream(sender, **kwargs):
 | 
			
		||||
 | 
			
		||||
def to_dict_cache_key_id(message_id):
 | 
			
		||||
    # type: (int) -> Text
 | 
			
		||||
    return u'message_dict:%d' % (message_id,)
 | 
			
		||||
    return 'message_dict:%d' % (message_id,)
 | 
			
		||||
 | 
			
		||||
def to_dict_cache_key(message):
 | 
			
		||||
    # type: (Message) -> Text
 | 
			
		||||
 
 | 
			
		||||
@@ -51,7 +51,7 @@ def create_user_profile(realm, email, password, active, bot_type, full_name,
 | 
			
		||||
 | 
			
		||||
def create_user(email, password, realm, full_name, short_name,
 | 
			
		||||
                active=True, is_realm_admin=False, bot_type=None, bot_owner=None, tos_version=None,
 | 
			
		||||
                timezone=u"", avatar_source=UserProfile.AVATAR_FROM_GRAVATAR,
 | 
			
		||||
                timezone="", avatar_source=UserProfile.AVATAR_FROM_GRAVATAR,
 | 
			
		||||
                is_mirror_dummy=False, default_sending_stream=None,
 | 
			
		||||
                default_events_register_stream=None,
 | 
			
		||||
                default_all_public_streams=None, user_profile_id=None):
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ logger = logging.getLogger(__name__)
 | 
			
		||||
def redact_stream(error_message):
 | 
			
		||||
    # type: (Text) -> Text
 | 
			
		||||
    domain = settings.EMAIL_GATEWAY_PATTERN.rsplit('@')[-1]
 | 
			
		||||
    stream_match = re.search(u'\\b(.*?)@' + domain, error_message)
 | 
			
		||||
    stream_match = re.search('\\b(.*?)@' + domain, error_message)
 | 
			
		||||
    if stream_match:
 | 
			
		||||
        stream_name = stream_match.groups()[0]
 | 
			
		||||
        return error_message.replace(stream_name, "X" * len(stream_name))
 | 
			
		||||
@@ -129,7 +129,7 @@ def create_missed_message_address(user_profile, message):
 | 
			
		||||
        pipeline.expire(key, 60 * 60 * 24 * 5)
 | 
			
		||||
        pipeline.execute()
 | 
			
		||||
 | 
			
		||||
    address = u'mm' + token
 | 
			
		||||
    address = 'mm' + token
 | 
			
		||||
    return settings.EMAIL_GATEWAY_PATTERN % (address,)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -173,7 +173,7 @@ def send_to_missed_message_address(address, message):
 | 
			
		||||
    # Testing with basestring so we don't depend on the list return type from
 | 
			
		||||
    # get_display_recipient
 | 
			
		||||
    if not isinstance(display_recipient, str):
 | 
			
		||||
        recipient_str = u','.join([user['email'] for user in display_recipient])
 | 
			
		||||
        recipient_str = ','.join([user['email'] for user in display_recipient])
 | 
			
		||||
    else:
 | 
			
		||||
        recipient_str = display_recipient
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1380,7 +1380,7 @@ def import_uploads_s3(bucket_name, import_dir, processing_avatars=False):
 | 
			
		||||
        key.set_metadata("realm_id", str(user_profile.realm_id))
 | 
			
		||||
        key.set_metadata("orig_last_modified", record['last_modified'])
 | 
			
		||||
 | 
			
		||||
        headers = {u'Content-Type': record['content_type']}
 | 
			
		||||
        headers = {'Content-Type': record['content_type']}
 | 
			
		||||
 | 
			
		||||
        key.set_contents_from_filename(os.path.join(import_dir, record['path']), headers=headers)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@ def deliver_feedback_by_zulip(message):
 | 
			
		||||
    if len(subject) > 60:
 | 
			
		||||
        subject = subject[:57].rstrip() + "..."
 | 
			
		||||
 | 
			
		||||
    content = u''
 | 
			
		||||
    content = ''
 | 
			
		||||
    sender_email = message['sender_email']
 | 
			
		||||
 | 
			
		||||
    # We generate ticket numbers if it's been more than a few minutes
 | 
			
		||||
 
 | 
			
		||||
@@ -53,7 +53,7 @@ def get_language_list_for_templates(default_language):
 | 
			
		||||
            lang = language_list[ind]
 | 
			
		||||
            percent = name = lang['name']
 | 
			
		||||
            if 'percent_translated' in lang:
 | 
			
		||||
                percent = u"{} ({}%)".format(name, lang['percent_translated'])
 | 
			
		||||
                percent = "{} ({}%)".format(name, lang['percent_translated'])
 | 
			
		||||
 | 
			
		||||
            selected = False
 | 
			
		||||
            if default_language in (lang['code'], lang['locale']):
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ class _RateLimitFilter(object):
 | 
			
		||||
                if record.exc_info is not None:
 | 
			
		||||
                    tb = force_bytes('\n'.join(traceback.format_exception(*record.exc_info)))
 | 
			
		||||
                else:
 | 
			
		||||
                    tb = force_bytes(u'%s' % (record,))
 | 
			
		||||
                    tb = force_bytes('%s' % (record,))
 | 
			
		||||
                key = self.__class__.__name__.upper() + hashlib.sha1(tb).hexdigest()
 | 
			
		||||
                duplicate = cache.get(key) == 1
 | 
			
		||||
                if not duplicate:
 | 
			
		||||
 
 | 
			
		||||
@@ -297,8 +297,8 @@ class MessageDict(object):
 | 
			
		||||
        if rendered_content is not None:
 | 
			
		||||
            obj['rendered_content'] = rendered_content
 | 
			
		||||
        else:
 | 
			
		||||
            obj['rendered_content'] = (u'<p>[Zulip note: Sorry, we could not ' +
 | 
			
		||||
                                       u'understand the formatting of your message]</p>')
 | 
			
		||||
            obj['rendered_content'] = ('<p>[Zulip note: Sorry, we could not ' +
 | 
			
		||||
                                       'understand the formatting of your message]</p>')
 | 
			
		||||
 | 
			
		||||
        if rendered_content is not None:
 | 
			
		||||
            obj['is_me_message'] = Message.is_status_message(content, rendered_content)
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ import logging
 | 
			
		||||
client = get_redis_client()
 | 
			
		||||
rules = settings.RATE_LIMITING_RULES  # type: List[Tuple[int, int]]
 | 
			
		||||
 | 
			
		||||
KEY_PREFIX = u''
 | 
			
		||||
KEY_PREFIX = ''
 | 
			
		||||
 | 
			
		||||
class RateLimitedObject(object):
 | 
			
		||||
    def get_keys(self):
 | 
			
		||||
@@ -59,7 +59,7 @@ class RateLimitedUser(RateLimitedObject):
 | 
			
		||||
def bounce_redis_key_prefix_for_testing(test_name):
 | 
			
		||||
    # type: (Text) -> None
 | 
			
		||||
    global KEY_PREFIX
 | 
			
		||||
    KEY_PREFIX = test_name + u':' + Text(os.getpid()) + u':'
 | 
			
		||||
    KEY_PREFIX = test_name + ':' + Text(os.getpid()) + ':'
 | 
			
		||||
 | 
			
		||||
def max_api_calls(entity):
 | 
			
		||||
    # type: (RateLimitedObject) -> int
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ def realm_icon_url(realm):
 | 
			
		||||
 | 
			
		||||
def get_realm_icon_url(realm):
 | 
			
		||||
    # type: (Realm) -> Text
 | 
			
		||||
    if realm.icon_source == u'U':
 | 
			
		||||
    if realm.icon_source == 'U':
 | 
			
		||||
        return upload_backend.get_realm_icon_url(realm.id, realm.icon_version)
 | 
			
		||||
    elif settings.ENABLE_GRAVATAR:
 | 
			
		||||
        hash_key = gravatar_hash(realm.string_id)
 | 
			
		||||
 
 | 
			
		||||
@@ -215,35 +215,35 @@ class ZulipTestCase(TestCase):
 | 
			
		||||
        return django_client.get(url, info, **kwargs)
 | 
			
		||||
 | 
			
		||||
    example_user_map = dict(
 | 
			
		||||
        hamlet=u'hamlet@zulip.com',
 | 
			
		||||
        cordelia=u'cordelia@zulip.com',
 | 
			
		||||
        iago=u'iago@zulip.com',
 | 
			
		||||
        prospero=u'prospero@zulip.com',
 | 
			
		||||
        othello=u'othello@zulip.com',
 | 
			
		||||
        AARON=u'AARON@zulip.com',
 | 
			
		||||
        aaron=u'aaron@zulip.com',
 | 
			
		||||
        ZOE=u'ZOE@zulip.com',
 | 
			
		||||
        webhook_bot=u'webhook-bot@zulip.com',
 | 
			
		||||
        welcome_bot=u'welcome-bot@zulip.com',
 | 
			
		||||
        outgoing_webhook_bot=u'outgoing-webhook@zulip.com'
 | 
			
		||||
        hamlet='hamlet@zulip.com',
 | 
			
		||||
        cordelia='cordelia@zulip.com',
 | 
			
		||||
        iago='iago@zulip.com',
 | 
			
		||||
        prospero='prospero@zulip.com',
 | 
			
		||||
        othello='othello@zulip.com',
 | 
			
		||||
        AARON='AARON@zulip.com',
 | 
			
		||||
        aaron='aaron@zulip.com',
 | 
			
		||||
        ZOE='ZOE@zulip.com',
 | 
			
		||||
        webhook_bot='webhook-bot@zulip.com',
 | 
			
		||||
        welcome_bot='welcome-bot@zulip.com',
 | 
			
		||||
        outgoing_webhook_bot='outgoing-webhook@zulip.com'
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    mit_user_map = dict(
 | 
			
		||||
        sipbtest=u"sipbtest@mit.edu",
 | 
			
		||||
        starnine=u"starnine@mit.edu",
 | 
			
		||||
        espuser=u"espuser@mit.edu",
 | 
			
		||||
        sipbtest="sipbtest@mit.edu",
 | 
			
		||||
        starnine="starnine@mit.edu",
 | 
			
		||||
        espuser="espuser@mit.edu",
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    # Non-registered test users
 | 
			
		||||
    nonreg_user_map = dict(
 | 
			
		||||
        test=u'test@zulip.com',
 | 
			
		||||
        test1=u'test1@zulip.com',
 | 
			
		||||
        alice=u'alice@zulip.com',
 | 
			
		||||
        newuser=u'newuser@zulip.com',
 | 
			
		||||
        bob=u'bob@zulip.com',
 | 
			
		||||
        cordelia=u'cordelia@zulip.com',
 | 
			
		||||
        newguy=u'newguy@zulip.com',
 | 
			
		||||
        me=u'me@zulip.com',
 | 
			
		||||
        test='test@zulip.com',
 | 
			
		||||
        test1='test1@zulip.com',
 | 
			
		||||
        alice='alice@zulip.com',
 | 
			
		||||
        newuser='newuser@zulip.com',
 | 
			
		||||
        bob='bob@zulip.com',
 | 
			
		||||
        cordelia='cordelia@zulip.com',
 | 
			
		||||
        newguy='newguy@zulip.com',
 | 
			
		||||
        me='me@zulip.com',
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    def nonreg_user(self, name):
 | 
			
		||||
@@ -317,7 +317,7 @@ class ZulipTestCase(TestCase):
 | 
			
		||||
 | 
			
		||||
    def submit_reg_form_for_user(self, email, password, realm_name="Zulip Test",
 | 
			
		||||
                                 realm_subdomain="zuliptest",
 | 
			
		||||
                                 from_confirmation='', full_name=None, timezone=u'',
 | 
			
		||||
                                 from_confirmation='', full_name=None, timezone='',
 | 
			
		||||
                                 realm_in_root_domain=None, **kwargs):
 | 
			
		||||
        # type: (Text, Text, Optional[Text], Optional[Text], Optional[Text], Optional[Text], Optional[Text], Optional[Text], **Any) -> HttpResponse
 | 
			
		||||
        """
 | 
			
		||||
@@ -370,9 +370,9 @@ class ZulipTestCase(TestCase):
 | 
			
		||||
                api_key = get_user_profile_by_email(identifier).api_key
 | 
			
		||||
            API_KEYS[identifier] = api_key
 | 
			
		||||
 | 
			
		||||
        credentials = u"%s:%s" % (identifier, api_key)
 | 
			
		||||
        credentials = "%s:%s" % (identifier, api_key)
 | 
			
		||||
        return {
 | 
			
		||||
            'HTTP_AUTHORIZATION': u'Basic ' + base64.b64encode(credentials.encode('utf-8')).decode('utf-8')
 | 
			
		||||
            'HTTP_AUTHORIZATION': 'Basic ' + base64.b64encode(credentials.encode('utf-8')).decode('utf-8')
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def get_streams(self, email, realm):
 | 
			
		||||
@@ -386,7 +386,7 @@ class ZulipTestCase(TestCase):
 | 
			
		||||
        )
 | 
			
		||||
        return [cast(Text, get_display_recipient(sub.recipient)) for sub in subs]
 | 
			
		||||
 | 
			
		||||
    def send_personal_message(self, from_email, to_email, content=u"test content"):
 | 
			
		||||
    def send_personal_message(self, from_email, to_email, content="test content"):
 | 
			
		||||
        # type: (Text, Text, Text) -> int
 | 
			
		||||
        sender = get_user_profile_by_email(from_email)
 | 
			
		||||
 | 
			
		||||
@@ -398,7 +398,7 @@ class ZulipTestCase(TestCase):
 | 
			
		||||
            content
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def send_huddle_message(self, from_email, to_emails, content=u"test content"):
 | 
			
		||||
    def send_huddle_message(self, from_email, to_emails, content="test content"):
 | 
			
		||||
        # type: (Text, List[Text], Text) -> int
 | 
			
		||||
        sender = get_user_profile_by_email(from_email)
 | 
			
		||||
 | 
			
		||||
@@ -412,7 +412,7 @@ class ZulipTestCase(TestCase):
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def send_stream_message(self, sender_email, stream_name,
 | 
			
		||||
                            content=u"test content", topic_name=u"test"):
 | 
			
		||||
                            content="test content", topic_name="test"):
 | 
			
		||||
        # type: (Text, Text, Text, Text) -> int
 | 
			
		||||
        sender = get_user_profile_by_email(sender_email)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -52,13 +52,13 @@ DEFAULT_EMOJI_SIZE = 64
 | 
			
		||||
# "file name" is the original filename provided by the user run
 | 
			
		||||
# through a sanitization function.
 | 
			
		||||
 | 
			
		||||
attachment_url_re = re.compile(u'[/\-]user[\-_]uploads[/\.-].*?(?=[ )]|\Z)')
 | 
			
		||||
attachment_url_re = re.compile('[/\-]user[\-_]uploads[/\.-].*?(?=[ )]|\Z)')
 | 
			
		||||
 | 
			
		||||
def attachment_url_to_path_id(attachment_url):
 | 
			
		||||
    # type: (Text) -> Text
 | 
			
		||||
    path_id_raw = re.sub(u'[/\-]user[\-_]uploads[/\.-]', u'', attachment_url)
 | 
			
		||||
    path_id_raw = re.sub('[/\-]user[\-_]uploads[/\.-]', '', attachment_url)
 | 
			
		||||
    # Remove any extra '.' after file extension. These are probably added by the user
 | 
			
		||||
    return re.sub(u'[.]+$', u'', path_id_raw, re.M)
 | 
			
		||||
    return re.sub('[.]+$', '', path_id_raw, re.M)
 | 
			
		||||
 | 
			
		||||
def sanitize_name(raw_value):
 | 
			
		||||
    # type: (NonBinaryStr) -> Text
 | 
			
		||||
@@ -194,7 +194,7 @@ def upload_image_to_s3(
 | 
			
		||||
    key.set_metadata("realm_id", str(user_profile.realm_id))
 | 
			
		||||
 | 
			
		||||
    if content_type is not None:
 | 
			
		||||
        headers = {u'Content-Type': content_type}  # type: Optional[Dict[Text, Text]]
 | 
			
		||||
        headers = {'Content-Type': content_type}  # type: Optional[Dict[Text, Text]]
 | 
			
		||||
    else:
 | 
			
		||||
        headers = None
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,12 @@
 | 
			
		||||
from typing import Optional, Any, Dict, List, Text, Tuple
 | 
			
		||||
from collections import defaultdict
 | 
			
		||||
SUBJECT_WITH_BRANCH_TEMPLATE = u'{repo} / {branch}'
 | 
			
		||||
SUBJECT_WITH_PR_OR_ISSUE_INFO_TEMPLATE = u'{repo} / {type} #{id} {title}'
 | 
			
		||||
SUBJECT_WITH_BRANCH_TEMPLATE = '{repo} / {branch}'
 | 
			
		||||
SUBJECT_WITH_PR_OR_ISSUE_INFO_TEMPLATE = '{repo} / {type} #{id} {title}'
 | 
			
		||||
 | 
			
		||||
EMPTY_SHA = '0000000000000000000000000000000000000000'
 | 
			
		||||
 | 
			
		||||
COMMITS_LIMIT = 20
 | 
			
		||||
COMMIT_ROW_TEMPLATE = u'* {commit_msg} ([{commit_short_sha}]({commit_url}))\n'
 | 
			
		||||
COMMIT_ROW_TEMPLATE = '* {commit_msg} ([{commit_short_sha}]({commit_url}))\n'
 | 
			
		||||
COMMITS_MORE_THAN_LIMIT_TEMPLATE = u"[and {commits_number} more commit(s)]"
 | 
			
		||||
COMMIT_OR_COMMITS = u"commit{}"
 | 
			
		||||
 | 
			
		||||
@@ -69,7 +69,7 @@ def get_push_commits_event_message(user_name, compare_url, branch_name,
 | 
			
		||||
    pushed_text_message = pushed_message_template.format(
 | 
			
		||||
        compare_url=compare_url,
 | 
			
		||||
        number_of_commits=len(commits_data),
 | 
			
		||||
        commit_or_commits=COMMIT_OR_COMMITS.format(u's' if len(commits_data) > 1 else u''))
 | 
			
		||||
        commit_or_commits=COMMIT_OR_COMMITS.format('s' if len(commits_data) > 1 else ''))
 | 
			
		||||
 | 
			
		||||
    committers_items = get_all_committers(commits_data)  # type: List[Tuple[str, int]]
 | 
			
		||||
    if len(committers_items) == 1 and user_name == committers_items[0][0]:
 | 
			
		||||
@@ -192,7 +192,7 @@ def get_commits_comment_action_message(user_name, action, commit_url, sha, messa
 | 
			
		||||
 | 
			
		||||
def get_commits_content(commits_data, is_truncated=False):
 | 
			
		||||
    # type: (List[Dict[str, Any]], Optional[bool]) -> Text
 | 
			
		||||
    commits_content = u''
 | 
			
		||||
    commits_content = ''
 | 
			
		||||
    for commit in commits_data[:COMMITS_LIMIT]:
 | 
			
		||||
        commits_content += COMMIT_ROW_TEMPLATE.format(
 | 
			
		||||
            commit_short_sha=get_short_sha(commit['sha']),
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user