요즘 AI가 유행이죠? 저도 알아요요
This commit is contained in:
parent
8399ce4107
commit
0017a3eb16
6 changed files with 122 additions and 15 deletions
35
app/bun.lock
35
app/bun.lock
|
|
@ -4,6 +4,9 @@
|
||||||
"": {
|
"": {
|
||||||
"name": "app",
|
"name": "app",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@azure-rest/ai-inference": "^1.0.0-beta.6",
|
||||||
|
"@azure/core-auth": "^1.9.0",
|
||||||
|
"@azure/core-sse": "^2.2.0",
|
||||||
"@napi-rs/canvas": "^0.1.70",
|
"@napi-rs/canvas": "^0.1.70",
|
||||||
"cheerio": "^1.0.0",
|
"cheerio": "^1.0.0",
|
||||||
"igramapi": "^1.48.3",
|
"igramapi": "^1.48.3",
|
||||||
|
|
@ -18,6 +21,26 @@
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"packages": {
|
"packages": {
|
||||||
|
"@azure-rest/ai-inference": ["@azure-rest/ai-inference@1.0.0-beta.6", "", { "dependencies": { "@azure-rest/core-client": "^2.1.0", "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.9.0", "@azure/core-lro": "^2.7.2", "@azure/core-rest-pipeline": "^1.18.2", "@azure/core-tracing": "^1.2.0", "@azure/logger": "^1.1.4", "tslib": "^2.8.1" } }, "sha512-j5FrJDTHu2P2+zwFVe5j2edasOIhqkFj+VkDjbhGkQuOoIAByF0egRkgs0G1k03HyJ7bOOT9BkRF7MIgr/afhw=="],
|
||||||
|
|
||||||
|
"@azure-rest/core-client": ["@azure-rest/core-client@2.4.0", "", { "dependencies": { "@azure/abort-controller": "^2.0.0", "@azure/core-auth": "^1.3.0", "@azure/core-rest-pipeline": "^1.5.0", "@azure/core-tracing": "^1.0.1", "@typespec/ts-http-runtime": "^0.2.2", "tslib": "^2.6.2" } }, "sha512-CjMFBcmnt0YNdRcxSSoZbtZNXudLlicdml7UrPsV03nHiWB+Bq5cu5ctieyaCuRtU7jm7+SOFtiE/g4pBFPKKA=="],
|
||||||
|
|
||||||
|
"@azure/abort-controller": ["@azure/abort-controller@2.1.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA=="],
|
||||||
|
|
||||||
|
"@azure/core-auth": ["@azure/core-auth@1.9.0", "", { "dependencies": { "@azure/abort-controller": "^2.0.0", "@azure/core-util": "^1.11.0", "tslib": "^2.6.2" } }, "sha512-FPwHpZywuyasDSLMqJ6fhbOK3TqUdviZNF8OqRGA4W5Ewib2lEEZ+pBsYcBa88B2NGO/SEnYPGhyBqNlE8ilSw=="],
|
||||||
|
|
||||||
|
"@azure/core-lro": ["@azure/core-lro@2.7.2", "", { "dependencies": { "@azure/abort-controller": "^2.0.0", "@azure/core-util": "^1.2.0", "@azure/logger": "^1.0.0", "tslib": "^2.6.2" } }, "sha512-0YIpccoX8m/k00O7mDDMdJpbr6mf1yWo2dfmxt5A8XVZVVMz2SSKaEbMCeJRvgQ0IaSlqhjT47p4hVIRRy90xw=="],
|
||||||
|
|
||||||
|
"@azure/core-rest-pipeline": ["@azure/core-rest-pipeline@1.20.0", "", { "dependencies": { "@azure/abort-controller": "^2.0.0", "@azure/core-auth": "^1.8.0", "@azure/core-tracing": "^1.0.1", "@azure/core-util": "^1.11.0", "@azure/logger": "^1.0.0", "@typespec/ts-http-runtime": "^0.2.2", "tslib": "^2.6.2" } }, "sha512-ASoP8uqZBS3H/8N8at/XwFr6vYrRP3syTK0EUjDXQy0Y1/AUS+QeIRThKmTNJO2RggvBBxaXDPM7YoIwDGeA0g=="],
|
||||||
|
|
||||||
|
"@azure/core-sse": ["@azure/core-sse@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-6Xg/CeW0jRyMoWt+puw2x6Qqkml3tr76Cn/oA9goIcUXtsi3ngmTwCVbwqkUWfhsOfo4F+78LGgiswSxTHN0sg=="],
|
||||||
|
|
||||||
|
"@azure/core-tracing": ["@azure/core-tracing@1.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-UKTiEJPkWcESPYJz3X5uKRYyOcJD+4nYph+KpfdPRnQJVrZfk0KJgdnaAWKfhsBBtAf/D58Az4AvCJEmWgIBAg=="],
|
||||||
|
|
||||||
|
"@azure/core-util": ["@azure/core-util@1.12.0", "", { "dependencies": { "@azure/abort-controller": "^2.0.0", "@typespec/ts-http-runtime": "^0.2.2", "tslib": "^2.6.2" } }, "sha512-13IyjTQgABPARvG90+N2dXpC+hwp466XCdQXPCRlbWHgd3SJd5Q1VvaBGv6k1BIa4MQm6hAF1UBU1m8QUxV8sQ=="],
|
||||||
|
|
||||||
|
"@azure/logger": ["@azure/logger@1.2.0", "", { "dependencies": { "@typespec/ts-http-runtime": "^0.2.2", "tslib": "^2.6.2" } }, "sha512-0hKEzLhpw+ZTAfNJyRrn6s+V0nDWzXk9OjBr2TiGIu0OfMr5s2V4FpKLTAK3Ca5r5OKLbf4hkOGDPyiRjie/jA=="],
|
||||||
|
|
||||||
"@inquirer/checkbox": ["@inquirer/checkbox@4.1.5", "", { "dependencies": { "@inquirer/core": "^10.1.10", "@inquirer/figures": "^1.0.11", "@inquirer/type": "^3.0.6", "ansi-escapes": "^4.3.2", "yoctocolors-cjs": "^2.1.2" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-swPczVU+at65xa5uPfNP9u3qx/alNwiaykiI/ExpsmMSQW55trmZcwhYWzw/7fj+n6Q8z1eENvR7vFfq9oPSAQ=="],
|
"@inquirer/checkbox": ["@inquirer/checkbox@4.1.5", "", { "dependencies": { "@inquirer/core": "^10.1.10", "@inquirer/figures": "^1.0.11", "@inquirer/type": "^3.0.6", "ansi-escapes": "^4.3.2", "yoctocolors-cjs": "^2.1.2" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-swPczVU+at65xa5uPfNP9u3qx/alNwiaykiI/ExpsmMSQW55trmZcwhYWzw/7fj+n6Q8z1eENvR7vFfq9oPSAQ=="],
|
||||||
|
|
||||||
"@inquirer/confirm": ["@inquirer/confirm@5.1.9", "", { "dependencies": { "@inquirer/core": "^10.1.10", "@inquirer/type": "^3.0.6" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-NgQCnHqFTjF7Ys2fsqK2WtnA8X1kHyInyG+nMIuHowVTIgIuS10T4AznI/PvbqSpJqjCUqNBlKGh1v3bwLFL4w=="],
|
"@inquirer/confirm": ["@inquirer/confirm@5.1.9", "", { "dependencies": { "@inquirer/core": "^10.1.10", "@inquirer/type": "^3.0.6" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-NgQCnHqFTjF7Ys2fsqK2WtnA8X1kHyInyG+nMIuHowVTIgIuS10T4AznI/PvbqSpJqjCUqNBlKGh1v3bwLFL4w=="],
|
||||||
|
|
@ -86,6 +109,10 @@
|
||||||
|
|
||||||
"@types/tough-cookie": ["@types/tough-cookie@4.0.5", "", {}, "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA=="],
|
"@types/tough-cookie": ["@types/tough-cookie@4.0.5", "", {}, "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA=="],
|
||||||
|
|
||||||
|
"@typespec/ts-http-runtime": ["@typespec/ts-http-runtime@0.2.2", "", { "dependencies": { "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "tslib": "^2.6.2" } }, "sha512-Gz/Sm64+Sq/vklJu1tt9t+4R2lvnud8NbTD/ZfpZtMiUX7YeVpCA8j6NSW8ptwcoLL+NmYANwqP8DV0q/bwl2w=="],
|
||||||
|
|
||||||
|
"agent-base": ["agent-base@7.1.3", "", {}, "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw=="],
|
||||||
|
|
||||||
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
|
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
|
||||||
|
|
||||||
"ansi-escapes": ["ansi-escapes@4.3.2", "", { "dependencies": { "type-fest": "^0.21.3" } }, "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ=="],
|
"ansi-escapes": ["ansi-escapes@4.3.2", "", { "dependencies": { "type-fest": "^0.21.3" } }, "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ=="],
|
||||||
|
|
@ -210,8 +237,12 @@
|
||||||
|
|
||||||
"htmlparser2": ["htmlparser2@9.1.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.1.0", "entities": "^4.5.0" } }, "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ=="],
|
"htmlparser2": ["htmlparser2@9.1.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.1.0", "entities": "^4.5.0" } }, "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ=="],
|
||||||
|
|
||||||
|
"http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="],
|
||||||
|
|
||||||
"http-signature": ["http-signature@1.2.0", "", { "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", "sshpk": "^1.7.0" } }, "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ=="],
|
"http-signature": ["http-signature@1.2.0", "", { "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", "sshpk": "^1.7.0" } }, "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ=="],
|
||||||
|
|
||||||
|
"https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
|
||||||
|
|
||||||
"iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
|
"iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
|
||||||
|
|
||||||
"igramapi": ["igramapi@1.48.3", "", { "dependencies": { "@lifeomic/attempt": "^3.0.0", "@types/chance": "^1.0.2", "@types/request-promise": "^4.1.43", "bluebird": "^3.7.1", "chance": "^1.0.18", "class-transformer": "^0.5.1", "debug": "^4.1.1", "image-size": "^0.7.3", "json-bigint": "^1.0.0", "lodash": "^4.17.20", "luxon": "^1.28.1", "reflect-metadata": "^0.1.13", "request": "^2.88.0", "request-promise": "^4.2.4", "rxjs": "^6.5.2", "snakecase-keys": "^3.1.0", "tough-cookie": "^4.1.3", "ts-custom-error": "^3.1.1", "ts-xor": "^1.0.6", "url-regex-safe": "^3.0.0", "utility-types": "^3.10.0" }, "peerDependencies": { "re2": "^1.17.2" }, "optionalPeers": ["re2"] }, "sha512-Q2NB/IawGHVHxWqyqVwvyH3wsaVoIeUdgzOFfuq5jFXyjBP62S8DZhfy+3VvYH/ED65dvbaQhqDRZ6l+fDJINQ=="],
|
"igramapi": ["igramapi@1.48.3", "", { "dependencies": { "@lifeomic/attempt": "^3.0.0", "@types/chance": "^1.0.2", "@types/request-promise": "^4.1.43", "bluebird": "^3.7.1", "chance": "^1.0.18", "class-transformer": "^0.5.1", "debug": "^4.1.1", "image-size": "^0.7.3", "json-bigint": "^1.0.0", "lodash": "^4.17.20", "luxon": "^1.28.1", "reflect-metadata": "^0.1.13", "request": "^2.88.0", "request-promise": "^4.2.4", "rxjs": "^6.5.2", "snakecase-keys": "^3.1.0", "tough-cookie": "^4.1.3", "ts-custom-error": "^3.1.1", "ts-xor": "^1.0.6", "url-regex-safe": "^3.0.0", "utility-types": "^3.10.0" }, "peerDependencies": { "re2": "^1.17.2" }, "optionalPeers": ["re2"] }, "sha512-Q2NB/IawGHVHxWqyqVwvyH3wsaVoIeUdgzOFfuq5jFXyjBP62S8DZhfy+3VvYH/ED65dvbaQhqDRZ6l+fDJINQ=="],
|
||||||
|
|
@ -324,7 +355,7 @@
|
||||||
|
|
||||||
"ts-xor": ["ts-xor@1.3.0", "", {}, "sha512-RLXVjliCzc1gfKQFLRpfeD0rrWmjnSTgj7+RFhoq3KRkUYa8LE/TIidYOzM5h+IdFBDSjjSgk9Lto9sdMfDFEA=="],
|
"ts-xor": ["ts-xor@1.3.0", "", {}, "sha512-RLXVjliCzc1gfKQFLRpfeD0rrWmjnSTgj7+RFhoq3KRkUYa8LE/TIidYOzM5h+IdFBDSjjSgk9Lto9sdMfDFEA=="],
|
||||||
|
|
||||||
"tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="],
|
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
"tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="],
|
"tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="],
|
||||||
|
|
||||||
|
|
@ -372,6 +403,6 @@
|
||||||
|
|
||||||
"request-promise/tough-cookie": ["tough-cookie@2.5.0", "", { "dependencies": { "psl": "^1.1.28", "punycode": "^2.1.1" } }, "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g=="],
|
"request-promise/tough-cookie": ["tough-cookie@2.5.0", "", { "dependencies": { "psl": "^1.1.28", "punycode": "^2.1.1" } }, "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g=="],
|
||||||
|
|
||||||
"inquirer/rxjs/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
"rxjs/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { createCanvas, loadImage, GlobalFonts } from "@napi-rs/canvas";
|
import { createCanvas, loadImage, GlobalFonts } from "@napi-rs/canvas";
|
||||||
import { getMealInfo } from "./meal"; // 이 함수의 내용은 제공되지 않았으므로 그대로 둡니다.
|
import { getMealInfo, NameToEmoji } from "./meal"; // 이 함수의 내용은 제공되지 않았으므로 그대로 둡니다.
|
||||||
import { getAllSchedules } from "./schedule";
|
import { getAllSchedules } from "./schedule";
|
||||||
|
|
||||||
GlobalFonts.registerFromPath('./template/Pretendard-Bold.ttf', 'Pretendard Bold')
|
GlobalFonts.registerFromPath('./template/Pretendard-Bold.ttf', 'Pretendard Bold')
|
||||||
|
GlobalFonts.registerFromPath('./template/NotoColorEmoji-Regular.ttf', 'NotoColorEmoji Regular')
|
||||||
|
|
||||||
export class CreateImage {
|
export class CreateImage {
|
||||||
static async PostMeal(MLSV_YMD: string) {
|
static async PostMeal(MLSV_YMD: string): Promise<void> {
|
||||||
const mealInfo = await getMealInfo(MLSV_YMD);
|
const mealInfo = await getMealInfo(MLSV_YMD);
|
||||||
const img = await loadImage(path.join("./template/skeleton.png"));
|
const img = await loadImage(path.join("./template/skeleton.png"));
|
||||||
const canvas = createCanvas(img.width, img.height);
|
const canvas = createCanvas(img.width, img.height);
|
||||||
|
|
@ -19,9 +20,23 @@ export class CreateImage {
|
||||||
ctx.textAlign = "left";
|
ctx.textAlign = "left";
|
||||||
|
|
||||||
const lines = mealInfo.meal.split("\n").reverse();
|
const lines = mealInfo.meal.split("\n").reverse();
|
||||||
lines.forEach((line, i) => {
|
let emojis = (await NameToEmoji(lines.toString())).split(",");
|
||||||
ctx.fillText(line, 75, 930 - i * 60);
|
console.log(emojis);
|
||||||
});
|
if (lines.length !== emojis.length) {
|
||||||
|
console.error("Error: Emojis and lines count mismatch retrying...");
|
||||||
|
return this.PostMeal(MLSV_YMD);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
const emoji = emojis[i];
|
||||||
|
const text = lines[i];
|
||||||
|
|
||||||
|
ctx.font = "50px NotoColorEmoji Regular";
|
||||||
|
ctx.fillText(emoji ?? "", 75, 930 - i * 60);
|
||||||
|
|
||||||
|
ctx.font = "56px Pretendard Bold";
|
||||||
|
ctx.fillText(text ?? "", 75 + 80, 930 - i * 60);
|
||||||
|
}
|
||||||
|
|
||||||
ctx.font = "24px Pretendard Bold";
|
ctx.font = "24px Pretendard Bold";
|
||||||
ctx.textAlign = "right";
|
ctx.textAlign = "right";
|
||||||
|
|
@ -138,7 +153,9 @@ export class CreateImage {
|
||||||
|
|
||||||
ctx.drawImage(img, offsetX, offsetY, resizedWidth, resizedHeight);
|
ctx.drawImage(img, offsetX, offsetY, resizedWidth, resizedHeight);
|
||||||
|
|
||||||
const outPath = path.join("./", `${filePath}-story.png`);
|
const extIndex = filePath.lastIndexOf(".");
|
||||||
|
const baseName = extIndex !== -1 ? filePath.substring(0, extIndex) : filePath;
|
||||||
|
const outPath = path.join("./", `${baseName}-story.png`);
|
||||||
const buffer = canvas.toBuffer("image/png");
|
const buffer = canvas.toBuffer("image/png");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
import ModelClient, { isUnexpected } from "@azure-rest/ai-inference";
|
||||||
|
import { AzureKeyCredential } from "@azure/core-auth";
|
||||||
|
|
||||||
const KEY = process.env.NEIS_API_KEY;
|
const KEY = process.env.NEIS_API_KEY;
|
||||||
|
|
||||||
export function removeNutritionInfo(value: string): string {
|
export function removeNutritionInfo(value: string): string {
|
||||||
|
|
@ -23,3 +26,55 @@ export async function getMealInfo(MLSV_YMD: string): Promise<{ meal: string; dat
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function NameToEmoji(name: string): Promise<string> {
|
||||||
|
const token = process.env.GITHUB_TOKEN;
|
||||||
|
if (!token) {
|
||||||
|
throw new Error("GITHUB_TOKEN environment variable is not set.");
|
||||||
|
}
|
||||||
|
const endpoint = "https://models.github.ai/inference";
|
||||||
|
const model = "openai/gpt-4.1";
|
||||||
|
|
||||||
|
const client = ModelClient(
|
||||||
|
endpoint,
|
||||||
|
new AzureKeyCredential(token),
|
||||||
|
);
|
||||||
|
|
||||||
|
const systemPrompt = `You are an emoji responder.
|
||||||
|
When given any word or phrase, you must reply with exactly one emoji per item, matching the meaning as closely as possible.
|
||||||
|
**If multiple words or phrases are given, they will be separated by commas (,), and your emojis must also be separated by commas (,) in the same order.**
|
||||||
|
Do not include any words, explanations, or multiple emojis—just **one emoji per item**.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
Q: 현미찹쌀밥
|
||||||
|
A: 🍚
|
||||||
|
Q: 개
|
||||||
|
A: 🐶
|
||||||
|
Q: 축구
|
||||||
|
A: ⚽
|
||||||
|
Q: 해넘이
|
||||||
|
A: 🌇
|
||||||
|
Q: 현미찹쌀밥,개,축구
|
||||||
|
A: 🍚,🐶,⚽
|
||||||
|
`;
|
||||||
|
|
||||||
|
const response = await client.path("/chat/completions").post({
|
||||||
|
body: {
|
||||||
|
messages: [
|
||||||
|
{ role: "system", content: systemPrompt },
|
||||||
|
{ role: "user", content: name }
|
||||||
|
],
|
||||||
|
temperature: 1.0,
|
||||||
|
top_p: 1.0,
|
||||||
|
model: model
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (isUnexpected(response)) {
|
||||||
|
throw response.body.error;
|
||||||
|
}
|
||||||
|
|
||||||
|
const choices = response.body?.choices;
|
||||||
|
if (!choices || !choices[0]?.message?.content) {
|
||||||
|
throw new Error("No valid response from the model.");
|
||||||
|
}
|
||||||
|
return choices[0].message.content as string;
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,9 @@
|
||||||
"typescript": "^5"
|
"typescript": "^5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@azure-rest/ai-inference": "^1.0.0-beta.6",
|
||||||
|
"@azure/core-auth": "^1.9.0",
|
||||||
|
"@azure/core-sse": "^2.2.0",
|
||||||
"@napi-rs/canvas": "^0.1.70",
|
"@napi-rs/canvas": "^0.1.70",
|
||||||
"cheerio": "^1.0.0",
|
"cheerio": "^1.0.0",
|
||||||
"igramapi": "^1.48.3",
|
"igramapi": "^1.48.3",
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,29 @@
|
||||||
//import { Discord } from "./lib/discord";
|
//import { Discord } from "./lib/discord";
|
||||||
|
import { CreateImage } from "./lib/image";
|
||||||
|
|
||||||
const YYMMDD = new Date().toISOString().slice(0, 10).replace(/-/g, "").toString();
|
const YYMMDD = new Date().toISOString().slice(0, 10).replace(/-/g, "").toString();
|
||||||
console.log(YYMMDD);
|
console.log(YYMMDD);
|
||||||
|
|
||||||
//Discord("20250509")
|
//Discord("20250509")
|
||||||
/*async function run() {
|
async function run() {
|
||||||
console.time("Post");
|
console.time("Post");
|
||||||
await CreateImage.Post(YYMMDD);
|
await CreateImage.PostMeal(YYMMDD);
|
||||||
console.timeEnd("Post");
|
console.timeEnd("Post");
|
||||||
|
|
||||||
console.time("Story");
|
console.time("Story");
|
||||||
await CreateImage.Story(YYMMDD);
|
await CreateImage.ConvertToStory(`./temp/${YYMMDD}.png`);
|
||||||
console.timeEnd("Story");
|
console.timeEnd("Story");
|
||||||
}
|
}
|
||||||
|
|
||||||
run();
|
run();
|
||||||
*/
|
|
||||||
|
|
||||||
//import { CreateImage } from "./lib/image";
|
//import { CreateImage } from "./lib/image";
|
||||||
|
|
||||||
//CreateImage.PostSchedule()
|
//CreateImage.PostSchedule()
|
||||||
|
|
||||||
const tomorrow = new Date();
|
//const tomorrow = new Date();
|
||||||
tomorrow.setDate(tomorrow.getDate() + 1);
|
//tomorrow.setDate(tomorrow.getDate() + 1);
|
||||||
|
|
||||||
// 내일이 1일이면
|
// 내일이 1일이면
|
||||||
console.log(tomorrow.getDate());
|
//console.log(tomorrow.getDate());
|
||||||
|
|
|
||||||
BIN
app/template/NotoColorEmoji-Regular.ttf
Normal file
BIN
app/template/NotoColorEmoji-Regular.ttf
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue