diff --git a/config.example.toml b/config.example.toml index 19f5469..d5d8808 100644 --- a/config.example.toml +++ b/config.example.toml @@ -85,3 +85,9 @@ [logger] write=true file="/var/log/icynet.log" + +# Matomo tracking +#[matomo] +# site_id= +# site_domain="icynet.eu" +# track_url="//analytics.icynet.eu/" diff --git a/documents/privacy-policy.html b/documents/privacy-policy.html index e0f84c0..20a3a65 100644 --- a/documents/privacy-policy.html +++ b/documents/privacy-policy.html @@ -1,5 +1,6 @@

Privacy Policy

+Last modified: Friday, 13 Oct 2017

By using Services of Icy Network, you acknowledge and agree to these policies.

Information We Collect and Use

Icy Network may collect and save some information about our users.

diff --git a/documents/terms-of-service.html b/documents/terms-of-service.html index 5878d56..62b97b6 100644 --- a/documents/terms-of-service.html +++ b/documents/terms-of-service.html @@ -1,5 +1,6 @@

Terms of Service

+Last modified: Wednesday, 03 Jan 2018

Please read the following Terms and Conditions carefully. By using Icy Network services, you signify that you have read, understood and agreed to be bound by these Terms and Conditions. Icy Network reserves the right to modify, replace or remove any of the Terms and Conditions written in this document at any given time without restrictions. We will try to notify you of any such amendments. If you do not agree to these Terms and Conditions, you may not use any of the services provided by Icy Network.

Separate entities owned by Icy Network may have their own Terms and Conditions which you must read and comply with.

Who May Use the Services

@@ -16,4 +17,5 @@

Credits

Google Play and the Google Play logo are trademarks of Google Inc.

Apple and the Apple logo are trademarks of Apple Inc., registered in the U.S. and other countries. App Store is a service mark of Apple Inc., registered in the U.S. and other countries.

+

Font Awesome by Dave Gandy - http://fontawesome.io

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/server/server.js b/server/server.js index 82a8549..1415559 100644 --- a/server/server.js +++ b/server/server.js @@ -53,8 +53,8 @@ app.use((req, res, next) => { }) // Add Piwik tracker if configured - if (config.piwik && config.piwik.site_id) { - res.locals.piwik = config.piwik + if (config.matomo && config.matomo.site_id) { + res.locals.matomo = config.matomo } next() diff --git a/src/script/component/OAuthClients.vue b/src/script/component/OAuthClients.vue index d049c1c..99d0a54 100644 --- a/src/script/component/OAuthClients.vue +++ b/src/script/component/OAuthClients.vue @@ -6,7 +6,7 @@ pagination(:page="pagination.page" :pages="pagination.pages" v-on:page="getClients") .list.client o-auth-client(v-for="client in clients" v-bind="client" :key="client.id") - client-modal(:show="editing != 0" @close='editing = 0', :id='editing') + client-modal(:show="editing != 0" @close='editing = 0', :id='editing')