mirror of
https://git.stupid.fish/teidesu/scripts.git
synced 2025-07-28 02:32:11 +10:00
chore: update public repo
This commit is contained in:
parent
9891d7734d
commit
2423324540
8 changed files with 531 additions and 0 deletions
|
@ -17,3 +17,7 @@ export async function directoryExists(path: string): Promise<boolean> {
|
|||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export function sanitizeFilename(filename: string) {
|
||||
return filename.replace(/[/\\?%*:|"<>]/g, '_')
|
||||
}
|
||||
|
|
|
@ -8,3 +8,9 @@ export function getEnv<T>(key: string, parser?: (value: string) => T): T | strin
|
|||
if (!parser) return value
|
||||
return parser(value)
|
||||
}
|
||||
|
||||
export function* chunks<T>(arr: T[], size: number) {
|
||||
for (let i = 0; i < arr.length; i += size) {
|
||||
yield arr.slice(i, i + size)
|
||||
}
|
||||
}
|
||||
|
|
30
utils/opus.ts
Normal file
30
utils/opus.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { Bytes, write } from '@fuman/io'
|
||||
import { $ } from 'zx'
|
||||
|
||||
export async function generateOpusImageBlob(image: Uint8Array) {
|
||||
// todo we should probably not use ffprobe here but whatever lol
|
||||
const proc = $`ffprobe -of json -v error -show_entries stream=codec_name,width,height pipe:0`
|
||||
proc.stdin.write(image)
|
||||
proc.stdin.end()
|
||||
const json = await proc.json()
|
||||
|
||||
const img = json.streams[0]
|
||||
// https://www.rfc-editor.org/rfc/rfc9639.html#section-8.8
|
||||
const mime = img.codec_name === 'mjpeg' ? 'image/jpeg' : 'image/png'
|
||||
const description = 'Cover Artwork'
|
||||
|
||||
const res = Bytes.alloc(image.length + 128)
|
||||
write.uint32be(res, 3) // picture type = album cover
|
||||
write.uint32be(res, mime.length)
|
||||
write.rawString(res, mime)
|
||||
write.uint32be(res, description.length)
|
||||
write.rawString(res, description)
|
||||
write.uint32be(res, img.width)
|
||||
write.uint32be(res, img.height)
|
||||
write.uint32be(res, 0) // color depth
|
||||
write.uint32be(res, 0) // color index (unused, for gifs)
|
||||
write.uint32be(res, image.length)
|
||||
write.bytes(res, image)
|
||||
|
||||
return res.result()
|
||||
}
|
54
utils/strings.ts
Normal file
54
utils/strings.ts
Normal file
|
@ -0,0 +1,54 @@
|
|||
export function parseJsObject(str: string, offset = 0) {
|
||||
let i = offset
|
||||
const len = str.length
|
||||
let start = -1
|
||||
let end = -1
|
||||
|
||||
const depth = {
|
||||
'{': 0,
|
||||
'[': 0,
|
||||
}
|
||||
|
||||
const possibleQuotes = {
|
||||
'"': true,
|
||||
'\'': true,
|
||||
'`': true,
|
||||
}
|
||||
let inQuote: string | null = null
|
||||
let escapeNextQuote = false
|
||||
|
||||
while (i < len) {
|
||||
const char = str[i]
|
||||
if (char in possibleQuotes && !escapeNextQuote) {
|
||||
if (inQuote === null) {
|
||||
inQuote = char
|
||||
} else if (char === inQuote) {
|
||||
inQuote = null
|
||||
}
|
||||
} else if (inQuote != null) {
|
||||
escapeNextQuote = char === '\\' && !escapeNextQuote
|
||||
} else if (inQuote == null && char in depth) {
|
||||
if (start === -1) {
|
||||
start = i
|
||||
}
|
||||
depth[char] += 1
|
||||
} else if (inQuote == null && (
|
||||
char === '}' || char === ']'
|
||||
)) {
|
||||
if (char === '}') depth['{'] -= 1
|
||||
if (char === ']') depth['['] -= 1
|
||||
|
||||
if (depth['{'] === 0 && depth['['] === 0) {
|
||||
end = i + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
|
||||
if (start === -1 && end === -1) return null
|
||||
if (depth['{'] !== 0 || depth['['] !== 0) throw new SyntaxError('Mismatched brackets')
|
||||
if (inQuote) throw new SyntaxError('Unclosed string')
|
||||
|
||||
return str.substring(start, end)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue