forked from cadence/out-of-your-element
Add new WHERE feature to my funny orm
This commit is contained in:
parent
28abdac5b6
commit
475cd5b724
30 changed files with 149 additions and 105 deletions
|
@ -14,9 +14,9 @@ const emoji = sync.require("../converters/emoji")
|
|||
* @param {Ty.Event.Outer<Ty.Event.M_Reaction>} event
|
||||
*/
|
||||
async function addReaction(event) {
|
||||
const channelID = select("channel_room", "channel_id", "WHERE room_id = ?").pluck().get(event.room_id)
|
||||
const channelID = select("channel_room", "channel_id", {room_id: event.room_id}).pluck().get()
|
||||
if (!channelID) return // We just assume the bridge has already been created
|
||||
const messageID = select("event_message", "message_id", "WHERE event_id = ? AND part = 0").pluck().get(event.content["m.relates_to"].event_id) // 0 = primary
|
||||
const messageID = select("event_message", "message_id", {event_id: event.content["m.relates_to"].event_id, part: 0}).pluck().get() // 0 = primary
|
||||
if (!messageID) return // Nothing can be done if the parent message was never bridged.
|
||||
|
||||
const key = event.content["m.relates_to"].key // TODO: handle custom text or emoji reactions
|
||||
|
|
|
@ -14,7 +14,7 @@ const {discord, db, select} = passthrough
|
|||
*/
|
||||
async function ensureWebhook(channelID, forceCreate = false) {
|
||||
if (!forceCreate) {
|
||||
const row = select("webhook", ["webhook_id", "webhook_token"], "WHERE channel_id = ?").get(channelID)
|
||||
const row = select("webhook", ["webhook_id", "webhook_token"], {channel_id: channelID}).get()
|
||||
if (row) {
|
||||
return {
|
||||
id: row.webhook_id,
|
||||
|
|
|
@ -12,7 +12,7 @@ const utils = sync.require("../converters/utils")
|
|||
* @param {Ty.Event.Outer_M_Room_Redaction} event
|
||||
*/
|
||||
async function deleteMessage(event) {
|
||||
const rows = from("event_message").join("message_channel", "message_id").select("channel_id", "message_id").and("WHERE event_id = ?").all(event.redacts)
|
||||
const rows = from("event_message").join("message_channel", "message_id").select("channel_id", "message_id").where({event_id: event.redacts}).all()
|
||||
for (const row of rows) {
|
||||
discord.snow.channel.deleteMessage(row.channel_id, row.message_id, event.content.reason)
|
||||
}
|
||||
|
@ -23,7 +23,8 @@ async function deleteMessage(event) {
|
|||
*/
|
||||
async function removeReaction(event) {
|
||||
const hash = utils.getEventIDHash(event.redacts)
|
||||
const row = from("reaction").join("message_channel", "message_id").select("channel_id", "message_id", "encoded_emoji").and("WHERE hashed_event_id = ?").get(hash)
|
||||
// TODO: this works but fix the type
|
||||
const row = from("reaction").join("message_channel", "message_id").select("channel_id", "message_id", "encoded_emoji").where({hashed_event_id: hash}).get()
|
||||
if (!row) return
|
||||
await discord.snow.channel.deleteReactionSelf(row.channel_id, row.message_id, row.encoded_emoji)
|
||||
db.prepare("DELETE FROM reaction WHERE hashed_event_id = ?").run(hash)
|
||||
|
|
|
@ -58,7 +58,7 @@ async function resolvePendingFiles(message) {
|
|||
|
||||
/** @param {Ty.Event.Outer_M_Room_Message | Ty.Event.Outer_M_Room_Message_File | Ty.Event.Outer_M_Sticker} event */
|
||||
async function sendEvent(event) {
|
||||
const row = select("channel_room", ["channel_id", "thread_parent"], "WHERE room_id = ?").get(event.room_id)
|
||||
const row = select("channel_room", ["channel_id", "thread_parent"], {room_id: event.room_id}).get()
|
||||
if (!row) return // allow the bot to exist in unbridged rooms, just don't do anything with it
|
||||
let channelID = row.channel_id
|
||||
let threadID = undefined
|
||||
|
|
|
@ -7,19 +7,19 @@ const passthrough = require("../../passthrough")
|
|||
const {sync, select} = passthrough
|
||||
|
||||
/**
|
||||
* @param {string} emoji
|
||||
* @param {string} input
|
||||
* @param {string | null | undefined} shortcode
|
||||
* @returns {string?}
|
||||
*/
|
||||
function encodeEmoji(emoji, shortcode) {
|
||||
function encodeEmoji(input, shortcode) {
|
||||
let discordPreferredEncoding
|
||||
if (emoji.startsWith("mxc://")) {
|
||||
if (input.startsWith("mxc://")) {
|
||||
// Custom emoji
|
||||
let row = select("emoji", ["id", "name"], "WHERE mxc_url = ?").get(emoji)
|
||||
let row = select("emoji", ["emoji_id", "name"], {mxc_url: input}).get()
|
||||
if (!row && shortcode) {
|
||||
// Use the name to try to find a known emoji with the same name.
|
||||
const name = shortcode.replace(/^:|:$/g, "")
|
||||
row = select("emoji", ["id", "name"], "WHERE name = ?").get(name)
|
||||
row = select("emoji", ["emoji_id", "name"], {name: name}).get()
|
||||
}
|
||||
if (!row) {
|
||||
// We don't have this emoji and there's no realistic way to just-in-time upload a new emoji somewhere.
|
||||
|
@ -27,11 +27,11 @@ function encodeEmoji(emoji, shortcode) {
|
|||
return null
|
||||
}
|
||||
// Cool, we got an exact or a candidate emoji.
|
||||
discordPreferredEncoding = encodeURIComponent(`${row.name}:${row.id}`)
|
||||
discordPreferredEncoding = encodeURIComponent(`${row.name}:${row.emoji_id}`)
|
||||
} else {
|
||||
// Default emoji
|
||||
// https://github.com/discord/discord-api-docs/issues/2723#issuecomment-807022205 ????????????
|
||||
const encoded = encodeURIComponent(emoji)
|
||||
const encoded = encodeURIComponent(input)
|
||||
const encodedTrimmed = encoded.replace(/%EF%B8%8F/g, "")
|
||||
|
||||
const forceTrimmedList = [
|
||||
|
@ -42,10 +42,10 @@ function encodeEmoji(emoji, shortcode) {
|
|||
|
||||
discordPreferredEncoding =
|
||||
( forceTrimmedList.includes(encodedTrimmed) ? encodedTrimmed
|
||||
: encodedTrimmed !== encoded && [...emoji].length === 2 ? encoded
|
||||
: encodedTrimmed !== encoded && [...input].length === 2 ? encoded
|
||||
: encodedTrimmed)
|
||||
|
||||
console.log("add reaction from matrix:", emoji, encoded, encodedTrimmed, "chosen:", discordPreferredEncoding)
|
||||
console.log("add reaction from matrix:", input, encoded, encodedTrimmed, "chosen:", discordPreferredEncoding)
|
||||
}
|
||||
return discordPreferredEncoding
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ turndownService.addRule("emoji", {
|
|||
replacement: function (content, node) {
|
||||
const mxcUrl = node.getAttribute("src")
|
||||
// Get the known emoji from the database. (We may not be able to actually use this if it was from another server.)
|
||||
const row = select("emoji", ["id", "name", "animated"], "WHERE mxc_url = ?").get(mxcUrl)
|
||||
const row = select("emoji", ["emoji_id", "name", "animated"], {mxc_url: mxcUrl}).get()
|
||||
// Also guess a suitable emoji based on the ID (if available) or name
|
||||
let guess = null
|
||||
const guessedName = node.getAttribute("title").replace(/^:|:$/g, "")
|
||||
|
@ -129,7 +129,7 @@ turndownService.addRule("emoji", {
|
|||
/** @type {{name: string, id: string, animated: number}[]} */
|
||||
// @ts-ignore
|
||||
const emojis = guild.emojis
|
||||
const match = emojis.find(e => e.id === row?.id) || emojis.find(e => e.name === guessedName) || emojis.find(e => e.name?.toLowerCase() === guessedName.toLowerCase())
|
||||
const match = emojis.find(e => e.id === row?.emoji_id) || emojis.find(e => e.name === guessedName) || emojis.find(e => e.name?.toLowerCase() === guessedName.toLowerCase())
|
||||
if (match) {
|
||||
guess = match
|
||||
break
|
||||
|
@ -180,7 +180,7 @@ turndownService.addRule("fencedCodeBlock", {
|
|||
* @returns {Promise<{displayname?: string?, avatar_url?: string?}>}
|
||||
*/
|
||||
async function getMemberFromCacheOrHomeserver(roomID, mxid, api) {
|
||||
const row = select("member_cache", ["displayname", "avatar_url"], "WHERE room_id = ? AND mxid = ?").get(roomID, mxid)
|
||||
const row = select("member_cache", ["displayname", "avatar_url"], {room_id: roomID, mxid}).get()
|
||||
if (row) return row
|
||||
return api.getStateEvent(roomID, "m.room.member", mxid).then(event => {
|
||||
db.prepare("REPLACE INTO member_cache (room_id, mxid, displayname, avatar_url) VALUES (?, ?, ?, ?)").run(roomID, mxid, event?.displayname || null, event?.avatar_url || null)
|
||||
|
@ -285,7 +285,7 @@ async function eventToMessage(event, guild, di) {
|
|||
if (relType !== "m.replace") return
|
||||
const originalEventId = relatesTo.event_id
|
||||
if (!originalEventId) return
|
||||
messageIDsToEdit = select("event_message", "message_id", "WHERE event_id = ? ORDER BY part").pluck().all(originalEventId)
|
||||
messageIDsToEdit = select("event_message", "message_id", {event_id: originalEventId}, "ORDER BY part").pluck().all()
|
||||
if (!messageIDsToEdit.length) return
|
||||
|
||||
// Ok, it's an edit.
|
||||
|
@ -316,7 +316,7 @@ async function eventToMessage(event, guild, di) {
|
|||
if (!repliedToEventId) return
|
||||
let repliedToEvent = await di.api.getEvent(event.room_id, repliedToEventId)
|
||||
if (!repliedToEvent) return
|
||||
const row = from("event_message").join("message_channel", "message_id").select("channel_id", "message_id").and("WHERE event_id = ? ORDER BY part").get(repliedToEventId)
|
||||
const row = from("event_message").join("message_channel", "message_id").select("channel_id", "message_id").where({event_id: repliedToEventId}).and("ORDER BY part").get()
|
||||
if (row) {
|
||||
replyLine = `<:L1:1144820033948762203><:L2:1144820084079087647>https://discord.com/channels/${guild.id}/${row.channel_id}/${row.message_id} `
|
||||
} else {
|
||||
|
@ -324,7 +324,7 @@ async function eventToMessage(event, guild, di) {
|
|||
}
|
||||
const sender = repliedToEvent.sender
|
||||
const senderName = sender.match(/@([^:]*)/)?.[1] || sender
|
||||
const authorID = select("sim", "user_id", "WHERE mxid = ?").pluck().get(repliedToEvent.sender)
|
||||
const authorID = select("sim", "user_id", {mxid: repliedToEvent.sender}).pluck().get()
|
||||
if (authorID) {
|
||||
replyLine += `<@${authorID}>`
|
||||
} else {
|
||||
|
@ -367,14 +367,14 @@ async function eventToMessage(event, guild, di) {
|
|||
// Handling mentions of Discord users
|
||||
input = input.replace(/("https:\/\/matrix.to\/#\/(@[^"]+)")>/g, (whole, attributeValue, mxid) => {
|
||||
if (!utils.eventSenderIsFromDiscord(mxid)) return whole
|
||||
const userID = select("sim", "user_id", "WHERE mxid = ?").pluck().get(mxid)
|
||||
const userID = select("sim", "user_id", {mxid: mxid}).pluck().get()
|
||||
if (!userID) return whole
|
||||
return `${attributeValue} data-user-id="${userID}">`
|
||||
})
|
||||
|
||||
// Handling mentions of Discord rooms
|
||||
input = input.replace(/("https:\/\/matrix.to\/#\/(![^"]+)")>/g, (whole, attributeValue, roomID) => {
|
||||
const channelID = select("channel_room", "channel_id", "WHERE room_id = ?").pluck().get(roomID)
|
||||
const channelID = select("channel_room", "channel_id", {room_id: roomID}).pluck().get()
|
||||
if (!channelID) return whole
|
||||
return `${attributeValue} data-channel-id="${channelID}">`
|
||||
})
|
||||
|
|
|
@ -1508,7 +1508,7 @@ test("event2message: caches the member if the member is not known", async t => {
|
|||
}
|
||||
)
|
||||
|
||||
t.deepEqual(select("member_cache", ["avatar_url", "displayname", "mxid"], "WHERE room_id = '!should_be_newly_cached:cadence.moe'").all(), [
|
||||
t.deepEqual(select("member_cache", ["avatar_url", "displayname", "mxid"], {room_id: "!should_be_newly_cached:cadence.moe"}).all(), [
|
||||
{avatar_url: "mxc://cadence.moe/this_is_the_avatar", displayname: null, mxid: "@should_be_newly_cached:cadence.moe"}
|
||||
])
|
||||
t.equal(called, 1, "getStateEvent should be called once")
|
||||
|
@ -1551,7 +1551,7 @@ test("event2message: skips caching the member if the member does not exist, some
|
|||
}]
|
||||
}
|
||||
)
|
||||
t.deepEqual(select("member_cache", ["avatar_url", "displayname", "mxid"], "WHERE room_id = '!not_real:cadence.moe'").all(), [])
|
||||
t.deepEqual(select("member_cache", ["avatar_url", "displayname", "mxid"], {room_id: "!not_real:cadence.moe"}).all(), [])
|
||||
t.equal(called, 1, "getStateEvent should be called once")
|
||||
})
|
||||
|
||||
|
@ -1594,7 +1594,7 @@ test("event2message: overly long usernames are shifted into the message content"
|
|||
}]
|
||||
}
|
||||
)
|
||||
t.deepEqual(select("member_cache", ["avatar_url", "displayname", "mxid"], "WHERE room_id = '!should_be_newly_cached_2:cadence.moe'").all(), [
|
||||
t.deepEqual(select("member_cache", ["avatar_url", "displayname", "mxid"], {room_id: "!should_be_newly_cached_2:cadence.moe"}).all(), [
|
||||
{avatar_url: null, displayname: "I am BLACK I am WHITE I am SHORT I am LONG I am EVERYTHING YOU THINK IS IMPORTANT and I DON'T MATTER", mxid: "@should_be_newly_cached_2:cadence.moe"}
|
||||
])
|
||||
t.equal(called, 1, "getStateEvent should be called once")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue