def handle(self, *args: Any, **options: Any) -> None:
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        streams = []
        stream_names = {
            stream.strip()
            for stream in options["streams"].split(",")
        }
        for stream_name in set(stream_names):
            stream = ensure_stream(realm, stream_name, acting_user=None)
            streams.append(stream)

        try:
            default_stream_group = DefaultStreamGroup.objects.get(
                name=options["name"],
                realm=realm,
                description=options["description"])
        except DefaultStreamGroup.DoesNotExist:
            default_stream_group = DefaultStreamGroup.objects.create(
                name=options["name"],
                realm=realm,
                description=options["description"])
        default_stream_group.streams.set(streams)

        default_stream_groups = DefaultStreamGroup.objects.all()
        for default_stream_group in default_stream_groups:
            print(default_stream_group.name)
            print(default_stream_group.description)
            for stream in default_stream_group.streams.all():
                print(stream.name)
            print("")
Пример #2
0
    def test_mentions(self) -> None:
        cordelia = self.example_user("cordelia")
        hamlet = self.example_user("hamlet")
        othello = self.example_user("othello")
        zoe = self.example_user("ZOE")

        realm = cordelia.realm

        group_name = "support"
        stream_name = "Dev help"

        content_with_group_mention = "hey @*support* can you help us with this?"

        ensure_stream(realm, stream_name, acting_user=None)

        all_users = {cordelia, hamlet, othello, zoe}
        support_team = {hamlet, zoe}
        sender = cordelia
        other_users = all_users - support_team

        for user in all_users:
            self.subscribe(user, stream_name)

        create_user_group(
            name=group_name,
            members=list(support_team),
            realm=realm,
        )

        payload = dict(
            type="stream",
            to=stream_name,
            topic="whatever",
            content=content_with_group_mention,
        )

        result = self.api_post(sender, "/json/messages", payload)

        self.assert_json_success(result)

        for user in support_team:
            um = most_recent_usermessage(user)
            self.assertTrue(um.flags.mentioned)

        for user in other_users:
            um = most_recent_usermessage(user)
            self.assertFalse(um.flags.mentioned)
Пример #3
0
    def handle(self, *args: Any, **options: Any) -> None:
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        user_profiles = self.get_users(options, realm)
        stream_names = {
            stream.strip()
            for stream in options["streams"].split(",")
        }

        for stream_name in set(stream_names):
            for user_profile in user_profiles:
                stream = ensure_stream(realm, stream_name, acting_user=None)
                _ignore, already_subscribed = bulk_add_subscriptions(
                    realm, [stream], [user_profile], acting_user=None)
                was_there_already = user_profile.id in (
                    info.user.id for info in already_subscribed)
                print("{} {} to {}".format(
                    "Already subscribed"
                    if was_there_already else "Subscribed",
                    user_profile.delivery_email,
                    stream_name,
                ))
Пример #4
0
    def add_message_formatting_conversation(self) -> None:
        realm = get_realm("zulip")
        stream = ensure_stream(realm, "zulip features", acting_user=None)

        UserProfile.objects.filter(email__contains="stage").delete()
        starr = do_create_user("*****@*****.**",
                               "password",
                               realm,
                               "Ada Starr",
                               acting_user=None)
        self.set_avatar(starr, "static/images/characters/starr.png")
        fisher = do_create_user("*****@*****.**",
                                "password",
                                realm,
                                "Bel Fisher",
                                acting_user=None)
        self.set_avatar(fisher, "static/images/characters/fisher.png")
        twitter_bot = do_create_user(
            "*****@*****.**",
            "password",
            realm,
            "Twitter Bot",
            bot_type=UserProfile.DEFAULT_BOT,
            acting_user=None,
        )
        self.set_avatar(twitter_bot, "static/images/features/twitter.png")

        bulk_add_subscriptions(realm, [stream],
                               list(UserProfile.objects.filter(realm=realm)),
                               acting_user=None)

        staged_messages: List[Dict[str, Any]] = [
            {
                "sender":
                starr,
                "content":
                "Hey @**Bel Fisher**, check out Zulip's Markdown formatting! "
                "You can have:\n* bulleted lists\n  * with sub-bullets too\n"
                "* **bold**, *italic*, and ~~strikethrough~~ text\n"
                "* LaTeX for mathematical formulas, both inline -- $$O(n^2)$$ -- and displayed:\n"
                "```math\n\\int_a^b f(t)\\, dt=F(b)-F(a)\n```",
            },
            {
                "sender":
                fisher,
                "content":
                "My favorite is the syntax highlighting for code blocks\n"
                "```python\ndef fib(n: int) -> int:\n    # returns the n-th Fibonacci number\n"
                "    return fib(n-1) + fib(n-2)\n```",
            },
            {
                "sender":
                starr,
                "content":
                "I think you forgot your base case there, Bel :laughing:\n"
                "```quote\n```python\ndef fib(n: int) -> int:\n    # returns the n-th Fibonacci number\n"
                "    return fib(n-1) + fib(n-2)\n```\n```",
            },
            {
                "sender":
                fisher,
                "content":
                "I'm also a big fan of inline link, tweet, video, and image previews. "
                "Check out this picture of Çet Whalin[](/static/images/features/whale.png)!",
            },
            {
                "sender":
                starr,
                "content":
                "I just set up a custom linkifier, "
                "so `#1234` becomes [#1234](github.com/zulip/zulip/1234), "
                "a link to the corresponding GitHub issue.",
            },
            {
                "sender":
                twitter_bot,
                "content":
                "https://twitter.com/gvanrossum/status/786661035637772288",
            },
            {
                "sender":
                fisher,
                "content":
                "Oops, the Twitter bot I set up shouldn't be posting here. Let me go fix that.",
            },
        ]

        messages = [
            internal_prep_stream_message(
                message["sender"],
                stream,
                "message formatting",
                message["content"],
            ) for message in staged_messages
        ]

        message_ids = do_send_messages(messages)

        preview_message = Message.objects.get(
            id__in=message_ids, content__icontains="image previews")
        (emoji_code, reaction_type) = emoji_name_to_emoji_code(realm, "whale")
        do_add_reaction(starr, preview_message, "whale", emoji_code,
                        reaction_type)

        twitter_message = Message.objects.get(id__in=message_ids,
                                              content__icontains="gvanrossum")
        # Setting up a twitter integration in dev is a decent amount of work. If you need
        # to update this tweet, either copy the format below, or send the link to the tweet
        # to chat.zulip.org and ask an admin of that server to get you the rendered_content.
        twitter_message.rendered_content = (
            "<p><a>https://twitter.com/gvanrossum/status/786661035637772288</a></p>\n"
            '<div class="inline-preview-twitter"><div class="twitter-tweet">'
            '<a><img class="twitter-avatar" '
            'src="https://pbs.twimg.com/profile_images/424495004/GuidoAvatar_bigger.jpg"></a>'
            "<p>Great blog post about Zulip's use of mypy: "
            "<a>http://blog.zulip.org/2016/10/13/static-types-in-python-oh-mypy/</a></p>"
            "<span>- Guido van Rossum (@gvanrossum)</span></div></div>")
        twitter_message.save(update_fields=["rendered_content"])

        # Put a short pause between the whale reaction and this, so that the
        # thumbs_up shows up second
        (emoji_code,
         reaction_type) = emoji_name_to_emoji_code(realm, "thumbs_up")
        do_add_reaction(starr, preview_message, "thumbs_up", emoji_code,
                        reaction_type)
Пример #5
0
def do_create_realm(
    string_id: str,
    name: str,
    *,
    emails_restricted_to_domains: Optional[bool] = None,
    email_address_visibility: Optional[int] = None,
    description: Optional[str] = None,
    invite_required: Optional[bool] = None,
    plan_type: Optional[int] = None,
    org_type: Optional[int] = None,
    date_created: Optional[datetime.datetime] = None,
    is_demo_organization: bool = False,
    enable_spectator_access: Optional[bool] = None,
) -> Realm:
    if string_id == settings.SOCIAL_AUTH_SUBDOMAIN:
        raise AssertionError("Creating a realm on SOCIAL_AUTH_SUBDOMAIN is not allowed!")
    if Realm.objects.filter(string_id=string_id).exists():
        raise AssertionError(f"Realm {string_id} already exists!")
    if not server_initialized():
        logging.info("Server not yet initialized. Creating the internal realm first.")
        create_internal_realm()

    kwargs: Dict[str, Any] = {}
    if emails_restricted_to_domains is not None:
        kwargs["emails_restricted_to_domains"] = emails_restricted_to_domains
    if email_address_visibility is not None:
        kwargs["email_address_visibility"] = email_address_visibility
    if description is not None:
        kwargs["description"] = description
    if invite_required is not None:
        kwargs["invite_required"] = invite_required
    if plan_type is not None:
        kwargs["plan_type"] = plan_type
    if org_type is not None:
        kwargs["org_type"] = org_type
    if enable_spectator_access is not None:
        kwargs["enable_spectator_access"] = enable_spectator_access

    if date_created is not None:
        # The date_created parameter is intended only for use by test
        # suites that want to backdate the date of a realm's creation.
        assert not settings.PRODUCTION
        kwargs["date_created"] = date_created

    with transaction.atomic():
        realm = Realm(string_id=string_id, name=name, **kwargs)
        if is_demo_organization:
            realm.demo_organization_scheduled_deletion_date = (
                realm.date_created + datetime.timedelta(days=settings.DEMO_ORG_DEADLINE_DAYS)
            )

        set_realm_permissions_based_on_org_type(realm)
        realm.save()

        RealmAuditLog.objects.create(
            # acting_user will be set as the initial realm owner inside
            # do_create_user(..., realm_creation=True).
            acting_user=None,
            realm=realm,
            event_type=RealmAuditLog.REALM_CREATED,
            event_time=realm.date_created,
        )

        RealmUserDefault.objects.create(realm=realm)

        create_system_user_groups_for_realm(realm)

    # Create stream once Realm object has been saved
    notifications_stream = ensure_stream(
        realm,
        Realm.DEFAULT_NOTIFICATION_STREAM_NAME,
        stream_description="Everyone is added to this stream by default. Welcome! :octopus:",
        acting_user=None,
    )
    realm.notifications_stream = notifications_stream

    # With the current initial streams situation, the only public
    # stream is the notifications_stream.
    DefaultStream.objects.create(stream=notifications_stream, realm=realm)

    signup_notifications_stream = ensure_stream(
        realm,
        Realm.INITIAL_PRIVATE_STREAM_NAME,
        invite_only=True,
        stream_description="A private stream for core team members.",
        acting_user=None,
    )
    realm.signup_notifications_stream = signup_notifications_stream

    realm.save(update_fields=["notifications_stream", "signup_notifications_stream"])

    if plan_type is None and settings.BILLING_ENABLED:
        # We use acting_user=None for setting the initial plan type.
        do_change_realm_plan_type(realm, Realm.PLAN_TYPE_LIMITED, acting_user=None)

    admin_realm = get_realm(settings.SYSTEM_BOT_REALM)
    sender = get_system_bot(settings.NOTIFICATION_BOT, admin_realm.id)
    # Send a notification to the admin realm
    signup_message = _("Signups enabled")

    try:
        signups_stream = get_signups_stream(admin_realm)
        topic = realm.display_subdomain

        internal_send_stream_message(
            sender,
            signups_stream,
            topic,
            signup_message,
        )
    except Stream.DoesNotExist:  # nocoverage
        # If the signups stream hasn't been created in the admin
        # realm, don't auto-create it to send to it; just do nothing.
        pass

    setup_realm_internal_bots(realm)
    return realm