def get_guest(user: ZerverFieldsT) -> bool: restricted_user = user.get('is_restricted', False) ultra_restricted_user = user.get('is_ultra_restricted', False) if restricted_user or ultra_restricted_user: return True else: return False
def get_admin(user: ZerverFieldsT) -> bool: admin = user.get('is_admin', False) owner = user.get('is_owner', False) primary_owner = user.get('is_primary_owner', False) if admin or owner or primary_owner: return True return False
def get_guest(user: ZerverFieldsT) -> bool: restricted_user = user.get('is_restricted', False) ultra_restricted_user = user.get('is_ultra_restricted', False) # Slack's Single channel and multi channel guests both have # is_restricted set to True. So assuming Slack doesn't change their # data model, it would also be correct to just check whether # is_restricted is set to True. return restricted_user or ultra_restricted_user
def build_customprofile_field(customprofile_field: List[ZerverFieldsT], fields: ZerverFieldsT, customprofilefield_id: int, realm_id: int, custom_field_map: ZerverFieldsT) -> Tuple[ZerverFieldsT, int]: # The name of the custom profile field is not provided in the slack data # Hash keys of the fields are provided # Reference: https://api.slack.com/methods/users.profile.set for field, value in fields.items(): if field not in custom_field_map: slack_custom_fields = ['phone', 'skype'] if field in slack_custom_fields: field_name = field else: field_name = ("slack custom field %s" % str(customprofilefield_id + 1)) customprofilefield = CustomProfileField( id=customprofilefield_id, name=field_name, field_type=1 # For now this is defaulted to 'SHORT_TEXT' # Processing is done in the function 'process_customprofilefields' ) customprofilefield_dict = model_to_dict(customprofilefield, exclude=['realm']) customprofilefield_dict['realm'] = realm_id custom_field_map[field] = customprofilefield_id customprofilefield_id += 1 customprofile_field.append(customprofilefield_dict) return custom_field_map, customprofilefield_id
def build_customprofile_field( customprofile_field: List[ZerverFieldsT], fields: ZerverFieldsT, custom_profile_field_id: int, realm_id: int, slack_custom_field_name_to_zulip_custom_field_id: ZerverFieldsT, ) -> Tuple[ZerverFieldsT, int]: # The name of the custom profile field is not provided in the Slack data # Hash keys of the fields are provided # Reference: https://api.slack.com/methods/users.profile.set for field, value in fields.items(): if field not in slack_custom_field_name_to_zulip_custom_field_id: slack_custom_fields = ["phone", "skype"] if field in slack_custom_fields: field_name = field else: field_name = f"Slack custom field {str(custom_profile_field_id + 1)}" customprofilefield = CustomProfileField( id=custom_profile_field_id, name=field_name, field_type=1, # For now this is defaulted to 'SHORT_TEXT' # Processing is done in the function 'process_customprofilefields' ) customprofilefield_dict = model_to_dict(customprofilefield, exclude=["realm"]) customprofilefield_dict["realm"] = realm_id slack_custom_field_name_to_zulip_custom_field_id[field] = custom_profile_field_id custom_profile_field_id += 1 customprofile_field.append(customprofilefield_dict) return slack_custom_field_name_to_zulip_custom_field_id, custom_profile_field_id
def build_customprofilefields_values( custom_field_map: ZerverFieldsT, fields: ZerverFieldsT, user_id: int, custom_field_id: int, custom_field_values: List[ZerverFieldsT]) -> int: for field, value in fields.items(): custom_field_value = dict(id=custom_field_id, user_profile=user_id, field=custom_field_map[field], value=value['value']) custom_field_values.append(custom_field_value) custom_field_id += 1 return custom_field_id
def build_customprofilefields_values( custom_field_map: ZerverFieldsT, fields: ZerverFieldsT, user_id: int, custom_field_id: int, custom_field_values: List[ZerverFieldsT]) -> int: for field, value in fields.items(): custom_field_value = CustomProfileFieldValue(id=custom_field_id, value=value['value']) custom_field_value_dict = model_to_dict( custom_field_value, exclude=['user_profile', 'field']) custom_field_value_dict['user_profile'] = user_id custom_field_value_dict['field'] = custom_field_map[field] custom_field_values.append(custom_field_value_dict) custom_field_id += 1 return custom_field_id
def build_customprofilefields_values(custom_field_map: ZerverFieldsT, fields: ZerverFieldsT, user_id: int, custom_field_id: int, custom_field_values: List[ZerverFieldsT]) -> int: for field, value in fields.items(): custom_field_value = CustomProfileFieldValue( id=custom_field_id, value=value['value']) custom_field_value_dict = model_to_dict(custom_field_value, exclude=['user_profile', 'field']) custom_field_value_dict['user_profile'] = user_id custom_field_value_dict['field'] = custom_field_map[field] custom_field_values.append(custom_field_value_dict) custom_field_id += 1 return custom_field_id
def build_customprofilefields_values(slack_custom_field_name_to_zulip_custom_field_id: ZerverFieldsT, fields: ZerverFieldsT, user_id: int, custom_field_id: int, custom_field_values: List[ZerverFieldsT]) -> int: for field, value in fields.items(): if value['value'] == "": continue custom_field_value = CustomProfileFieldValue( id=custom_field_id, value=value['value']) custom_field_value_dict = model_to_dict(custom_field_value, exclude=['user_profile', 'field']) custom_field_value_dict['user_profile'] = user_id custom_field_value_dict['field'] = slack_custom_field_name_to_zulip_custom_field_id[field] custom_field_values.append(custom_field_value_dict) custom_field_id += 1 return custom_field_id
def build_realmemoji( custom_emoji_list: ZerverFieldsT, realm_id: int) -> Tuple[List[ZerverFieldsT], ZerverFieldsT]: zerver_realmemoji = [] emoji_url_map = {} emoji_id = 0 for emoji_name, url in custom_emoji_list.items(): if 'emoji.slack-edge.com' in url: # Some of the emojis we get from the api have invalid links # this is to prevent errors related to them realmemoji = dict(name=emoji_name, id=emoji_id, author=None, realm=realm_id, file_name=os.path.basename(url), deactivated=False) emoji_url_map[emoji_name] = url zerver_realmemoji.append(realmemoji) emoji_id += 1 return zerver_realmemoji, emoji_url_map
def build_realmemoji( custom_emoji_list: ZerverFieldsT, realm_id: int ) -> Tuple[List[ZerverFieldsT], ZerverFieldsT]: zerver_realmemoji = [] emoji_url_map = {} emoji_id = 0 for emoji_name, url in custom_emoji_list.items(): if "emoji.slack-edge.com" in url: # Some of the emojis we get from the API have invalid links # this is to prevent errors related to them realmemoji = RealmEmoji( name=emoji_name, id=emoji_id, file_name=os.path.basename(url), deactivated=False ) realmemoji_dict = model_to_dict(realmemoji, exclude=["realm", "author"]) realmemoji_dict["author"] = None realmemoji_dict["realm"] = realm_id emoji_url_map[emoji_name] = url zerver_realmemoji.append(realmemoji_dict) emoji_id += 1 return zerver_realmemoji, emoji_url_map
def build_realmemoji(custom_emoji_list: ZerverFieldsT, realm_id: int) -> Tuple[List[ZerverFieldsT], ZerverFieldsT]: zerver_realmemoji = [] emoji_url_map = {} emoji_id = 0 for emoji_name, url in custom_emoji_list.items(): if 'emoji.slack-edge.com' in url: # Some of the emojis we get from the api have invalid links # this is to prevent errors related to them realmemoji = RealmEmoji( name=emoji_name, id=emoji_id, file_name=os.path.basename(url), deactivated=False) realmemoji_dict = model_to_dict(realmemoji, exclude=['realm', 'author']) realmemoji_dict['author'] = None realmemoji_dict['realm'] = realm_id emoji_url_map[emoji_name] = url zerver_realmemoji.append(realmemoji_dict) emoji_id += 1 return zerver_realmemoji, emoji_url_map
def get_message_sending_user(message: ZerverFieldsT) -> Optional[str]: if 'user' in message: return message['user'] if message.get('file'): return message['file'].get('user') return None
def get_user_timezone(user: ZerverFieldsT) -> str: _default_timezone = "America/New_York" timezone = user.get("tz", _default_timezone) if timezone is None or '/' not in timezone: timezone = _default_timezone return timezone
def get_message_sending_user(message: ZerverFieldsT) -> Optional[str]: if "user" in message: return message["user"] if message.get("file"): return message["file"].get("user") return None
def get_owner(user: ZerverFieldsT) -> bool: owner = user.get("is_owner", False) primary_owner = user.get("is_primary_owner", False) return primary_owner or owner
def process_message_files(message: ZerverFieldsT, domain_name: str, realm_id: int, message_id: int, user: str, users: List[ZerverFieldsT], added_users: AddedUsersT, zerver_attachment: List[ZerverFieldsT], uploads_list: List[ZerverFieldsT]) -> Dict[str, Any]: has_attachment = False has_image = False has_link = False files = message.get('files', []) subtype = message.get('subtype') if subtype == 'file_share': # In Slack messages, uploads can either have the subtype as 'file_share' or # have the upload information in 'files' keyword files = [message['file']] markdown_links = [] for fileinfo in files: url = fileinfo['url_private'] if 'files.slack.com' in url: # For attachments with slack download link has_attachment = True has_link = True has_image = True if 'image' in fileinfo['mimetype'] else False file_user = [iterate_user for iterate_user in users if message['user'] == iterate_user['id']] file_user_email = get_user_email(file_user[0], domain_name) s3_path, content_for_link = get_attachment_path_and_content(fileinfo, realm_id) markdown_links.append(content_for_link) # construct attachments build_uploads(added_users[user], realm_id, file_user_email, fileinfo, s3_path, uploads_list) build_attachment(realm_id, {message_id}, added_users[user], fileinfo, s3_path, zerver_attachment) else: # For attachments with link not from slack # Example: Google drive integration has_link = True if 'title' in fileinfo: file_name = fileinfo['title'] else: file_name = fileinfo['name'] markdown_links.append('[%s](%s)' % (file_name, fileinfo['url_private'])) content = '\n'.join(markdown_links) return dict( content=content, has_attachment=has_attachment, has_image=has_image, has_link=has_link, )
def get_admin(user: ZerverFieldsT) -> bool: admin = user.get("is_admin", False) return admin
def process_message_files( message: ZerverFieldsT, domain_name: str, realm_id: int, message_id: int, slack_user_id: str, users: List[ZerverFieldsT], slack_user_id_to_zulip_user_id: SlackToZulipUserIDT, zerver_attachment: List[ZerverFieldsT], uploads_list: List[ZerverFieldsT], ) -> Dict[str, Any]: has_attachment = False has_image = False has_link = False files = message.get("files", []) subtype = message.get("subtype") if subtype == "file_share": # In Slack messages, uploads can either have the subtype as 'file_share' or # have the upload information in 'files' keyword files = [message["file"]] markdown_links = [] for fileinfo in files: if fileinfo.get("mode", "") in ["tombstone", "hidden_by_limit"]: # Slack sometimes includes tombstone mode files with no # real data on the actual file (presumably in cases where # the file was deleted). hidden_by_limit mode is for files # that are hidden because of 10k cap in free plan. continue url = fileinfo["url_private"] if "files.slack.com" in url: # For attachments with Slack download link has_attachment = True has_link = True has_image = True if "image" in fileinfo["mimetype"] else False file_user = [ iterate_user for iterate_user in users if message["user"] == iterate_user["id"] ] file_user_email = get_user_email(file_user[0], domain_name) s3_path, content_for_link = get_attachment_path_and_content(fileinfo, realm_id) markdown_links.append(content_for_link) build_uploads( slack_user_id_to_zulip_user_id[slack_user_id], realm_id, file_user_email, fileinfo, s3_path, uploads_list, ) build_attachment( realm_id, {message_id}, slack_user_id_to_zulip_user_id[slack_user_id], fileinfo, s3_path, zerver_attachment, ) else: # For attachments with link not from Slack # Example: Google drive integration has_link = True if "title" in fileinfo: file_name = fileinfo["title"] else: file_name = fileinfo["name"] markdown_links.append("[{}]({})".format(file_name, fileinfo["url_private"])) content = "\n".join(markdown_links) return dict( content=content, has_attachment=has_attachment, has_image=has_image, has_link=has_link, )
def process_message_files(message: ZerverFieldsT, domain_name: str, realm_id: int, message_id: int, slack_user_id: str, users: List[ZerverFieldsT], slack_user_id_to_zulip_user_id: SlackToZulipUserIDT, zerver_attachment: List[ZerverFieldsT], uploads_list: List[ZerverFieldsT]) -> Dict[str, Any]: has_attachment = False has_image = False has_link = False files = message.get('files', []) subtype = message.get('subtype') if subtype == 'file_share': # In Slack messages, uploads can either have the subtype as 'file_share' or # have the upload information in 'files' keyword files = [message['file']] markdown_links = [] for fileinfo in files: if fileinfo.get('mode', '') in ['tombstone', 'hidden_by_limit']: # Slack sometimes includes tombstone mode files with no # real data on the actual file (presumably in cases where # the file was deleted). hidden_by_limit mode is for files # that are hidden because of 10k cap in free plan. continue url = fileinfo['url_private'] if 'files.slack.com' in url: # For attachments with slack download link has_attachment = True has_link = True has_image = True if 'image' in fileinfo['mimetype'] else False file_user = [ iterate_user for iterate_user in users if message['user'] == iterate_user['id'] ] file_user_email = get_user_email(file_user[0], domain_name) s3_path, content_for_link = get_attachment_path_and_content( fileinfo, realm_id) markdown_links.append(content_for_link) build_uploads(slack_user_id_to_zulip_user_id[slack_user_id], realm_id, file_user_email, fileinfo, s3_path, uploads_list) build_attachment(realm_id, {message_id}, slack_user_id_to_zulip_user_id[slack_user_id], fileinfo, s3_path, zerver_attachment) else: # For attachments with link not from slack # Example: Google drive integration has_link = True if 'title' in fileinfo: file_name = fileinfo['title'] else: file_name = fileinfo['name'] markdown_links.append('[%s](%s)' % (file_name, fileinfo['url_private'])) content = '\n'.join(markdown_links) return dict( content=content, has_attachment=has_attachment, has_image=has_image, has_link=has_link, )