def setup_initial_streams(realm: Realm) -> None: stream_dicts = [ {'name': "general"}, {'name': "new members", 'description': "For welcoming and onboarding new members. If you haven't yet, " "introduce yourself in a new thread using your name as the topic!"}, {'name': "zulip", 'description': "For discussing Zulip, Zulip tips and tricks, and asking " "questions about how Zulip works"}] # type: List[Mapping[str, Any]] create_streams_if_needed(realm, stream_dicts) set_default_streams(realm, {stream['name']: {} for stream in stream_dicts})
def list_to_streams(streams_raw, user_profile, autocreate=False, invite_only=False): # type: (Iterable[text_type], UserProfile, Optional[bool], Optional[bool]) -> Tuple[List[Stream], List[Stream]] """Converts plaintext stream names to a list of Streams, validating input in the process For each stream name, we validate it to ensure it meets our requirements for a proper stream name: that is, that it is shorter than Stream.MAX_NAME_LENGTH characters and passes valid_stream_name. This function in autocreate mode should be atomic: either an exception will be raised during a precheck, or all the streams specified will have been created if applicable. @param streams_raw The list of stream names to process @param user_profile The user for whom we are retreiving the streams @param autocreate Whether we should create streams if they don't already exist @param invite_only Whether newly created streams should have the invite_only bit set """ # Validate all streams, getting extant ones, then get-or-creating the rest. stream_set = set(stream_name.strip() for stream_name in streams_raw) for stream_name in stream_set: if len(stream_name) > Stream.MAX_NAME_LENGTH: raise JsonableError(_("Stream name (%s) too long.") % (stream_name,)) if not valid_stream_name(stream_name): raise JsonableError(_("Invalid stream name (%s).") % (stream_name,)) existing_streams = [] # type: List[Stream] missing_stream_names = [] # type: List[text_type] existing_stream_map = bulk_get_streams(user_profile.realm, stream_set) for stream_name in stream_set: stream = existing_stream_map.get(stream_name.lower()) if stream is None: missing_stream_names.append(stream_name) else: existing_streams.append(stream) if not missing_stream_names: # This is the happy path for callers who expected all of these # streams to exist already. created_streams = [] # type: List[Stream] else: # autocreate=True path starts here if not user_profile.can_create_streams(): raise JsonableError(_('User cannot create streams.')) elif not autocreate: raise JsonableError(_("Stream(s) (%s) do not exist") % ", ".join(missing_stream_names)) # We already filtered out existing streams, so dup_streams # will normally be an empty list below, but we protect against somebody # else racing to create the same stream. (This is not an entirely # paranoid approach, since often on Zulip two people will discuss # creating a new stream, and both people eagerly do it.) created_streams, dup_streams = create_streams_if_needed(realm=user_profile.realm, stream_names=missing_stream_names, invite_only=invite_only) existing_streams += dup_streams return existing_streams, created_streams
def list_to_streams(streams_raw: Iterable[Mapping[str, Any]], user_profile: UserProfile, autocreate: bool=False) -> Tuple[List[Stream], List[Stream]]: """Converts list of dicts to a list of Streams, validating input in the process For each stream name, we validate it to ensure it meets our requirements for a proper stream name using check_stream_name. This function in autocreate mode should be atomic: either an exception will be raised during a precheck, or all the streams specified will have been created if applicable. @param streams_raw The list of stream dictionaries to process; names should already be stripped of whitespace by the caller. @param user_profile The user for whom we are retreiving the streams @param autocreate Whether we should create streams if they don't already exist """ # Validate all streams, getting extant ones, then get-or-creating the rest. stream_set = set(stream_dict["name"] for stream_dict in streams_raw) for stream_name in stream_set: # Stream names should already have been stripped by the # caller, but it makes sense to verify anyway. assert stream_name == stream_name.strip() check_stream_name(stream_name) existing_streams = [] # type: List[Stream] missing_stream_dicts = [] # type: List[Mapping[str, Any]] existing_stream_map = bulk_get_streams(user_profile.realm, stream_set) for stream_dict in streams_raw: stream_name = stream_dict["name"] stream = existing_stream_map.get(stream_name.lower()) if stream is None: missing_stream_dicts.append(stream_dict) else: existing_streams.append(stream) if len(missing_stream_dicts) == 0: # This is the happy path for callers who expected all of these # streams to exist already. created_streams = [] # type: List[Stream] else: # autocreate=True path starts here if not user_profile.can_create_streams(): raise JsonableError(_('User cannot create streams.')) elif not autocreate: raise JsonableError(_("Stream(s) (%s) do not exist") % ", ".join( stream_dict["name"] for stream_dict in missing_stream_dicts)) # We already filtered out existing streams, so dup_streams # will normally be an empty list below, but we protect against somebody # else racing to create the same stream. (This is not an entirely # paranoid approach, since often on Zulip two people will discuss # creating a new stream, and both people eagerly do it.) created_streams, dup_streams = create_streams_if_needed(realm=user_profile.realm, stream_dicts=missing_stream_dicts) existing_streams += dup_streams return existing_streams, created_streams
def list_to_streams(streams_raw, user_profile, autocreate=False, invite_only=False): # type: (Iterable[text_type], UserProfile, Optional[bool], Optional[bool]) -> Tuple[List[Stream], List[Stream]] """Converts plaintext stream names to a list of Streams, validating input in the process For each stream name, we validate it to ensure it meets our requirements for a proper stream name: that is, that it is shorter than Stream.MAX_NAME_LENGTH characters and passes valid_stream_name. This function in autocreate mode should be atomic: either an exception will be raised during a precheck, or all the streams specified will have been created if applicable. @param streams_raw The list of stream names to process @param user_profile The user for whom we are retreiving the streams @param autocreate Whether we should create streams if they don't already exist @param invite_only Whether newly created streams should have the invite_only bit set """ # Validate all streams, getting extant ones, then get-or-creating the rest. stream_set = set(stream_name.strip() for stream_name in streams_raw) for stream_name in stream_set: if len(stream_name) > Stream.MAX_NAME_LENGTH: raise JsonableError( _("Stream name (%s) too long.") % (stream_name, )) if not valid_stream_name(stream_name): raise JsonableError( _("Invalid stream name (%s).") % (stream_name, )) existing_streams = [] # type: List[Stream] missing_stream_names = [] # type: List[text_type] existing_stream_map = bulk_get_streams(user_profile.realm, stream_set) for stream_name in stream_set: stream = existing_stream_map.get(stream_name.lower()) if stream is None: missing_stream_names.append(stream_name) else: existing_streams.append(stream) if not missing_stream_names: # This is the happy path for callers who expected all of these # streams to exist already. created_streams = [] # type: List[Stream] else: # autocreate=True path starts here if not user_profile.can_create_streams(): raise JsonableError(_('User cannot create streams.')) elif not autocreate: raise JsonableError( _("Stream(s) (%s) do not exist") % ", ".join(missing_stream_names)) # We already filtered out existing streams, so dup_streams # will normally be an empty list below, but we protect against somebody # else racing to create the same stream. (This is not an entirely # paranoid approach, since often on Zulip two people will discuss # creating a new stream, and both people eagerly do it.) created_streams, dup_streams = create_streams_if_needed( realm=user_profile.realm, stream_names=missing_stream_names, invite_only=invite_only) existing_streams += dup_streams return existing_streams, created_streams