164 lines
3.9 KiB
JavaScript
164 lines
3.9 KiB
JavaScript
import { User, Pagination } from './index'
|
|
import * as Models from './models'
|
|
import config from '../../scripts/load-config'
|
|
|
|
import { Feed } from 'feed'
|
|
|
|
const perPage = 8
|
|
|
|
let feed
|
|
|
|
function slugify (title) {
|
|
return title.toLowerCase().replace(/\W/g, '-').substring(0, 32)
|
|
}
|
|
|
|
async function cleanArticle (entry) {
|
|
const poster = await User.get(entry.user_id)
|
|
const article = {
|
|
id: entry.id,
|
|
slug: slugify(entry.title),
|
|
title: entry.title,
|
|
content: entry.content,
|
|
tags: entry.tags.split(','),
|
|
created_at: entry.created_at,
|
|
updated_at: entry.updated_at
|
|
}
|
|
|
|
if (poster) {
|
|
article.author = {
|
|
id: poster.id,
|
|
display_name: poster.display_name,
|
|
email: poster.email
|
|
}
|
|
}
|
|
|
|
article.description = article.content.replace(/(<([^>]+)>)/ig, '').replace(/\n/g, ' ').substring(0, 197) + '...'
|
|
|
|
return article
|
|
}
|
|
|
|
export async function preview () {
|
|
// Fetch 3 latest stories
|
|
const news = await Models.News.query().orderBy('created_at', 'desc').limit(3)
|
|
|
|
if (!news.length) return []
|
|
|
|
const articles = []
|
|
for (const i in news) {
|
|
const entry = news[i]
|
|
articles.push(await cleanArticle(entry))
|
|
}
|
|
|
|
return articles
|
|
}
|
|
|
|
export async function listNews (page) {
|
|
let count = await Models.News.query().count('id as ids')
|
|
if (page < 1) page = 1
|
|
|
|
if (!count.length || !count[0].ids || isNaN(page)) {
|
|
return { error: 'No news' }
|
|
}
|
|
|
|
count = count[0].ids
|
|
const paginated = Pagination(perPage, parseInt(count), page)
|
|
const news = await Models.News.query().orderBy('created_at', 'desc').offset(paginated.offset).limit(perPage)
|
|
|
|
const articles = []
|
|
for (const i in news) {
|
|
const entry = news[i]
|
|
|
|
articles.push(await cleanArticle(entry))
|
|
}
|
|
|
|
return {
|
|
page: paginated,
|
|
articles: articles
|
|
}
|
|
}
|
|
|
|
export async function article (id) {
|
|
let article = await Models.News.query().where('id', id)
|
|
if (!article.length) return {}
|
|
article = article[0]
|
|
|
|
return cleanArticle(article)
|
|
}
|
|
|
|
export async function compose (user, body) {
|
|
const article = {
|
|
title: body.title,
|
|
content: body.content,
|
|
tags: body.tags || '',
|
|
user_id: user.id,
|
|
created_at: new Date(),
|
|
updated_at: new Date()
|
|
}
|
|
|
|
const result = await Models.News.query().insert(article)
|
|
result.slug = slugify(result.title)
|
|
|
|
return result
|
|
}
|
|
|
|
export async function edit (id, body) {
|
|
const patch = {
|
|
content: body.content,
|
|
updated_at: new Date()
|
|
}
|
|
|
|
const result = await Models.News.query().patchAndFetchById(id, patch)
|
|
if (!result) throw new Error('Something went wrong.')
|
|
return {}
|
|
}
|
|
|
|
export async function generateFeed () {
|
|
if (feed && new Date(feed.options.updated).getTime() > Date.now() - 3600000) return feed // Update feed hourly
|
|
|
|
const posts = await Models.News.query().orderBy('created_at', 'desc').limit(perPage)
|
|
const cleanNews = []
|
|
|
|
for (const i in posts) {
|
|
cleanNews.push(await cleanArticle(posts[i]))
|
|
}
|
|
|
|
feed = new Feed({
|
|
title: 'Icy Network News',
|
|
description: 'Icy Network News',
|
|
id: config.server.domain + '/news',
|
|
link: config.server.domain + '/news',
|
|
image: config.server.domain + '/static/image/icynet-icon.png',
|
|
favicon: config.server.domain + '/favicon.ico',
|
|
copyright: '2020 Icy Network',
|
|
updated: new Date(),
|
|
feedLinks: {
|
|
json: config.server.domain + '/news/feed.json',
|
|
atom: config.server.domain + '/news/atom.xml'
|
|
},
|
|
author: {
|
|
name: 'Icy Network',
|
|
email: 'icynet@icynet.eu',
|
|
link: config.server.domain
|
|
}
|
|
})
|
|
|
|
for (const i in cleanNews) {
|
|
const post = cleanNews[i]
|
|
|
|
feed.addItem({
|
|
title: post.title,
|
|
link: `${config.server.domain}/news/${post.id}-${slugify(post.title)}`,
|
|
description: post.description,
|
|
content: post.content,
|
|
author: [{
|
|
name: post.author.display_name,
|
|
email: post.author.email,
|
|
link: config.server.domain
|
|
}],
|
|
date: new Date(post.updated_at)
|
|
})
|
|
}
|
|
|
|
return feed
|
|
}
|