Auto-detect mimetype from file's content

This commit is contained in:
Elizabeth Cray 2025-01-31 23:30:38 -05:00
parent db6bf23fb5
commit 5487f633a4
3 changed files with 151 additions and 6 deletions

View File

@ -22,6 +22,7 @@ import { htmlToText } from "html-to-text";
import axios from "axios"; import axios from "axios";
import { AtpAgent, RichText } from '@atproto/api' import { AtpAgent, RichText } from '@atproto/api'
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
import { fileTypeFromBuffer } from 'file-type';
const historyFile = process.env.HISTORY_FILE || '.history'; const historyFile = process.env.HISTORY_FILE || '.history';
let history = []; let history = [];
@ -90,12 +91,14 @@ if (existsSync(historyFile)){
const bskyPost = async (text, media = []) => { const bskyPost = async (text, media = []) => {
let uploadedMedia = []; let uploadedMedia = [];
for (let m of media){ for (let m of media){
let mime = `${m.url}`.split('.').pop(); // let mime = `${m.url}`.split('.').pop();
mime = mime.toLowerCase(); // mime = mime.toLowerCase();
mime = mime === 'jpg'?'jpeg':mime; // mime = mime === 'jpg'?'jpeg':mime;
const fileBuffer = Buffer.from(readFileSync(m.data)); const fileBuffer = Buffer.from(readFileSync(m.data));
const { ext, mimeT } = await fileTypeFromBuffer(fileBuffer);
let uploadResult = await bsky.uploadBlob(fileBuffer, { let uploadResult = await bsky.uploadBlob(fileBuffer, {
encoding: `image/${mime}` // encoding: `image/${mime}`
encoding: mimeT
}); });
if (uploadResult.success){ if (uploadResult.success){
uploadedMedia.push({ uploadedMedia.push({
@ -117,7 +120,6 @@ const bskyPost = async (text, media = []) => {
createdAt: new Date().toISOString() createdAt: new Date().toISOString()
}; };
if (uploadedMedia.length > 0){ if (uploadedMedia.length > 0){
// TODO: Add aspect ratio to images
post.embed = { post.embed = {
"$type": "app.bsky.embed.images", "$type": "app.bsky.embed.images",
images: uploadedMedia images: uploadedMedia
@ -191,7 +193,9 @@ client.get(`/accounts/${process.env.MASTODON_ID}/statuses`, {
} }
}else{ }else{
// is boosted post // is boosted post
// TODO: Handle boosts let text = status.reblog.url;
bskyPost(text, []);
appendFileSync(historyFile, `\n${status.id}`);
} }
} }
} }

140
package-lock.json generated
View File

@ -12,6 +12,7 @@
"@atproto/api": "^0.13.31", "@atproto/api": "^0.13.31",
"axios": "^1.7.9", "axios": "^1.7.9",
"dotenv": "^16.4.7", "dotenv": "^16.4.7",
"file-type": "^20.0.1",
"html-to-text": "^9.0.5", "html-to-text": "^9.0.5",
"mastodon-api": "^1.3.0", "mastodon-api": "^1.3.0",
"string-replace-async": "^3.0.2", "string-replace-async": "^3.0.2",
@ -82,6 +83,49 @@
"url": "https://ko-fi.com/killymxi" "url": "https://ko-fi.com/killymxi"
} }
}, },
"node_modules/@tokenizer/inflate": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.2.6.tgz",
"integrity": "sha512-SdR/i05U7Xhnsq36iyIq/ZiGGw4PKzw4ww3bOq80Pjj4wyXpqyTcgrgdDdGlcatnlvzNJx8CQw3hp6QZvkUwhA==",
"dependencies": {
"debug": "^4.3.7",
"fflate": "^0.8.2",
"token-types": "^6.0.0"
},
"engines": {
"node": ">=16"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Borewit"
}
},
"node_modules/@tokenizer/inflate/node_modules/debug": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/@tokenizer/inflate/node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/@tokenizer/token": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="
},
"node_modules/acorn": { "node_modules/acorn": {
"version": "5.7.4", "version": "5.7.4",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz",
@ -1043,6 +1087,11 @@
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
}, },
"node_modules/fflate": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
"integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="
},
"node_modules/figures": { "node_modules/figures": {
"version": "1.7.0", "version": "1.7.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
@ -1067,6 +1116,23 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/file-type": {
"version": "20.0.1",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-20.0.1.tgz",
"integrity": "sha512-R80W+NZ+s1M8PsC8L7xn+J0N72vEyxstMH+4vwIyt5B7ojfG80h/nKu2Qw/NYJTIYyGUeaPNLnzfJd78SWnG3A==",
"dependencies": {
"@tokenizer/inflate": "^0.2.6",
"strtok3": "^10.2.0",
"token-types": "^6.0.0",
"uint8array-extras": "^1.4.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sindresorhus/file-type?sponsor=1"
}
},
"node_modules/flat-cache": { "node_modules/flat-cache": {
"version": "1.3.4", "version": "1.3.4",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz",
@ -1434,6 +1500,25 @@
"npm": ">=1.3.7" "npm": ">=1.3.7"
} }
}, },
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/ignore": { "node_modules/ignore": {
"version": "3.3.10", "version": "3.3.10",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
@ -2012,6 +2097,18 @@
"url": "https://ko-fi.com/killymxi" "url": "https://ko-fi.com/killymxi"
} }
}, },
"node_modules/peek-readable": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-6.1.0.tgz",
"integrity": "sha512-1H5ECS+rPH35Foh4JD/XohQKWsx6Jzn37ESOVTFuCSoI8wMB9r2e2aDSLgHSiyucVrPfoc0DRiipBEP1gr9wLw==",
"engines": {
"node": ">=18"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Borewit"
}
},
"node_modules/performance-now": { "node_modules/performance-now": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@ -2399,6 +2496,22 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/strtok3": {
"version": "10.2.0",
"resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.2.0.tgz",
"integrity": "sha512-S884oIGzokq3LkL/6jXw5c5oJXRiGt4jB42cuWdaooJdxFMSn99snaShh3cQmJx3jALV2eoyW3rV/TJxwOaBPA==",
"dependencies": {
"@tokenizer/token": "^0.3.0",
"peek-readable": "^6.1.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Borewit"
}
},
"node_modules/supports-color": { "node_modules/supports-color": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
@ -2514,6 +2627,22 @@
"tlds": "bin.js" "tlds": "bin.js"
} }
}, },
"node_modules/token-types": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/token-types/-/token-types-6.0.0.tgz",
"integrity": "sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==",
"dependencies": {
"@tokenizer/token": "^0.3.0",
"ieee754": "^1.2.1"
},
"engines": {
"node": ">=14.16"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Borewit"
}
},
"node_modules/tough-cookie": { "node_modules/tough-cookie": {
"version": "2.5.0", "version": "2.5.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
@ -2563,6 +2692,17 @@
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
"integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="
}, },
"node_modules/uint8array-extras": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.4.0.tgz",
"integrity": "sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/uint8arrays": { "node_modules/uint8arrays": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.0.0.tgz", "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.0.0.tgz",

View File

@ -16,6 +16,7 @@
"@atproto/api": "^0.13.31", "@atproto/api": "^0.13.31",
"axios": "^1.7.9", "axios": "^1.7.9",
"dotenv": "^16.4.7", "dotenv": "^16.4.7",
"file-type": "^20.0.1",
"html-to-text": "^9.0.5", "html-to-text": "^9.0.5",
"mastodon-api": "^1.3.0", "mastodon-api": "^1.3.0",
"string-replace-async": "^3.0.2", "string-replace-async": "^3.0.2",