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