diff --git a/package-lock.json b/package-lock.json
index 7ce74e9..8d27c9b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -77,6 +77,11 @@
}
}
},
+ "@types/node": {
+ "version": "9.4.6",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-9.4.6.tgz",
+ "integrity": "sha512-CTUtLb6WqCCgp6P59QintjHWqzf4VL1uPA27bipLAPxFqrtK1gEYllePzTICGqQ8rYsCbpnsNypXjjDzGAAjEQ=="
+ },
"JSONStream": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz",
@@ -801,6 +806,11 @@
}
}
},
+ "boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
+ },
"boom": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
@@ -1220,6 +1230,19 @@
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
"integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I="
},
+ "cheerio": {
+ "version": "1.0.0-rc.2",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.2.tgz",
+ "integrity": "sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs=",
+ "requires": {
+ "css-select": "1.2.0",
+ "dom-serializer": "0.1.0",
+ "entities": "1.1.1",
+ "htmlparser2": "3.9.2",
+ "lodash": "4.17.5",
+ "parse5": "3.0.3"
+ }
+ },
"chokidar": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
@@ -1768,6 +1791,22 @@
"resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
"integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA="
},
+ "css-select": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
+ "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
+ "requires": {
+ "boolbase": "1.0.0",
+ "css-what": "2.1.0",
+ "domutils": "1.5.1",
+ "nth-check": "1.0.1"
+ }
+ },
+ "css-what": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz",
+ "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0="
+ },
"cssnano": {
"version": "3.10.0",
"resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz",
@@ -2131,11 +2170,49 @@
"esutils": "2.0.2"
}
},
+ "dom-serializer": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
+ "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=",
+ "requires": {
+ "domelementtype": "1.1.3",
+ "entities": "1.1.1"
+ },
+ "dependencies": {
+ "domelementtype": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
+ "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs="
+ }
+ }
+ },
"domain-browser": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
"integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA=="
},
+ "domelementtype": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
+ "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI="
+ },
+ "domhandler": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz",
+ "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=",
+ "requires": {
+ "domelementtype": "1.3.0"
+ }
+ },
+ "domutils": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
+ "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
+ "requires": {
+ "dom-serializer": "0.1.0",
+ "domelementtype": "1.3.0"
+ }
+ },
"double-ended-queue": {
"version": "2.1.0-0",
"resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz",
@@ -2221,6 +2298,11 @@
}
}
},
+ "entities": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
+ "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA="
+ },
"error": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz",
@@ -5376,6 +5458,19 @@
"resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz",
"integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E="
},
+ "htmlparser2": {
+ "version": "3.9.2",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz",
+ "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=",
+ "requires": {
+ "domelementtype": "1.3.0",
+ "domhandler": "2.4.1",
+ "domutils": "1.5.1",
+ "entities": "1.1.1",
+ "inherits": "2.0.3",
+ "readable-stream": "2.3.4"
+ }
+ },
"http-errors": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
@@ -6870,6 +6965,11 @@
"timers-ext": "0.1.2"
}
},
+ "memory-cache": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz",
+ "integrity": "sha1-eJCwHVLADI68nVM+H46xfjA0hxo="
+ },
"meow": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
@@ -7634,6 +7734,14 @@
"set-blocking": "2.0.0"
}
},
+ "nth-check": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz",
+ "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=",
+ "requires": {
+ "boolbase": "1.0.0"
+ }
+ },
"num2fraction": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
@@ -8029,6 +8137,14 @@
"integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
"dev": true
},
+ "parse5": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
+ "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
+ "requires": {
+ "@types/node": "9.4.6"
+ }
+ },
"parseurl": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
@@ -9279,6 +9395,13 @@
"requires": {
"object-assign": "4.1.1",
"strict-uri-encode": "1.1.0"
+ },
+ "dependencies": {
+ "strict-uri-encode": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+ "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
+ }
}
},
"querystring": {
@@ -10567,9 +10690,9 @@
}
},
"strict-uri-encode": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
- "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
+ "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY="
},
"string-template": {
"version": "1.0.0",
diff --git a/package.json b/package.json
index f573cfa..84c4d49 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
"apicache": "^1.2.0",
"backbone": "^1.3.3",
"browserify": "^16.1.0",
+ "cheerio": "^1.0.0-rc.2",
"debug-logger": "^0.4.1",
"eslint": "^4.18.0",
"express": "^4.16.2",
@@ -31,10 +32,12 @@
"lodash": "^4.17.5",
"log4js": "^2.5.3",
"loggy": "^1.0.2",
+ "memory-cache": "^0.2.0",
"muicss": "^0.9.36",
"node-foursquare-venues": "^1.1.0",
"openweather-apis": "^3.3.5",
"request-json": "^0.6.3",
+ "strict-uri-encode": "^2.0.0",
"twitter": "^1.7.1",
"uglifyify": "^4.0.5",
"underscore": "^1.8.3",
diff --git a/server.js b/server.js
index d773a7a..95ca663 100644
--- a/server.js
+++ b/server.js
@@ -19,7 +19,7 @@ const cache = apicache.middleware;
app.use(express.static(path.join(__dirname, sitePath)));
-app.get('/weather', cache('45 minutes'), (req, res) => {
+app.get('/weather', cache('15 minutes'), (req, res) => {
if (req.query.hasOwnProperty('ll'))
weather.doGetOpenWeather(req.query.ll)
@@ -37,7 +37,7 @@ app.get('/weather', cache('45 minutes'), (req, res) => {
}
});
-app.get('/weatheralert', cache('45 minutes'), (req, res) => {
+app.get('/weatheralert', cache('15 minutes'), (req, res) => {
if (req.query.hasOwnProperty('ll'))
// weather.doGetOpenWeather(req.query.ll)
// doGetDarkSkyWeather
@@ -56,7 +56,7 @@ app.get('/weatheralert', cache('45 minutes'), (req, res) => {
}
});
-app.get('/fsexplore', cache('30 minutes'), (req, res) => {
+app.get('/fsexplore', cache('15 minutes'), (req, res) => {
if (req.query.hasOwnProperty('ll'))
foursquare.doGetFourSquareExplore(req.query.ll)
.then((d) => {
@@ -90,15 +90,40 @@ app.get('/rightbyme', cache('12 hour'), (req, res) => {
}
});
-app.get('/news', cache('30 minutes'), (req, res) => {
+app.get('/news', cache('15 minutes'), (req, res) => {
euronews.getEuroNews().then((d) => {
res.send(d);
}).catch((e) => {
- logger.error(e);
- res.status(500).send('There was an error!');
+ if (e.message === '304:Not changed') {
+ logger.info('Euronews ', e.message);
+ res.status(304).send();
+ }
+ else {
+ logger.error(e);
+ res.status(500).send('There was an error!');
+ }
});
});
+app.get('/article', (req, res) => {
+ if (req.query.hasOwnProperty('guid')) {
+ logger.debug('Beofre', req.query.guid);
+
+ euronews.getArticle(req.query.guid)
+ .then((d) => {
+ res.send(d);
+ }).catch((e) => {
+ logger.error(e);
+ res.status(500).send('There was an error!');
+ });
+ }
+ else {
+ // throw new Error('Weather: LL missing');
+ logger.warn('FS: GUID missing');
+ res.status(500).send('GUID Missing');
+ }
+});
+
app.listen(port, (err) => {
if (err)
return logger.error('Server error:', err);
diff --git a/server/euronews.js b/server/euronews.js
index 6e3348e..c81ef13 100644
--- a/server/euronews.js
+++ b/server/euronews.js
@@ -1,15 +1,24 @@
const FeedMe = require('feedme');
const fecha = require('fecha');
+const request = require('request');
const http = require('http');
+const cheerio = require('cheerio');
+
+const { reduceArticle } = require('./reducers/euronews');
const logger = require('log4js').getLogger('euronews');
+logger.level = 'debug';
module.exports = {
'getEuroNews': doGetEuroNews,
- 'render': render
+ 'render': render,
+ 'getArticle' : doGetArticle
};
+const headers = {};
+const lastGood = {};
+
class Template {
constructor(item) {
// "pubdate": "Tue, 06 Feb 2018 17:05:00 +0100",
@@ -34,16 +43,28 @@ function doGetEuroNews() {
return new Promise((resolve, reject) => {
logger.info('Retrieving Euronews Headlines..');
- http.get('http://feeds.feedburner.com/euronews/en/news/', (res) => {
+ const options = {
+ 'hostname': 'feeds.feedburner.com',
+ 'path': '/euronews/en/news/',
+ 'method': 'GET',
+ 'headers': headers
+ };
+
+ // http.get('http://feeds.feedburner.com/euronews/en/news/', (res) => {
+ http.get(options, (res) => {
const { statusCode } = res;
const contentType = res.headers['content-type'];
+ const reqLastModified = res.headers['last-modified'];
+ logger.debug(res.headers);
let error;
- if (statusCode !== 200)
+ logger.debug('contentType', contentType);
+ if (statusCode !== 200 && statusCode !== 304)
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`);
- else if (!/^text\/xml/.test(contentType))
+
+ else if (!/^text\/xml/.test(contentType) && statusCode === 200)
error = new Error('Invalid content-type.\n' +
`Expected text/xml but received ${contentType}`);
@@ -55,11 +76,51 @@ function doGetEuroNews() {
return reject(error);
}
- const parser = new FeedMe(true);
- res.pipe(parser);
- parser.on('end', () => {
- return resolve(parser.done());
- });
+ if ( statusCode === 200) {
+ headers['If-Modified-Since'] = reqLastModified;
+ const parser = new FeedMe(true);
+ res.pipe(parser);
+ parser.on('end', () => {
+ lastGood.page = parser.done();
+ logger.info('Euronews page cached');
+ // return resolve(parser.done());
+ return resolve(lastGood.page);
+ });
+ }
+ else if (statusCode === 304) {
+ logger.info('Euronews not changed');
+
+ return resolve(lastGood.page);
+ }
+ });
+ });
+}
+
+function doGetArticle(guid = '') {
+ const splitURL = /([--:\w?@%&+~#=]*\.[a-z]{2,4}\/{0,2})((?:[?&](?:\w+)=(?:\w+))+|[--:\w?@%&+~#=]+)?/g;
+ const url = splitURL.exec(decodeURI(guid));
+ logger.debug('Converting:', guid);
+ // logger.debug('Split', url);
+
+ const ampURL = `${url[1]}amp/${url[2]}`;
+
+ return new Promise(function(resolve, reject) {
+ request(ampURL, function(err, resp, body) {
+ if (err)
+ // Logger.error(err);
+ return reject(err);
+ // Throw err;
+
+ const output = reduceArticle(body);
+
+ return resolve(output);
+ }, function(error, response, body) {
+ if (response.statusCode !== 200) {
+ logger.error(response.statusCode);
+ logger.error(body);
+
+ return reject(error);
+ }
});
});
}
diff --git a/server/reducers/euronews.js b/server/reducers/euronews.js
new file mode 100644
index 0000000..7973760
--- /dev/null
+++ b/server/reducers/euronews.js
@@ -0,0 +1,37 @@
+const cheerio = require('cheerio');
+
+const logger = require('log4js').getLogger('Euronews Reducer');
+
+const { get, isEmpty } = require('lodash');
+logger.level = 'debug';
+
+const htmlTidy = /<(\/*?)(?!(em|p|br\s*\/|strong|h1|h2|h3))\w+?.+?>/gim;
+
+function reduceArticle(body = '') {
+ if (body === '') return {};
+
+ const obj = {};
+ const $ = cheerio.load(body);
+
+ const title = $('meta[property="og:title"]').attr('content');
+ const image = `http://image.silvrtree.co.uk/640,fit,q80/${ $('meta[property="og:image"]').attr('content')}`;
+
+ const stuff = $('[itemprop="articleBody"]');
+
+ const html = [];
+
+ // stuff.children().each(function () {
+ stuff.each(function () {
+ html.push($(this).html());
+ });
+
+ const outputHTML = html.join('').replace(htmlTidy, '');
+
+ obj.title = title;
+ obj.image = image;
+ obj.html = outputHTML;
+
+ return obj;
+}
+
+module.exports = { reduceArticle };
diff --git a/server/weather.js b/server/weather.js
index 557acd8..99a7dfb 100644
--- a/server/weather.js
+++ b/server/weather.js
@@ -43,7 +43,6 @@ function doGetOpenWeatherForecast(ll) {
function doGetDarkSkyWeather(ll) {
const query = `${ll}?units=uk2&exclude=daily,flags,minutely,hourly`;
- logger.debug(query);
return new Promise((resolve, reject) => {
DSclient.get(query, function(err, res, body) {
if (err || !body || !body.currently)
diff --git a/src/css/custom.scss b/src/css/custom.scss
index 95f1361..e09dcca 100644
--- a/src/css/custom.scss
+++ b/src/css/custom.scss
@@ -2,7 +2,7 @@
@import "./node_modules/muicss/lib/sass/mui/colors";
// customize MUI variables
-$mui-primary-color: mui-color('blue-grey', '500');
+$mui-primary-color: mui-color('yellow', '500');
$mui-primary-color-dark: mui-color('blue-grey', '700');
$mui-primary-color-light: mui-color('blue-grey', '100');
@@ -12,6 +12,9 @@ $mui-accent-color-light: mui-color('indigo', 'A400');
$mui-base-font-family: 'Roboto', "Helvetica Neue", Helvetica, Arial, Verdana, "Trebuchet MS";
+$mui-appbar-font-color: mui-color('black') !default;
+
+
// import MUI SASS
@import "./node_modules/muicss/lib/sass/mui";
@import "./src/css/horscroll";
@@ -308,3 +311,60 @@ li {
max-height: 100%;
max-width: 100%;
}
+
+.stop-scrolling {
+ height: 100%;
+ overflow: hidden;
+}
+
+.fullscreen {
+ position: absolute;
+ z-index: 5000;
+ top: 0;
+ left: 0;
+ height: 100vh;
+ width: 100vw;
+ background-color: mui-color('grey','300');
+ background-repeat: no-repeat;
+ background-position: center top;
+}
+
+.fillpanel {
+ width:100%;
+ height:100%;
+ background-color: mui-color('amber', '50');
+}
+
+.fullscreen .header {
+ /*position: fixed;
+ top: 0;
+ right: 0;
+ left: 0;
+ z-index: +1;
+ transition: left 0.2s;*/
+
+ position:sticky;
+}
+
+.box {
+ display: flex;
+ flex-flow: column;
+ height:100%;
+ // overflow:auto;
+}
+
+.box .headerSpacer {
+ flex: 0 1 66px;
+}
+
+.box .content {
+ flex: 1 1 auto;
+ background-color: mui-color('white');
+ overflow: auto;
+ margin-bottom: 15px;
+}
+
+.newsarticle img {
+ max-height:100%;
+ max-width:100%;
+}
diff --git a/src/v1/index.html b/src/v1/index.html
index 2f2dc47..baae939 100644
--- a/src/v1/index.html
+++ b/src/v1/index.html
@@ -7,6 +7,7 @@
Jubilee
+
diff --git a/src/v1/js/Foursquare.js b/src/v1/js/Foursquare.js
index 65d8197..f73b6a5 100644
--- a/src/v1/js/Foursquare.js
+++ b/src/v1/js/Foursquare.js
@@ -3,8 +3,8 @@ const _ = require('underscore');
const Backbone = require('backbone');
const request = require('request');
const { get } = require('lodash');
-const { reduceNearby } = require('./reducers');
-const { partOfDay } = require('./utils');
+const { reduceNearby } = require('./libs/reducers');
+const { partOfDay } = require('./libs/utils');
const FSDetailView = Backbone.View.extend({
'initialize': function(options) {
diff --git a/src/v1/js/Greet.js b/src/v1/js/Greet.js
index b01e405..97f541e 100644
--- a/src/v1/js/Greet.js
+++ b/src/v1/js/Greet.js
@@ -1,7 +1,7 @@
const $ = require('jquery');
const _ = require('underscore');
const Backbone = require('backbone');
-const { partOfDay, toHour } = require('./utils');
+const { partOfDay, toHour } = require('./libs/utils');
const GreetModel = Backbone.Model.extend({
'initialize': function() {
@@ -46,8 +46,8 @@ const GreetView = Backbone.View.extend({
console.log('>> Location has changed...');
console.log(JSON.stringify(l.changed));
- if (l.has('location')) {
- const location = l.get('location');
+ if (l.has('atHome')) {
+ const location = l.toJSON();
// console.log('location:', location);
console.log('city', location.city);
if (location.hasOwnProperty('atHome'))
diff --git a/src/v1/js/Location.js b/src/v1/js/Location.js
index 717aac6..92266f6 100644
--- a/src/v1/js/Location.js
+++ b/src/v1/js/Location.js
@@ -3,7 +3,7 @@ const Backbone = require('backbone');
const geolocation = require('geolocation');
const TimeFormat = require('hh-mm-ss');
-const { distance } = require('./utils');
+const { distance } = require('./libs/utils');
const NodeGeocoder = require('node-geocoder');
@@ -56,7 +56,7 @@ const LocationModel = Backbone.Model.extend({
// this.set('location', location);
}.bind(this));
- this.watcher = geolocation.createWatcher();
+ this.watcher = geolocation.createWatcher();
this.listenTo(this, 'change:location', this.onChange);
// this.tick();
@@ -69,8 +69,9 @@ const LocationModel = Backbone.Model.extend({
console.log('processPosition');
const { latitude, longitude, timestamp } = pos;
- const current = this.get('location');
-
+ // const current = this.get('location');
+ const current = this.toJSON();
+ // console.log('># current', current);
const options = {
'provider': 'google',
@@ -90,14 +91,15 @@ const LocationModel = Backbone.Model.extend({
const ll = `${latitude},${longitude}`;
const llFixed = `${Number.parseFloat(latitude).toFixed(3)},${Number.parseFloat(longitude).toFixed(3)}`;
const llSix = `${Number.parseFloat(latitude).toFixed(6)},${Number.parseFloat(longitude).toFixed(6)}`;
+ const llShort = `${Number.parseFloat(latitude).toFixed(1)},${Number.parseFloat(longitude).toFixed(1)}`;
const moving = true;
- const newLocation = { homeDistance, workDistance, latitude, longitude, atHome, atWork, atHomeOrWork, timestamp, ll, llFixed, llSix, moving, 'city' : '', 'cityCC':'' };
+ const newLocation = { homeDistance, workDistance, latitude, longitude, atHome, atWork, atHomeOrWork, timestamp, ll, llFixed, llSix, llShort, moving, 'city' : '', 'cityCC':'' };
// console.log('>> NewLocation', JSON.stringify(newLocation));
// const distanceFromLast = distance(current.latitude, current.longitude, latitude, longitude);
- if (!current /* || distanceFromLast > 1.5*/) {
+ if (!_.has(current, 'atHomeOrWork')) {
console.info('>> Location:geocoder request');
geocoder.reverse(latlong)
.then(function(res) {
@@ -105,9 +107,12 @@ const LocationModel = Backbone.Model.extend({
newLocation.city = res[0].city;
newLocation.cityCC = `${res[0].city},${res[0].countryCode}`;
newLocation.address = res[0].formattedAddress;
- this.set('location', newLocation);
- this.set('moving', moving);
- this.set('lastGeocode', { 'lat':latitude, 'lng':longitude, 'timestamp':timestamp });
+ // this.set('location', newLocation);
+ newLocation.lastGeocode = { 'lat':latitude, 'lng':longitude, 'timestamp':timestamp };
+ this.set( newLocation);
+ // this.set('moving', moving);
+ // this.set('lastGeocode', { 'lat':latitude, 'lng':longitude, 'timestamp':timestamp });
+ console.log('### location', this);
}.bind(this))
.catch(function(err) {
console.error(err);
@@ -124,14 +129,15 @@ const LocationModel = Backbone.Model.extend({
console.log('>> distance from last record', distanceFromLast);
// console.log('>> distanceFromLastGeocode', distanceFromLastGeocode, TimeFormat.fromMs(timestamp - lastGeocode.timestamp, 'hh:mm:ss'));
console.log('>> distanceFromLastGeocode', distanceFromLastGeocode, TimeFormat.fromMs(currentTime - lastGeocode.timestamp, 'hh:mm:ss'));
- console.log(`(currentTime:${currentTime}, timestamp:${timestamp}, lastGeocode.timestamp:${lastGeocode.timestamp})`);
- console.log('(currentTime - current.timestamp > 900000) ', (currentTime - current.timestamp > 900000));
+ // console.log(`(currentTime:${currentTime}, timestamp:${timestamp}, lastGeocode.timestamp:${lastGeocode.timestamp})`);
+ // console.log('(currentTime - current.timestamp > 900000) ', (currentTime - current.timestamp > 900000));
// if ((distanceFromLast > 0.5 && distanceFromLast < 2.0) || (timestamp - current.timestamp > 900000)) {
if ((distanceFromLast > 0.5 && distanceFromLast < 2.0) || ((currentTime - current.timestamp > 900000) && (currentTime - lastGeocode.timestamp < 1.8e+6))) {
// dont bother re geocoding
console.log('Slightly moved from previous');
- this.set('location', newLocation);
- this.set('moving', moving);
+ // this.set('location', newLocation);
+ // this.set('moving', moving);
+ this.set( newLocation);
}
else if (distanceFromLastGeocode >= 2.0 || (currentTime - lastGeocode.timestamp >= 1.8e+6) ) {
console.log('Moved from previous', (currentTime - lastGeocode.timestamp >= 1.8e+6));
@@ -142,15 +148,16 @@ const LocationModel = Backbone.Model.extend({
newLocation.cityCC = `${res[0].city},${res[0].countryCode}`;
newLocation.address = res[0].formattedAddress;
console.log('!!! Setting location...');
- this.set('location', newLocation);
- this.set('lastGeocode', { 'lat':latitude, 'lng':longitude, 'timestamp':timestamp });
- this.set('moving', moving);
-
+ // this.set('location', newLocation);
+ // this.set('lastGeocode', { 'lat':latitude, 'lng':longitude, 'timestamp':timestamp });
+ // this.set('moving', moving);
+ newLocation.lastGeocode = { 'lat':latitude, 'lng':longitude, 'timestamp':timestamp };
+ this.set( newLocation);
console.log(this);
}.bind(this))
.catch(function(err) {
console.error(err);
- this.set('location', newLocation);
+ this.set( newLocation);
});
}
}
diff --git a/src/v1/js/Nearby.js b/src/v1/js/Nearby.js
index 28a0576..2179ec6 100644
--- a/src/v1/js/Nearby.js
+++ b/src/v1/js/Nearby.js
@@ -3,8 +3,8 @@ const _ = require('underscore');
const Backbone = require('backbone');
const request = require('request');
const { get } = require('lodash');
-const { reduceNearby } = require('./reducers');
-const { toHour } = require('./utils');
+const { reduceNearby } = require('./libs/reducers');
+const { toHour } = require('./libs/utils');
const { FSDetailView } = require('./Foursquare');
@@ -102,14 +102,10 @@ const NearbyView = Backbone.View.extend({
this.fsCollection = fsCollection;
// this.model.bind('change', this.render, this);
- this.location.bind('change', this.updateLocation, this);
+ this.location.bind('change:llFixed', this.updateLocation, this);
this.$nearby = $('#nearby');
- /* this.fsCollection.on('all', function(eventName) {
- console.log(`${eventName } was triggered!`);
- });*/
-
this.fsCollection.bind('reset', this.render, this);
},
'events': {
@@ -118,10 +114,9 @@ const NearbyView = Backbone.View.extend({
'updateLocation': function(l) {
console.log('>> Nearby Location has changed...');
- if (l.has('location')) {
- const location = l.get('location');
- if (location.hasOwnProperty('atHome'))
- this.model.set(location);
+ if (l.has('atHome')) {
+ const llFixed = l.get('llFixed');
+ this.model.set('llFixed', llFixed);
}
else
console.log('>> Nearby No location yet');
diff --git a/src/v1/js/News.js b/src/v1/js/News.js
index bb88b42..c24bcdb 100644
--- a/src/v1/js/News.js
+++ b/src/v1/js/News.js
@@ -3,7 +3,7 @@ const _ = require('underscore');
const Backbone = require('backbone');
const request = require('request');
const { get } = require('lodash');
-const { reduceEuronews } = require('./reducers');
+const { reduceEuronews } = require('./libs/reducers');
const NewsItem = Backbone.Model.extend({
@@ -31,7 +31,7 @@ const newsItemView = Backbone.View.extend({
},
'attributes': function() {
return {
- 'data-id': this.model.id
+ 'data-guid': this.model.get('guid')
};
},
@@ -99,6 +99,7 @@ const NewsModel = Backbone.Model.extend({
});
const NewsView = Backbone.View.extend({
+ 'className': '',
'initialize': function(options) {
this.eventBus = options.eventBus;
this.newsCollection = newsCollection;
@@ -128,9 +129,12 @@ const NewsView = Backbone.View.extend({
this.$el.parent().show();
// console.log(this.$el.parent());
}, 'events': {
- 'click': 'doClick'
+ 'click .scrollCard': 'doClick'
}, 'doClick': function(d) {
console.log('Do click', d);
+ const id = get(d, 'currentTarget.dataset.guid', '');
+ console.log(id);
+ this.eventBus.trigger('showNews', id);
}
});
diff --git a/src/v1/js/NewsViewer.js b/src/v1/js/NewsViewer.js
new file mode 100644
index 0000000..0a27adf
--- /dev/null
+++ b/src/v1/js/NewsViewer.js
@@ -0,0 +1,96 @@
+const $ = require('jquery');
+const _ = require('underscore');
+const Backbone = require('backbone');
+const request = require('request');
+const { get, isEmpty } = require('lodash');
+const { createPanel, addPanel } = require('./libs/panel');
+
+const NewsCardModel = Backbone.Model.extend({
+ 'initialize': function() {
+ this.listenTo(this, 'change:guid', this.newGuid);
+ },
+ 'newGuid': function() {
+ console.log('>> GUID changed:', this.get('guid'));
+ this.getNews();
+ },
+ 'getNews': function() {
+ const guid = this.get('guid');
+ request({
+ 'url': `${window.loc}/article`,
+ 'method': 'GET',
+ 'qs': {
+ 'guid': guid
+ }
+ }, function(err, res, body) {
+ if (err)
+ console.error(err);
+ else{
+ // console.log(body);
+ const fsJSON = JSON.parse(body);
+ // console.log(fsJSON);
+
+ this.set('article', fsJSON);
+ console.log(body);
+ }
+ }.bind(this));
+ }
+
+});
+
+const NewsCardView = Backbone.View.extend({
+ 'initialize': function(options) {
+ this.eventBus = options.eventBus;
+
+ /* this.model.on('all', function(eventName) {
+ console.log(`${eventName } was triggered!`);
+ });*/
+
+ this.model.bind('change:article', this.doRender, this);
+ this.eventBus.on('showNews', this.showNewsPanel, this);
+ },
+
+ 'template': _.template(`
+
+
+
+
<%= title %>
+
<%= html %>
+
+
+ `),
+ 'showNewsPanel': function(guid) {
+ console.log('Showing news', guid);
+ const prevGuid = this.model.get('guid');
+
+ this.model.set('guid', guid);
+
+ this.$newPanel = createPanel({ 'title':'News', 'divId':'newsP' });
+
+ this.$el = addPanel(this.$newPanel);
+
+ this.$el.empty();
+ this.$newPanel.show();
+
+ if (prevGuid === guid)
+ this.doRender();
+ },
+ 'events': {
+ 'click .closebutton': 'doClick'
+ },
+ 'doClick': function(d) {
+ console.log('Do click', d);
+ const id = get(d, 'currentTarget', '');
+ console.log(id);
+ // this.eventBus.trigger('showNews', id);
+ },
+ 'doClose': function(d) {
+ console.log('close??');
+ },
+ 'doRender': function() {
+ this.$el.html(this.template(this.model.get('article')));
+ }
+
+});
+
+module.exports = { NewsCardModel, NewsCardView };
+
diff --git a/src/v1/js/RightByMe.js b/src/v1/js/RightByMe.js
index dc50908..af1a893 100644
--- a/src/v1/js/RightByMe.js
+++ b/src/v1/js/RightByMe.js
@@ -3,7 +3,7 @@ const _ = require('underscore');
const Backbone = require('backbone');
const request = require('request');
const { get, isEmpty } = require('lodash');
-const { maybePluralize } = require('./utils');
+const { maybePluralize } = require('./libs/utils');
const ByMeModel = Backbone.Model.extend({
'initialize': function() {
@@ -17,25 +17,37 @@ const ByMeModel = Backbone.Model.extend({
},
'onChange': function() {
// this.getByMe(); trigger when not moved for 30 seconds
- if (this.get('atHomeOrWork') !== true)
- this.timerID = setTimeout(
- () => this.getByMe(),
- 30000
- );
+ console.log('>> changedAttributes:', this.changedAttributes());
+ if (this.get('atHomeOrWork') !== true) {
+ if ( this.timerID === 0) {
+ console.log('setting timeout....');
+ clearInterval(this.timerID);
+ this.timerID = setTimeout(
+ () => this.getByMe(),
+ 30000
+ );
+ }
+ }
else {
clearInterval(this.timerID);
console.log('>> ByMe: atHomeOrWork');
}
},
'getByMe': function() {
- const llSix = this.get('llFixed');
+ const ll = this.get('ll');
+
console.info('>> ByMe:request');
+
+ clearInterval(this.timerID);
+ this.timerID = 0;
+
+ console.log(this.toJSON());
// const section = (partOfDay >= 11 && partOfDay <= 14) ? 'food' : 'topPicks';
request({
'url': `${window.loc}/rightbyme`,
'method': 'GET',
'qs': {
- 'll': llSix
+ 'll': ll
}
}, function(err, res, body) {
if (err)
@@ -109,7 +121,7 @@ const ByMeView = Backbone.View.extend({
this.location = options.location;
// this.model.bind('change', this.render, this);
- this.location.bind('change', this.updateLocation, this);
+ this.location.bind('change:llSix', this.updateLocation, this);
this.location.bind('change:atHomeOrWork', this.atHomeOrWork, this);
this.model.bind('change:byme', this.render, this);
},
@@ -117,21 +129,25 @@ const ByMeView = Backbone.View.extend({
'click .itemRow': 'doClick'
},
'atHomeOrWork': function(m) {
- console.log('>> atHomeOrWork', m);
+ const atHomeOrWork = m.get('atHomeOrWork');
+ console.log('>> atHomeOrWork', atHomeOrWork);
+ if (atHomeOrWork)
+ // We're at home so hide
+ this.$el.parent().hide();
},
'updateLocation': function(l) {
console.log('>> ByMe Location has changed...');
- if (l.has('location')) {
- const location = l.get('location');
- if (location.hasOwnProperty('atHomeOrWork')) {
- this.model.set(location);
-
- if (location.atHomeOrWork)
- // We're at home so hide
- this.$el.parent().hide();
- }
+ if (l.has('atHome')) {
+ const llSix = l.get('llSix');
+ const ll = l.get('ll');
+ const atHomeOrWork = l.get('atHomeOrWork');
+ this.model.set({ llSix, atHomeOrWork, ll });
+ if (atHomeOrWork)
+ // We're at home so hide
+ this.$el.parent().hide();
}
+
else
console.log('>> ByMe No location yet');
},
diff --git a/src/v1/js/Weather.js b/src/v1/js/Weather.js
index e0c01a4..075603f 100644
--- a/src/v1/js/Weather.js
+++ b/src/v1/js/Weather.js
@@ -3,8 +3,8 @@ const _ = require('underscore');
const Backbone = require('backbone');
const request = require('request');
const { get } = require('lodash');
-const { reduceOpenWeather } = require('./reducers');
-const { distance } = require('./utils');
+const { reduceOpenWeather } = require('./libs/reducers');
+const { distance } = require('./libs/utils');
const weatherItem = Backbone.Model.extend({
@@ -63,7 +63,7 @@ const WeatherModel = Backbone.Model.extend({
'initialize': function() {
this.weatherCollection = weatherCollection;
this.run = false;
- this.listenTo(this, 'change:ll', this.onChange);
+ this.listenTo(this, 'change:llFixed', this.onChange);
this.listenTo(this, 'change:update', this.onChange);
},
'onChange': function() {
@@ -78,7 +78,7 @@ const WeatherModel = Backbone.Model.extend({
else {
const log = this.get('log');
const timeDiff = new Date().getTime() - log.time;
-
+ console.log('this', this);
const dist = distance(log.lat, log.long, this.get('latitude'), this.get('longitude'));
console.log('Weather distance:', dist);
@@ -104,7 +104,7 @@ const WeatherModel = Backbone.Model.extend({
if (err)
console.error(err);
else {
- // console.log(body);
+ // console.log(body);
const fsJSON = JSON.parse(body);
const city = get(fsJSON, 'city.name', '');
const list = get(fsJSON, 'list', []);
@@ -147,7 +147,7 @@ const WeatherView = Backbone.View.extend({
this.wCollection = weatherCollection;
// this.model.bind('change', this.render, this);
- this.location.bind('change', this.updateLocation, this);
+ this.location.bind('change:llFixed', this.updateLocation, this);
/* this.wCollection.on('all', function(eventName) {
console.log(`${eventName } was triggered!`);
@@ -166,10 +166,11 @@ const WeatherView = Backbone.View.extend({
'updateLocation': function(l) {
console.log('>> Weather Location has changed...');
- if (l.has('location')) {
- const location = l.get('location');
- if (location.hasOwnProperty('atHome'))
- this.model.set(location);
+ if (l.has('atHome')) {
+ const llFixed = l.get('llFixed');
+ const latitude = l.get('latitude');
+ const longitude = l.get('longitude');
+ this.model.set({ llFixed, latitude, longitude });
}
else
console.log('>> Weather No location yet');
diff --git a/src/v1/js/WeatherAlert.js b/src/v1/js/WeatherAlert.js
index 74c8b0b..757edcd 100644
--- a/src/v1/js/WeatherAlert.js
+++ b/src/v1/js/WeatherAlert.js
@@ -3,9 +3,10 @@ const _ = require('underscore');
const Backbone = require('backbone');
const request = require('request');
const fecha = require('fecha');
+const TimeFormat = require('hh-mm-ss');
const { get } = require('lodash');
-const { reduceOpenWeather } = require('./reducers');
-const { distance, toHour } = require('./utils');
+const { reduceOpenWeather } = require('./libs/reducers');
+const { distance, toHour } = require('./libs/utils');
const WeatherAlertModel = Backbone.Model.extend({
'defaults': function (obj) {
@@ -19,10 +20,19 @@ const WeatherAlertModel = Backbone.Model.extend({
this.listenTo(this, 'change:ll', this.onChange);
this.listenTo(this, 'change:update', this.onChange);
},
- 'onChange': function () {
- console.log('Weather LL has changed');
+ 'onChange': function (l) {
+ console.log('WeatherAlert LL has changed');
// if distance change > 10km
// if its been an hour since last update
+ const doUpdate = _.has(this.changedAttributes(), 'update');
+ console.log('doUpdate?', doUpdate);
+
+ /*
+ console.log(m.changedAttributes());
+ console.log(_.keys(m.changedAttributes()));
+ _.has()
+
+ */
if (!this.has('log')) {
console.info('First run');
@@ -34,11 +44,11 @@ const WeatherAlertModel = Backbone.Model.extend({
const ll = this.get('ll').split(',');
const dist = distance(log.lat, log.long, ll[0], ll[1]);
- console.log('Weather distance:', dist);
+ console.log('WeatherAlert distance:', dist);
if ((dist > 5.0) && (timeDiff > 1.8e+6))
this.getWeatherAlert();
- else if (timeDiff > 3.6e+6) {
+ else if (timeDiff > 3.6e+6 || doUpdate) {
console.log('WeatherAlert hourly update');
this.getWeatherAlert();
}
@@ -79,18 +89,17 @@ const WeatherAlertModel = Backbone.Model.extend({
const log = { 'lat': ll[0], 'long': ll[1], 'time': new Date().getTime() };
- console.log('>>WeatherAlert log', log);
- this.set('log', log);
-
+ console.log('Next update in', TimeFormat.fromMs(toHour(), 'hh:mm:ss'));
this.timerID = setTimeout(
() => this.tick(),
- toHour
+ toHour(1000)
);
-
+ console.log('>>WeatherAlert log', log);
+ this.set('log', log);
// console.log(this);
},
'tick': function () {
- console.log('Set update');
+ console.log('WeatherAlert:Force update', fecha.format(new Date(), 'mediumTime'));
this.set('update', new Date().getTime());
}
@@ -108,7 +117,7 @@ const WeatherAlertView = Backbone.View.extend({
this.$title = $('#weatherAlertTitle');
// this.model.bind('change', this.render, this);
- this.location.bind('change', this.updateLocation, this);
+ this.location.bind('change:llShort', this.updateLocation, this);
this.model.bind('change:alert', this.render, this);
},
'template': _.template(`
@@ -129,11 +138,11 @@ const WeatherAlertView = Backbone.View.extend({
},
'updateLocation': function(l) {
console.log('>> WeatherAlert Location has changed...');
+ console.log('changedAttributes:', this.location.changedAttributes());
- if (l.has('location')) {
- const location = l.get('location');
- if (location.hasOwnProperty('atHome'))
- this.model.set('ll', location.llFixed);
+ if (l.has('atHome')) {
+ const llShort = l.get('llShort');
+ this.model.set('ll', llShort);
}
else
console.log('>> Weather No location yet');
diff --git a/src/v1/js/app.js b/src/v1/js/app.js
index efd0a44..8b977d5 100644
--- a/src/v1/js/app.js
+++ b/src/v1/js/app.js
@@ -1,3 +1,4 @@
+/* eslint-disable max-len */
require('muicss');
const $ = require('jquery');
const _ = require('underscore');
@@ -9,6 +10,7 @@ const { NearbyModel, NearbyView } = require('./Nearby');
const { WeatherModel, WeatherView } = require('./Weather');
const { WeatherAlertModel, WeatherAlertView } = require('./WeatherAlert');
const { NewsModel, NewsView } = require('./News');
+const { NewsCardModel, NewsCardView } = require('./NewsViewer');
const { ByMeModel, ByMeView } = require('./RightByMe');
var app = app || {};
@@ -61,6 +63,8 @@ else
app.weatherAlert = new WeatherAlertView({ 'model': new WeatherAlertModel(), 'eventBus': app.eventBus, 'location': app.locationModel, 'el':'#weatherAlert', 'viewFrame':'#viewFrame' });
+ app.newsCard = new NewsCardView({ 'model': new NewsCardModel(), 'eventBus': app.eventBus });
+
app.news = new NewsView({ 'model': new NewsModel(), 'eventBus': app.eventBus, 'el':'#news' });
app.byMe = new ByMeView({ 'model': new ByMeModel(), 'eventBus': app.eventBus, 'location': app.locationModel, 'el':'#byme' });
diff --git a/src/v1/js/libs/panel.js b/src/v1/js/libs/panel.js
new file mode 100644
index 0000000..2f9a4a3
--- /dev/null
+++ b/src/v1/js/libs/panel.js
@@ -0,0 +1,93 @@
+const $ = require('jquery');
+let panelCount = 0;
+
+function createPanel(params) {
+ const { title, divId } = params;
+ const newPanel = `
+
+
+
+ `;
+
+ const $newPanel = $(newPanel);
+ const $closeButton = $newPanel.find(`button#close_${divId}`);
+
+ $closeButton.on('click', () => {
+ doClose();
+ });
+ $newPanel.offset({ 'top': $(window).scrollTop(), 'left': 0 });
+
+ function doClose() {
+ const $body = $('body');
+ $newPanel.hide().remove();
+ console.log('panelCount', panelCount);
+ panelCount--;
+ if (panelCount === 0)
+ console.log('Removing panel stuff');
+ $body.removeClass('stop-scrolling').unbind('touchmove');
+ }
+
+ return $newPanel;
+}
+
+function addPanel($newPanel) {
+ const $body = $('body');
+ const $content = $newPanel.find('.content');
+ $body.append($newPanel);
+ if (panelCount === 0) {
+ $body.addClass('stop-scrolling');
+ $body.bind('touchmove', function(e) {
+ e.preventDefault();
+ });
+ }
+ panelCount++;
+
+
+ return $content;
+}
+
+module.exports = { createPanel, addPanel };
+
+/*
+class Template {
+ constructor(item) {
+ // "pubdate": "Tue, 06 Feb 2018 17:05:00 +0100",
+ const pubdateSrc = fecha.parse(item.pubdate, 'ddd, DD MMM YYYY HH:mm:SS ZZ');
+ const pubdate = fecha.format(pubdateSrc, 'dddd MMMM Do, YYYY');
+ const description = item.description.replace(/(\n What next for EU-UK trade relations? | Euronews \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n \n \n\n \n \n\n \n \n \n\n \n \n\n \n \n \n \n\n\n\n\n\n \n \n \n \n
\n \n
\n What next for EU-UK trade relations?\n \n
\n Business representatives mull post-Brexit trade ties at Brussels forum, as EU prepares to publish guidelines\n
\n
\n \n\n
\n \n \n \n \n \n\n 05/03/2018\n
\n \n\n
\n \n
\n
\n \n
\n \n \n \n \n\n
\n \n \n
\n\n
\n
\n\n\n
\n
Share this article
\n
\n
\n
\n\n\n
Business leaders are desperate to get some clarity on post-Brexit trading. And, as the EU prepares to publish draft guidelines, the economic impact has been the talk of the Business Europe event in Brussels.
\n
One German representative is frustrated by the uncertainty.
\n
"It will be a bit difficult to start a new agreement from scratch. If you do not use one as an example where we can add things or delete things," Dieter Kempf, President of the Federation of German Industries (BDI), told Euronews.
\n
"So my proposal be it, whatever, take Canada agreement and right off what you don\'t want and add what you want that is I think the only chance to come to an end in that short time-frame."
\n
\n
\n\n\n\n\n \n \n
Stay united The EU\'s chief Brexit negotiator Michel Barnier took to the stage - and is calling on all to stand together under the cloudy Brexit sky.
\n
"Stay together to prepare together because the same issues are common to all, and stay united to preserve our common, social and economic capital which is the single market," Barnier said.
\n
The clock\'s ticking, with talks on future relations due to end in October.
\n\n
\n
\n\n \n\n
\n \n
Share this article
\n
\n
\n \n\n \n \n
\n
\n
\n\n\n \n \n \n \n \n \n \n \n \n\n\n\n\n\n \n \n \n\n\n