From 7ac622e4bd68d10cc3e361fcf37ab67d24c36f18 Mon Sep 17 00:00:00 2001 From: Mark Gibson Date: Wed, 13 Mar 2024 15:23:12 +0000 Subject: [PATCH] Added quote of the moment page --- cron.ts | 7 ++ deno.json | 3 +- deno.lock | 176 ++++++++++++++++++++++++++- main.ts | 3 + routes.ts | 1 + routes/blog/links.md | 9 +- routes/quote/_components/Quote.tsx | 12 ++ routes/quote/_cron/generate_quote.ts | 31 +++++ routes/quote/_lib/quote_store.ts | 9 ++ routes/quote/index.tsx | 15 +++ scripts/dev.ts | 6 + 11 files changed, 263 insertions(+), 9 deletions(-) create mode 100644 cron.ts create mode 100644 routes/quote/_components/Quote.tsx create mode 100644 routes/quote/_cron/generate_quote.ts create mode 100644 routes/quote/_lib/quote_store.ts create mode 100644 routes/quote/index.tsx diff --git a/cron.ts b/cron.ts new file mode 100644 index 0000000..8836e01 --- /dev/null +++ b/cron.ts @@ -0,0 +1,7 @@ +import * as quote_cron from "./routes/quote/_cron/generate_quote.ts"; + +// TODO: discover all _cron modules and generate this function + +export default function initCron() { + Deno.cron(quote_cron.name, quote_cron.schedule, quote_cron.default); +} diff --git a/deno.json b/deno.json index cd715ff..af34535 100644 --- a/deno.json +++ b/deno.json @@ -1,6 +1,7 @@ { "unstable": [ - "kv" + "kv", + "cron" ], "tasks": { "build": "deno run --allow-all scripts/build.ts", diff --git a/deno.lock b/deno.lock index 03b86e8..e2dd7fe 100644 --- a/deno.lock +++ b/deno.lock @@ -31,7 +31,8 @@ "npm:mdast-util-from-markdown@2.0.0": "npm:mdast-util-from-markdown@2.0.0", "npm:mdast-util-gfm@3.0.0": "npm:mdast-util-gfm@3.0.0", "npm:mdast-util-to-hast@13.0.2": "npm:mdast-util-to-hast@13.0.2", - "npm:micromark-extension-gfm@3.0.0": "npm:micromark-extension-gfm@3.0.0" + "npm:micromark-extension-gfm@3.0.0": "npm:micromark-extension-gfm@3.0.0", + "npm:openai": "npm:openai@4.28.4" }, "jsr": { "@http/fns@0.6.3": { @@ -127,10 +128,7 @@ ] }, "@std/path@0.219.1": { - "integrity": "e5c0ffef3a8ef2b48e9e3d88a1489320e8fb2cc7be767b17c91a1424ffb4c8ed", - "dependencies": [ - "jsr:@std/assert@^0.219.1" - ] + "integrity": "e5c0ffef3a8ef2b48e9e3d88a1489320e8fb2cc7be767b17c91a1424ffb4c8ed" }, "@std/streams@0.219.1": { "integrity": "6f5dac5773a4fafdbe7ee612d0a0d5a2cbe465b9c9e2c85d371877dc8a52d1d3" @@ -254,6 +252,23 @@ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", "dependencies": {} }, + "@types/node-fetch@2.6.11": { + "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", + "dependencies": { + "@types/node": "@types/node@18.16.19", + "form-data": "form-data@4.0.0" + } + }, + "@types/node@18.16.19": { + "integrity": "sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==", + "dependencies": {} + }, + "@types/node@18.19.21": { + "integrity": "sha512-2Q2NeB6BmiTFQi4DHBzncSoq/cJMLDdhPaAoJFnFCyD9a8VPZRf7a1GAwp1Edb7ROaZc5Jz/tnZyL6EsWMRaqw==", + "dependencies": { + "undici-types": "undici-types@5.26.5" + } + }, "@types/unist@3.0.2": { "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==", "dependencies": {} @@ -262,6 +277,26 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dependencies": {} }, + "abort-controller@3.0.0": { + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "event-target-shim@5.0.1" + } + }, + "agentkeepalive@4.5.0": { + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "dependencies": { + "humanize-ms": "humanize-ms@1.2.1" + } + }, + "asynckit@0.4.0": { + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dependencies": {} + }, + "base-64@0.1.0": { + "integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==", + "dependencies": {} + }, "ccount@2.0.1": { "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", "dependencies": {} @@ -270,10 +305,24 @@ "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", "dependencies": {} }, + "charenc@0.0.2": { + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "dependencies": {} + }, + "combined-stream@1.0.8": { + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "delayed-stream@1.0.0" + } + }, "comma-separated-tokens@2.0.3": { "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", "dependencies": {} }, + "crypt@0.0.2": { + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "dependencies": {} + }, "debug@4.3.4": { "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { @@ -286,6 +335,10 @@ "character-entities": "character-entities@2.0.2" } }, + "delayed-stream@1.0.0": { + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dependencies": {} + }, "dequal@2.0.3": { "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "dependencies": {} @@ -296,6 +349,13 @@ "dequal": "dequal@2.0.3" } }, + "digest-fetch@1.3.0": { + "integrity": "sha512-CGJuv6iKNM7QyZlM2T3sPAdZWd/p9zQiRNS9G+9COUCwzWFTs0Xp8NF5iePx7wtvhDykReiRRrSeNb4oMmB8lA==", + "dependencies": { + "base-64": "base-64@0.1.0", + "md5": "md5@2.3.0" + } + }, "entities@4.5.0": { "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dependencies": {} @@ -332,6 +392,29 @@ "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dependencies": {} }, + "event-target-shim@5.0.1": { + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dependencies": {} + }, + "form-data-encoder@1.7.2": { + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", + "dependencies": {} + }, + "form-data@4.0.0": { + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "asynckit@0.4.0", + "combined-stream": "combined-stream@1.0.8", + "mime-types": "mime-types@2.1.35" + } + }, + "formdata-node@4.4.1": { + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "dependencies": { + "node-domexception": "node-domexception@1.0.0", + "web-streams-polyfill": "web-streams-polyfill@4.0.0-beta.3" + } + }, "hast-util-from-parse5@8.0.1": { "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", "dependencies": { @@ -415,10 +498,20 @@ "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", "dependencies": {} }, + "humanize-ms@1.2.1": { + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dependencies": { + "ms": "ms@2.1.3" + } + }, "inline-style-parser@0.1.1": { "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==", "dependencies": {} }, + "is-buffer@1.1.6": { + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dependencies": {} + }, "longest-streak@3.1.0": { "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", "dependencies": {} @@ -427,6 +520,14 @@ "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", "dependencies": {} }, + "md5@2.3.0": { + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dependencies": { + "charenc": "charenc@0.0.2", + "crypt": "crypt@0.0.2", + "is-buffer": "is-buffer@1.1.6" + } + }, "mdast-util-find-and-replace@3.0.1": { "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", "dependencies": { @@ -796,10 +897,48 @@ "micromark-util-types": "micromark-util-types@2.0.0" } }, + "mime-db@1.52.0": { + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dependencies": {} + }, + "mime-types@2.1.35": { + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "mime-db@1.52.0" + } + }, "ms@2.1.2": { "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dependencies": {} }, + "ms@2.1.3": { + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dependencies": {} + }, + "node-domexception@1.0.0": { + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dependencies": {} + }, + "node-fetch@2.7.0": { + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "whatwg-url@5.0.0" + } + }, + "openai@4.28.4": { + "integrity": "sha512-RNIwx4MT/F0zyizGcwS+bXKLzJ8QE9IOyigDG/ttnwB220d58bYjYFp0qjvGwEFBO6+pvFVIDABZPGDl46RFsg==", + "dependencies": { + "@types/node": "@types/node@18.19.21", + "@types/node-fetch": "@types/node-fetch@2.6.11", + "abort-controller": "abort-controller@3.0.0", + "agentkeepalive": "agentkeepalive@4.5.0", + "digest-fetch": "digest-fetch@1.3.0", + "form-data-encoder": "form-data-encoder@1.7.2", + "formdata-node": "formdata-node@4.4.1", + "node-fetch": "node-fetch@2.7.0", + "web-streams-polyfill": "web-streams-polyfill@3.3.3" + } + }, "parse5@7.1.2": { "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "dependencies": { @@ -820,10 +959,18 @@ "inline-style-parser": "inline-style-parser@0.1.1" } }, + "tr46@0.0.3": { + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dependencies": {} + }, "trim-lines@3.0.1": { "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", "dependencies": {} }, + "undici-types@5.26.5": { + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dependencies": {} + }, "unist-util-is@6.0.0": { "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", "dependencies": { @@ -883,6 +1030,25 @@ "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", "dependencies": {} }, + "web-streams-polyfill@3.3.3": { + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "dependencies": {} + }, + "web-streams-polyfill@4.0.0-beta.3": { + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "dependencies": {} + }, + "webidl-conversions@3.0.1": { + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dependencies": {} + }, + "whatwg-url@5.0.0": { + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "tr46@0.0.3", + "webidl-conversions": "webidl-conversions@3.0.1" + } + }, "zwitch@2.0.4": { "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", "dependencies": {} diff --git a/main.ts b/main.ts index bba366f..c75cf73 100644 --- a/main.ts +++ b/main.ts @@ -1,4 +1,7 @@ import handler from "./handler.ts"; import init from "@http/fns/hosting/init_deploy"; +import initCron from "./cron.ts"; + +await initCron(); await Deno.serve(await init(handler)).finished; diff --git a/routes.ts b/routes.ts index d159df2..1d53ca3 100644 --- a/routes.ts +++ b/routes.ts @@ -14,6 +14,7 @@ export default cascade( byPattern("/sse/feed", lazy(() => import("./routes/sse/feed.tsx"))), byPattern("/sse", lazy(() => import("./routes/sse/index.tsx"))), byPattern("/sleep", lazy(() => import("./routes/sleep.ts"))), + byPattern("/quote", lazy(() => import("./routes/quote/index.tsx"))), byPattern("/quiz/answer/:id/:answer", lazy(() => import("./routes/quiz/answer/:id/:answer.tsx"))), byPattern("/quiz", lazy(() => import("./routes/quiz/index.tsx"))), byPattern("/ex/:from/:to", lazy(() => import("./routes/ex/:from/:to.tsx"))), diff --git a/routes/blog/links.md b/routes/blog/links.md index ea9cfe7..bab1f30 100644 --- a/routes/blog/links.md +++ b/routes/blog/links.md @@ -3,13 +3,16 @@ This site is powered by... - [Deno](https://deno.land) - the JS/TS runtime that isn't Node -- [JSR](https://jsr.io/) - the new registry that supplies many of the dependencies +- [JSR](https://jsr.io/) - the new registry that supplies many of the + dependencies - [Deno Deploy](https://deno.com/deploy) - the Deno based serverless hosting service - [htmx](https://htmx.org) - used for many of the interactive demos - [missing.css](https://missing.style) - css library -- [@http/fns](https://jsr.io/@http/fns) - my HTTP server functions library (for routing etc) -- [@http/jsx-stream](https://jsr.io/@http/jsx-stream) - my JSX streaming serializer +- [@http/fns](https://jsr.io/@http/fns) - my HTTP server functions library (for + routing etc) +- [@http/jsx-stream](https://jsr.io/@http/jsx-stream) - my JSX streaming + serializer - [remark](https://remark.js.org) - the markdown processor (although I use [mdast](https://github.com/syntax-tree/mdast) and it's utilities directly) - [esbuild](https://esbuild.github.io/) - to build the service worker, as not diff --git a/routes/quote/_components/Quote.tsx b/routes/quote/_components/Quote.tsx new file mode 100644 index 0000000..3877d37 --- /dev/null +++ b/routes/quote/_components/Quote.tsx @@ -0,0 +1,12 @@ +import { getQuote } from "../_lib/quote_store.ts"; + +export async function Quote() { + const quote = await getQuote(); + + return ( +
+

{quote}

+
- a generative AI
+
+ ); +} diff --git a/routes/quote/_cron/generate_quote.ts b/routes/quote/_cron/generate_quote.ts new file mode 100644 index 0000000..bf6760b --- /dev/null +++ b/routes/quote/_cron/generate_quote.ts @@ -0,0 +1,31 @@ +import { setQuote } from "../_lib/quote_store.ts"; +import OpenAI from "npm:openai"; + +export const name = "Generate a new quote of the moment"; + +export const schedule = Deno.env.get("QUOTE_SCHEDULE") ?? "*/30 * * * *"; + +export default async function generateQuote() { + console.log("Generating a new quote..."); + + const openai = new OpenAI(); + + const completion = await openai.chat.completions.create({ + model: "gpt-4", + messages: [ + { + role: "user", + content: + "Generate a new unique inspirational quote of the day. Do not attribute it to anyone", + }, + ], + }); + + const content = completion?.choices[0]?.message.content; + + if (content) { + await setQuote(content); + } +} + +export const init = generateQuote; diff --git a/routes/quote/_lib/quote_store.ts b/routes/quote/_lib/quote_store.ts new file mode 100644 index 0000000..fed08f0 --- /dev/null +++ b/routes/quote/_lib/quote_store.ts @@ -0,0 +1,9 @@ +import * as store from "$store"; + +export async function getQuote() { + return await store.getItem(["quote"]) ?? "Nothing to see here"; +} + +export async function setQuote(quote: string) { + await store.setItem(["quote"], quote); +} diff --git a/routes/quote/index.tsx b/routes/quote/index.tsx new file mode 100644 index 0000000..2253285 --- /dev/null +++ b/routes/quote/index.tsx @@ -0,0 +1,15 @@ +import { Page } from "../../components/Page.tsx"; +import { renderPage } from "../../lib/handle_page.ts"; +import { byMethod } from "@http/fns/by_method"; +import { Quote } from "./_components/Quote.tsx"; + +export default byMethod({ + GET: (req, match: URLPatternResult) => { + return renderPage(() => ( + +

Quote of the moment:

+ +
+ ))(req, match); + }, +}); diff --git a/scripts/dev.ts b/scripts/dev.ts index 3f5a786..1490bb6 100644 --- a/scripts/dev.ts +++ b/scripts/dev.ts @@ -2,9 +2,15 @@ import handler from "../handler.ts"; import { buildServiceWorker } from "./build.ts"; import generateRoutes from "./gen.ts"; import init from "@http/fns/hosting/init_localhost"; +import initCron from "../cron.ts"; +import generateQuote from "../routes/quote/_cron/generate_quote.ts"; await generateRoutes(); await buildServiceWorker(); +await generateQuote(); + +await initCron(); + await Deno.serve(await init(handler)).finished;