This repository has been archived on 2022-11-26. You can view files and clone it, but cannot push or open issues or pull requests.
IcyNet.eu/server/api/news.js

163 lines
4.0 KiB
JavaScript

import API from './index'
import 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, shortenContent = false) {
let poster = await API.User.get(entry.user_id)
let 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
}
const News = {
preview: async () => {
// Fetch 3 latest stories
let news = await Models.News.query().orderBy('created_at', 'desc').limit(3)
if (!news.length) return []
let articles = []
for (let i in news) {
let entry = news[i]
articles.push(await cleanArticle(entry))
}
return articles
},
listNews: async (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
let paginated = API.Pagination(perPage, parseInt(count), page)
let news = await Models.News.query().orderBy('created_at', 'desc').offset(paginated.offset).limit(perPage)
let articles = []
for (let i in news) {
let entry = news[i]
articles.push(await cleanArticle(entry))
}
return {
page: paginated,
articles: articles
}
},
article: async (id) => {
let article = await Models.News.query().where('id', id)
if (!article.length) return {}
article = article[0]
return cleanArticle(article)
},
compose: async (user, body) => {
let article = {
title: body.title,
content: body.content,
tags: body.tags || '',
user_id: user.id,
created_at: new Date(),
updated_at: new Date()
}
let result = await Models.News.query().insert(article)
result.slug = slugify(result.title)
return result
},
edit: async (id, body) => {
let patch = {
content: body.content,
updated_at: new Date()
}
let result = await Models.News.query().patchAndFetchById(id, patch)
if (!result) throw new Error('Something went wrong.')
return {}
},
generateFeed: async () => {
if (feed && new Date(feed.options.updated).getTime() > Date.now() - 3600000) return feed // Update feed hourly
let posts = await Models.News.query().orderBy('created_at', 'desc').limit(perPage)
let cleanNews = []
for (let 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: '2018 Icy Network - Some Rights Reserved',
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 (let i in cleanNews) {
let post = cleanNews[i]
feed.addItem({
title: post.title,
id: post.id,
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
}],
date: new Date(post.updated_at)
})
}
return feed
}
}
module.exports = News