pleroma-fe/src/services/entity_normalizer/entity_normalizer.service.js

317 lines
8.7 KiB
JavaScript
Raw Normal View History

2019-01-14 12:30:14 +00:00
const qvitterStatusType = (status) => {
if (status.is_post_verb) {
return 'status'
}
if (status.retweeted_status) {
return 'retweet'
}
if ((typeof status.uri === 'string' && status.uri.match(/(fave|objectType=Favourite)/)) ||
(typeof status.text === 'string' && status.text.match(/favorited/))) {
return 'favorite'
}
if (status.text.match(/deleted notice {{tag/) || status.qvitter_delete_notice) {
return 'deletion'
}
if (status.text.match(/started following/) || status.activity_type === 'follow') {
return 'follow'
}
return 'unknown'
}
2019-01-14 12:30:14 +00:00
export const parseUser = (data) => {
const output = {}
const masto = data.hasOwnProperty('acct')
// case for users in "mentions" property for statuses in MastoAPI
const mastoShort = masto && !data.hasOwnProperty('avatar')
output.id = String(data.id)
2019-01-14 12:30:14 +00:00
if (masto) {
output.screen_name = data.acct
// There's nothing else to get
if (mastoShort) {
return output
}
// output.name = ??? missing
2019-03-17 12:41:05 +00:00
output.name_html = addEmojis(data.display_name, data.emojis)
2019-01-14 12:30:14 +00:00
// output.description = ??? missing
2019-03-17 12:41:05 +00:00
output.description_html = addEmojis(data.note, data.emojis)
2019-01-14 12:30:14 +00:00
// Utilize avatar_static for gif avatars?
output.profile_image_url = data.avatar
output.profile_image_url_original = data.avatar
// Same, utilize header_static?
output.cover_photo = data.header
output.friends_count = data.following_count
output.bot = data.bot
output.statusnet_profile_url = data.url
if (data.pleroma) {
const relationship = data.pleroma.relationship
if (relationship) {
2019-03-12 19:49:03 +00:00
output.follows_you = relationship.followed_by
output.following = relationship.following
output.statusnet_blocking = relationship.blocking
output.muted = relationship.muting
}
}
2019-01-17 20:53:05 +00:00
// TODO: handle is_local
2019-03-13 19:43:48 +00:00
output.is_local = !output.screen_name.includes('@')
2019-01-14 12:30:14 +00:00
} else {
output.screen_name = data.screen_name
output.name = data.name
output.name_html = data.name_html
output.description = data.description
output.description_html = data.description_html
output.profile_image_url = data.profile_image_url
output.profile_image_url_original = data.profile_image_url_original
output.cover_photo = data.cover_photo
output.friends_count = data.friends_count
// output.bot = ??? missing
2019-01-14 12:30:14 +00:00
output.statusnet_profile_url = data.statusnet_profile_url
2019-01-17 20:53:05 +00:00
output.statusnet_blocking = data.statusnet_blocking
2019-01-14 12:30:14 +00:00
output.is_local = data.is_local
output.role = data.role
output.show_role = data.show_role
2019-01-17 19:11:51 +00:00
2019-01-17 20:53:05 +00:00
output.follows_you = data.follows_you
output.muted = data.muted
2019-01-17 19:11:51 +00:00
// QVITTER ONLY FOR NOW
// Really only applies to logged in user, really.. I THINK
output.rights = data.rights
output.no_rich_text = data.no_rich_text
output.default_scope = data.default_scope
output.hide_follows = data.hide_follows
output.hide_followers = data.hide_followers
2019-01-17 19:11:51 +00:00
output.background_image = data.background_image
2019-01-27 14:10:55 +00:00
// on mastoapi this info is contained in a "relationship"
output.following = data.following
// Websocket token
output.token = data.token
}
2019-01-14 12:30:14 +00:00
output.created_at = new Date(data.created_at)
output.locked = data.locked
output.followers_count = data.followers_count
output.statuses_count = data.statuses_count
output.friends = []
output.followers = []
if (data.pleroma) {
output.follow_request_count = data.pleroma.follow_request_count
}
2019-01-14 12:30:14 +00:00
return output
}
export const parseAttachment = (data) => {
2019-01-21 13:28:36 +00:00
const output = {}
const masto = !data.hasOwnProperty('oembed')
if (masto) {
// Not exactly same...
output.mimetype = data.pleroma ? data.pleroma.mime_type : data.type
2019-01-21 13:28:36 +00:00
output.meta = data.meta // not present in BE yet
2019-03-25 16:19:33 +00:00
output.id = data.id
2019-01-21 13:28:36 +00:00
} else {
output.mimetype = data.mimetype
// output.meta = ??? missing
}
2019-01-21 13:28:36 +00:00
output.url = data.url
output.description = data.description
return output
}
2019-03-11 20:41:08 +00:00
export const addEmojis = (string, emojis) => {
2019-03-09 00:15:35 +00:00
return emojis.reduce((acc, emoji) => {
return acc.replace(
new RegExp(`:${emoji.shortcode}:`, 'g'),
`<img src='${emoji.url}' alt='${emoji.shortcode}' class='emoji' />`
)
}, string)
}
export const parseStatus = (data) => {
const output = {}
const masto = data.hasOwnProperty('account')
if (masto) {
output.favorited = data.favourited
output.fave_num = data.favourites_count
output.repeated = data.reblogged
output.repeat_num = data.reblogs_count
output.type = data.reblog ? 'retweet' : 'status'
output.nsfw = data.sensitive
2019-03-09 00:15:35 +00:00
output.statusnet_html = addEmojis(data.content, data.emojis)
2019-01-14 19:58:23 +00:00
// Not exactly the same but works?
output.text = data.content
output.in_reply_to_status_id = data.in_reply_to_id
2019-01-17 20:22:51 +00:00
output.in_reply_to_user_id = data.in_reply_to_account_id
2019-01-21 18:41:17 +00:00
// Missing!! fix in UI?
// output.in_reply_to_screen_name = ???
2019-01-14 19:58:23 +00:00
2019-03-18 18:42:09 +00:00
// It breaks the conversation when combined with notification
// output.statusnet_conversation_id = data.id
if (output.type === 'retweet') {
output.retweeted_status = parseStatus(data.reblog)
}
2019-01-17 20:22:51 +00:00
output.summary = data.spoiler_text
2019-03-09 00:15:35 +00:00
output.summary_html = addEmojis(data.spoiler_text, data.emojis)
2019-01-17 20:44:31 +00:00
output.external_url = data.url
2019-03-15 02:07:42 +00:00
output.is_local = data.pleroma.local
} else {
output.favorited = data.favorited
output.fave_num = data.fave_num
output.repeated = data.repeated
output.repeat_num = data.repeat_num
// catchall, temporary
// Object.assign(output, data)
output.type = qvitterStatusType(data)
if (data.nsfw === undefined) {
output.nsfw = isNsfw(data)
if (data.retweeted_status) {
output.nsfw = data.retweeted_status.nsfw
}
} else {
output.nsfw = data.nsfw
}
output.statusnet_html = data.statusnet_html
output.text = data.text
2019-01-17 20:22:51 +00:00
output.in_reply_to_status_id = data.in_reply_to_status_id
output.in_reply_to_user_id = data.in_reply_to_user_id
2019-01-21 18:41:17 +00:00
output.in_reply_to_screen_name = data.in_reply_to_screen_name
2019-01-14 19:58:23 +00:00
output.statusnet_conversation_id = data.statusnet_conversation_id
if (output.type === 'retweet') {
output.retweeted_status = parseStatus(data.retweeted_status)
}
2019-01-17 20:22:51 +00:00
output.summary = data.summary
output.summary_html = data.summary_html
2019-01-17 20:44:31 +00:00
output.external_url = data.external_url
output.is_local = data.is_local
}
output.id = String(data.id)
output.visibility = data.visibility
output.card = data.card
output.created_at = new Date(data.created_at)
// Converting to string, the right way.
output.in_reply_to_status_id = output.in_reply_to_status_id
? String(output.in_reply_to_status_id)
: null
output.in_reply_to_user_id = output.in_reply_to_user_id
? String(output.in_reply_to_user_id)
: null
output.user = parseUser(masto ? data.account : data.user)
output.attentions = ((masto ? data.mentions : data.attentions) || []).map(parseUser)
output.attachments = ((masto ? data.media_attachments : data.attachments) || [])
.map(parseAttachment)
const retweetedStatus = masto ? data.reblog : data.retweeted_status
if (retweetedStatus) {
output.retweeted_status = parseStatus(retweetedStatus)
}
return output
}
2019-03-17 14:08:01 +00:00
// This is for masto API only.
2019-03-12 21:16:57 +00:00
export const parseFollow = (data) => {
const output = {}
output.id = String(data.id)
output.visibility = true
output.created_at = new Date(data.created_at)
output.user = parseUser(data.account)
2019-03-18 18:42:09 +00:00
output.notified_at = output.created_at
output.account = output.user
2019-03-12 21:16:57 +00:00
return output
}
export const parseNotification = (data) => {
const mastoDict = {
'favourite': 'like',
'reblog': 'repeat'
}
const masto = !data.hasOwnProperty('ntype')
const output = {}
if (masto) {
output.type = mastoDict[data.type] || data.type
2019-03-18 16:30:34 +00:00
output.seen = data.pleroma.is_seen
2019-03-12 21:16:57 +00:00
output.status = output.type === 'follow'
? parseFollow(data)
: parseStatus(data.status)
if (data.type === 'reblog' || data.type === 'favourite') {
2019-03-13 19:34:45 +00:00
output.status.user = parseUser(data.account)
2019-03-18 18:42:09 +00:00
output.status.account = parseUser(data.account)
output.status.notified_at = new Date(data.created_at)
2019-03-13 19:34:45 +00:00
}
output.action = output.status // not sure
output.from_profile = parseUser(data.account)
} else {
const parsedNotice = parseStatus(data.notice)
output.type = data.ntype
output.seen = Boolean(data.is_seen)
output.status = output.type === 'like'
? parseStatus(data.notice.favorited_status)
: parsedNotice
output.action = parsedNotice
output.from_profile = parseUser(data.from_profile)
}
output.created_at = new Date(data.created_at)
output.id = data.id
return output
}
const isNsfw = (status) => {
const nsfwRegex = /#nsfw/i
return (status.tags || []).includes('nsfw') || !!(status.text || '').match(nsfwRegex)
}