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("")
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)
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, ))
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)
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