Compare commits
No commits in common. "0b5475e9a82cc8c2700516e05f93372bb19ee7b0" and "044ccc08e06f11b48e16c7f7637d3c088008119a" have entirely different histories.
0b5475e9a8
...
044ccc08e0
6 changed files with 23 additions and 52 deletions
|
@ -68,7 +68,7 @@ function convertNameAndTopic(channel, guild, customName) {
|
|||
* @param {DiscordTypes.APIGuild} guild
|
||||
*/
|
||||
async function channelToKState(channel, guild) {
|
||||
const spaceID = await createSpace.ensureSpace(guild)
|
||||
const spaceID = await createSpace.ensureSpace(guild.id)
|
||||
assert.ok(typeof spaceID === "string")
|
||||
|
||||
const row = select("channel_room", ["nick", "custom_avatar"], "WHERE channel_id = ?").get(channel.id)
|
||||
|
|
|
@ -74,28 +74,30 @@ async function guildToKState(guild) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {DiscordTypes.APIGuild} guild
|
||||
* @param {string} guildID
|
||||
* @param {boolean} shouldActuallySync false if just need to ensure nspace exists (which is a quick database check),
|
||||
* true if also want to efficiently sync space name, space avatar, and child room avatars
|
||||
* @returns {Promise<string>} room ID
|
||||
*/
|
||||
async function _syncSpace(guild, shouldActuallySync) {
|
||||
async function _syncSpace(guildID, shouldActuallySync) {
|
||||
/** @ts-ignore @type {DiscordTypes.APIGuild} */
|
||||
const guild = discord.guilds.get(guildID)
|
||||
assert.ok(guild)
|
||||
|
||||
if (inflightSpaceCreate.has(guild.id)) {
|
||||
await inflightSpaceCreate.get(guild.id) // just waiting, and then doing a new db query afterwards, is the simplest way of doing it
|
||||
if (inflightSpaceCreate.has(guildID)) {
|
||||
await inflightSpaceCreate.get(guildID) // just waiting, and then doing a new db query afterwards, is the simplest way of doing it
|
||||
}
|
||||
|
||||
const spaceID = select("guild_space", "space_id", "WHERE guild_id = ?").pluck().get(guild.id)
|
||||
const spaceID = select("guild_space", "space_id", "WHERE guild_id = ?").pluck().get(guildID)
|
||||
|
||||
if (!spaceID) {
|
||||
const creation = (async () => {
|
||||
const guildKState = await guildToKState(guild)
|
||||
const spaceID = await createSpace(guild, guildKState)
|
||||
inflightSpaceCreate.delete(guild.id)
|
||||
inflightSpaceCreate.delete(guildID)
|
||||
return spaceID
|
||||
})()
|
||||
inflightSpaceCreate.set(guild.id, creation)
|
||||
inflightSpaceCreate.set(guildID, creation)
|
||||
return creation // Naturally, the newly created space is already up to date, so we can always skip syncing here.
|
||||
}
|
||||
|
||||
|
@ -134,20 +136,14 @@ async function _syncSpace(guild, shouldActuallySync) {
|
|||
return spaceID
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the space exists. If it doesn't, creates the space with an accurate initial state.
|
||||
* @param {DiscordTypes.APIGuild} guild
|
||||
*/
|
||||
function ensureSpace(guild) {
|
||||
return _syncSpace(guild, false)
|
||||
/** Ensures the space exists. If it doesn't, creates the space with an accurate initial state. */
|
||||
function ensureSpace(guildID) {
|
||||
return _syncSpace(guildID, false)
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually syncs. Efficiently updates the space name, space avatar, and child room avatars.
|
||||
* @param {DiscordTypes.APIGuild} guild
|
||||
*/
|
||||
function syncSpace(guild) {
|
||||
return _syncSpace(guild, true)
|
||||
/** Actually syncs. Efficiently updates the space name, space avatar, and child room avatars. */
|
||||
function syncSpace(guildID) {
|
||||
return _syncSpace(guildID, true)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -119,7 +119,7 @@ async function memberToStateContent(user, member, guildID) {
|
|||
return content
|
||||
}
|
||||
|
||||
function hashProfileContent(content) {
|
||||
function calculateProfileEventContentHash(content) {
|
||||
return `${content.displayname}\u0000${content.avatar_url}`
|
||||
}
|
||||
|
||||
|
@ -136,12 +136,12 @@ function hashProfileContent(content) {
|
|||
async function syncUser(user, member, guildID, roomID) {
|
||||
const mxid = await ensureSimJoined(user, roomID)
|
||||
const content = await memberToStateContent(user, member, guildID)
|
||||
const currentHash = hashProfileContent(content)
|
||||
const profileEventContentHash = calculateProfileEventContentHash(content)
|
||||
const existingHash = select("sim_member", "profile_event_content_hash", "WHERE room_id = ? AND mxid = ?").pluck().get(roomID, mxid)
|
||||
// only do the actual sync if the hash has changed since we last looked
|
||||
if (existingHash !== currentHash) {
|
||||
if (existingHash !== profileEventContentHash) {
|
||||
await api.sendState(roomID, "m.room.member", mxid, content, mxid)
|
||||
db.prepare("UPDATE sim_member SET profile_event_content_hash = ? WHERE room_id = ? AND mxid = ?").run(currentHash, roomID, mxid)
|
||||
db.prepare("UPDATE sim_member SET profile_event_content_hash = ? WHERE room_id = ? AND mxid = ?").run(profileEventContentHash, roomID, mxid)
|
||||
}
|
||||
return mxid
|
||||
}
|
||||
|
|
|
@ -167,31 +167,6 @@ async function messageToEvent(message, guild, options = {}, di) {
|
|||
escapeHTML: false,
|
||||
}, null, null)
|
||||
|
||||
for (const embed of message.embeds || []) {
|
||||
// Start building up a replica ("rep") of the embed in Discord-markdown format, which we will convert into both plaintext and formatted body at once
|
||||
let repParagraphs = []
|
||||
if (embed.author?.name) repParagraphs.push(`**${embed.author.name}**`)
|
||||
if (embed.title && embed.url) repParagraphs.push(`[**${embed.title}**](${embed.url})`)
|
||||
else if (embed.title) repParagraphs.push(`**${embed.title}**`)
|
||||
else if (embed.url) repParagraphs.push(`**${embed.url}**`)
|
||||
if (embed.description) repParagraphs.push(embed.description)
|
||||
for (const field of embed.fields || []) {
|
||||
repParagraphs.push(`**${field.name}**\n${field.value}`)
|
||||
}
|
||||
if (embed.footer?.text) repParagraphs.push(embed.footer.text)
|
||||
const repContent = repParagraphs.join("\n\n")
|
||||
|
||||
html += "<blockquote>" + markdown.toHTML(repContent, {
|
||||
discordCallback: getDiscordParseCallbacks(message, true)
|
||||
}, null, null) + "</blockquote>"
|
||||
|
||||
body += "\n\n" + markdown.toHTML(repContent, {
|
||||
discordCallback: getDiscordParseCallbacks(message, false),
|
||||
discordOnly: true,
|
||||
escapeHTML: false
|
||||
}, null, null)
|
||||
}
|
||||
|
||||
// Mentions scenario 3: scan the message content for written @mentions of matrix users. Allows for up to one space between @ and mention.
|
||||
const matches = [...content.matchAll(/@ ?([a-z0-9._]+)\b/gi)]
|
||||
if (matches.length && matches.some(m => m[1].match(/[a-z]/i))) {
|
||||
|
|
|
@ -140,7 +140,7 @@ module.exports = {
|
|||
async onGuildUpdate(client, guild) {
|
||||
const spaceID = select("guild_space", "space_id", "WHERE guild_id = ?").pluck().get(guild.id)
|
||||
if (!spaceID) return
|
||||
await createSpace.syncSpace(guild)
|
||||
await createSpace.syncSpace(guild.id)
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -66,7 +66,7 @@ async function migrateGuild(guild) {
|
|||
console.log(`START MIGRATION of ${guild.name} (${guild.id})`)
|
||||
|
||||
// Step 1: Create a new space for the guild (createSpace)
|
||||
const spaceID = await createSpace.syncSpace(guild)
|
||||
const spaceID = await createSpace.syncSpace(guild.id)
|
||||
|
||||
let oldRooms = oldDB.prepare("SELECT matrix_id, discord_guild, discord_channel FROM room_entries INNER JOIN remote_room_data ON remote_id = room_id WHERE discord_guild = ?").all(guild.id)
|
||||
const migrated = db.prepare("SELECT discord_channel FROM migration WHERE migrated = 1").pluck().all()
|
||||
|
@ -132,6 +132,6 @@ async function migrateGuild(guild) {
|
|||
}
|
||||
|
||||
// Step 5: Call syncSpace to make sure everything is up to date
|
||||
await createSpace.syncSpace(guild)
|
||||
await createSpace.syncSpace(guild.id)
|
||||
console.log(`Finished migrating ${guild.name} to Out Of Your Element`)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue