Compare commits

..

5 commits

5 changed files with 129 additions and 85 deletions

View file

@ -9,11 +9,11 @@ import { handler as ssrHandler } from './dist/server/entry.mjs'
const app = Fastify({ logger: true })
await app
.register(import('@fastify/rate-limit'), {
global: true,
max: 25,
timeWindow: 1000 * 60 * 5,
})
// .register(import('@fastify/rate-limit'), {
// global: true,
// max: 25,
// timeWindow: 1000 * 60 * 5,
// })
.register(fastifyStatic, {
root: fileURLToPath(new URL('./dist/client', import.meta.url)),
})
@ -21,21 +21,21 @@ await app
app.use(ssrHandler)
await app.setNotFoundHandler(
{
preHandler: app.rateLimit(),
},
function (request, reply) {
reply.code(404).send({ nothing: 'to see here' })
}
)
// await app.setNotFoundHandler(
// {
// preHandler: app.rateLimit(),
// },
// function (request, reply) {
// reply.code(404).send({ nothing: 'to see here' })
// }
// )
await app.setErrorHandler(function (error, request, reply) {
if (error.statusCode === 429) {
reply.code(429)
error.message = 'You hit the rate limit! Slow down please!'
}
reply.send(error)
})
// await app.setErrorHandler(function (error, request, reply) {
// if (error.statusCode === 429) {
// reply.code(429)
// error.message = 'You hit the rate limit! Slow down please!'
// }
// reply.send(error)
// })
app.listen({ port: 4321 })

View file

@ -6,4 +6,4 @@ export const SITE_AUTHOR_MASTODON = 'https://social.ayco.io/@ayo'
export const SITE_PROJECT_REPO = 'https://github.com/ayoayco/Cozy'
export const SITE_DESCRIPTION = 'The Web is Yours.'
export const VERSION = 'Drooling-Dogs'
export const VERSION = 'Maintenance'

View file

@ -120,11 +120,13 @@ const siteName = 'cozy.pub'
}
}
/*
&:has(#router-outlet #post) {
#jumbotron {
display: none;
}
}
*/
}
</style>
<style is:global>

View file

@ -1,74 +1,42 @@
---
import { createClient, type RedisJSON } from 'redis'
import { type ArticleData, extract } from '@extractus/article-extractor'
import AddressBar from '../components/AddressBar.astro'
import Post from '../components/Post.astro'
import App from '../layouts/App.astro'
import Library from '../components/Library.astro'
import Footer from '../components/Footer.astro'
// Initialize Redis client
const client = createClient()
client.on('error', (err) => console.error('Redis Client Error', err))
await client.connect()
// Disable prerendering for dynamic content
export const prerender = false
// Get URL parameter from query string
let url = Astro.url.searchParams.get('url')
let article: ArticleData | null = { url: '/' }
// Handle redirect loops by extracting URL from nested parameters
while (url?.startsWith(Astro.url.origin)) {
try {
// Parse the URL to extract search parameters
const parsedUrl = new URL(url)
url = parsedUrl.searchParams.get('url')
} catch {
// If URL parsing fails, break the loop
console.error('Failed to parse URL:', url)
break
}
}
// Process article extraction only if a valid URL is provided
if (url && url !== '/' && url !== '') {
const cacheKey = 'cozy:url:' + url
try {
// Check if article exists in Redis cache
const exists = await client.exists(cacheKey)
if (exists) {
// Retrieve cached article data
article = (await client.json.get(cacheKey)) as ArticleData
console.log('>>> Using cached content', article.url)
} else {
// Fetch article from the web
article = await extract(url)
console.log('>>> Using fetched content', article?.url)
if (article !== null && article.url) {
// Cache the fetched article in Redis
await client.json.set(cacheKey, '$', article as RedisJSON)
console.log('>>> Added to cache', article.url)
}
}
} catch (error) {
// Log error and continue with null article
console.error('Error processing article:', error)
article = null
}
}
---
<App article={article}>
<AddressBar url={url} />
<App article={null}>
<button
id="home-btn"
onclick="document.getElementById('router-outlet').innerHTML = `
<h1>Under Maintenance</h1>
<p>
Currently performing some maintenance, working to improve your
experience. Please check back soon. We apologize for any inconvenience
this may cause.
</p>
`;"
>Home</button
>
<div slot="post" id="router-outlet">
<Post article={article} />
<h1>Under Maintenance</h1>
<p>
Currently performing some maintenance, working to improve your experience.
Please check back soon. We apologize for any inconvenience this may cause.
</p>
</div>
<Library slot="library" skipSave={article === null} />
<Library slot="library" skipSave={true} />
<Footer slot="footer" />
</App>
<style>
#home-btn {
width: 100%;
padding: 0.5rem 1rem;
text-align: center;
border-radius: 30px;
border: 2px solid rgb(var(--gray));
background-color: white;
box-shadow: 0 1px 3px 1px rgb(var(--gray-light));
cursor: pointer;
}
</style>

View file

@ -0,0 +1,74 @@
---
import { createClient, type RedisJSON } from 'redis'
import { type ArticleData, extract } from '@extractus/article-extractor'
import AddressBar from '../components/AddressBar.astro'
import Post from '../components/Post.astro'
import App from '../layouts/App.astro'
import Library from '../components/Library.astro'
import Footer from '../components/Footer.astro'
// Initialize Redis client
const client = createClient()
client.on('error', (err) => console.error('Redis Client Error', err))
await client.connect()
// Disable prerendering for dynamic content
export const prerender = false
// Get URL parameter from query string
let url = Astro.url.searchParams.get('url')
let article: ArticleData | null = { url: '/' }
// Handle redirect loops by extracting URL from nested parameters
while (url?.startsWith(Astro.url.origin)) {
try {
// Parse the URL to extract search parameters
const parsedUrl = new URL(url)
url = parsedUrl.searchParams.get('url')
} catch {
// If URL parsing fails, break the loop
console.error('Failed to parse URL:', url)
break
}
}
// Process article extraction only if a valid URL is provided
if (url && url !== '/' && url !== '') {
const cacheKey = 'cozy:url:' + url
try {
// Check if article exists in Redis cache
const exists = await client.exists(cacheKey)
if (exists) {
// Retrieve cached article data
article = (await client.json.get(cacheKey)) as ArticleData
console.log('>>> Using cached content', article.url)
} else {
// Fetch article from the web
article = await extract(url)
console.log('>>> Using fetched content', article?.url)
if (article !== null && article.url) {
// Cache the fetched article in Redis
await client.json.set(cacheKey, '$', article as RedisJSON)
console.log('>>> Added to cache', article.url)
}
}
} catch (error) {
// Log error and continue with null article
console.error('Error processing article:', error)
article = null
}
}
---
<App article={article}>
<AddressBar url={url} />
<div slot="post" id="router-outlet">
<Post article={article} />
</div>
<Library slot="library" skipSave={article === null} />
<Footer slot="footer" />
</App>