diff --git a/package-lock.json b/package-lock.json index efb7f42..3255d55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "icynet.eu", - "version": "0.0.1-alpha1", + "version": "0.9.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -2679,6 +2679,14 @@ "pend": "1.2.0" } }, + "feed": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/feed/-/feed-1.1.1.tgz", + "integrity": "sha1-kUiXUX6U+jJ8xvc7tYWkfEqe0yE=", + "requires": { + "xml": "1.0.1" + } + }, "figures": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", @@ -7740,6 +7748,11 @@ "mkdirp": "0.5.1" } }, + "xml": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=" + }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", diff --git a/package.json b/package.json index 1b1dd65..f7b64d7 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "express": "^4.16.2", "express-rate-limit": "^2.9.0", "express-session": "^1.15.6", + "feed": "^1.1.1", "fs-extra": "^4.0.2", "gm": "^1.23.0", "knex": "^0.13.0", diff --git a/server/api/news.js b/server/api/news.js index 3ccb650..41d88da 100644 --- a/server/api/news.js +++ b/server/api/news.js @@ -1,8 +1,13 @@ 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) } @@ -22,13 +27,12 @@ async function cleanArticle (entry, shortenContent = false) { if (poster) { article.author = { id: poster.id, - display_name: poster.display_name + display_name: poster.display_name, + email: poster.email } } - if (shortenContent) { - article.content = article.content.replace(/(<([^>]+)>)/ig, '').substring(0, 128) + '...' - } + article.description = article.content.replace(/(<([^>]+)>)/ig, '').replace(/\n/g, ' ').substring(0, 197) + '...' return article } @@ -43,7 +47,7 @@ const News = { let articles = [] for (let i in news) { let entry = news[i] - articles.push(await cleanArticle(entry, true)) + articles.push(await cleanArticle(entry)) } return articles @@ -102,6 +106,55 @@ const News = { 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@lunasqu.ee', + 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 } } diff --git a/server/routes/index.js b/server/routes/index.js index 93f1947..0fd035e 100644 --- a/server/routes/index.js +++ b/server/routes/index.js @@ -797,6 +797,20 @@ router.get('/news/', wrap(async (req, res) => { res.render('news/news', {news: news}) })) +router.get('/news/atom.xml', wrap(async (req, res) => { + let feed = await News.generateFeed() + + res.set('Content-Type', 'application/atom+xml') + res.send(feed.atom1()) +})) + +router.get('/news/feed.json', wrap(async (req, res) => { + let feed = await News.generateFeed() + + res.set('Content-Type', 'application/json') + res.send(feed.json1()) +})) + // Render partials router.get('/partials/:view', (req, res, next) => { if (!req.params.view) return next() diff --git a/src/script/main.js b/src/script/main.js index 65b4160..b510445 100644 --- a/src/script/main.js +++ b/src/script/main.js @@ -204,7 +204,7 @@ $(document).ready(function () { html += '
' html += '' + article.title + '' html += 'Published at ' + new Date(article.created_at) + '' - html += '
' + article.content + '
' + html += '
' + article.description + '
' html += 'Read More' html += '
' } diff --git a/views/layout.pug b/views/layout.pug index 2c4433e..2edeb80 100644 --- a/views/layout.pug +++ b/views/layout.pug @@ -3,6 +3,14 @@ html head meta(charset="utf8") meta(name="viewport", content="width=device-width, initial-scale=1") + block meta + meta(name="og:title", content="Icy Network") + meta(name="og:description", content="Icy Network is a Global Network of Communities and Websites, United by a Single Login") + meta(name="og:image", content="https://icynet.eu/static/image/icynet-icon.png") + meta(name="og:type", content="website") + meta(name="twitter:card", content="summary") + meta(name="twitter:title", content="Icy Network") + meta(name="twitter:description", content="Icy Network is a Global Network of Communities and Websites, United by a Single Login") if matomo script(type="text/javascript"). var _paq = _paq || []; diff --git a/views/news/article.pug b/views/news/article.pug index 65ad88b..4e3c647 100644 --- a/views/news/article.pug +++ b/views/news/article.pug @@ -1,5 +1,18 @@ extends ../layout.pug +block meta + if article + meta(name="description", content=article.description) + meta(name="og:title", content=article.title) + meta(name="og:description", content=article.description) + meta(name="og:image", content="https://icynet.eu/static/image/icynet-icon.png") + meta(name="og:type", content="article") + meta(name="og:updated_time", content=article.updated_at) + meta(name="twitter:card", content="summary") + meta(name="twitter:title", content=article.title) + meta(name="twitter:description", content=article.description) + link(rel="alternate", href="/news/atom.xml", title="Icy Network News", type="application/atom+xml") + block append links if editing script(src="//cdnjs.cloudflare.com/ajax/libs/ckeditor/4.7.2/ckeditor.js") diff --git a/views/news/news.pug b/views/news/news.pug index f099aab..2caf28a 100644 --- a/views/news/news.pug +++ b/views/news/news.pug @@ -1,5 +1,8 @@ extends ../layout.pug +block append meta + link(rel="alternate", href="/news/atom.xml", title="Icy Network News", type="application/atom+xml") + block title |Icy Network - News