Compare commits

..

No commits in common. "development" and "Forecast_stuff" have entirely different histories.

112 changed files with 13681 additions and 51363 deletions

View File

@ -27,7 +27,7 @@
"func-names": 1,
"indent": ["error", 2, { "SwitchCase": 1 }],
"lines-around-comment": ["error", { "beforeBlockComment": true, "allowArrayStart": true }],
"max-len": [1, 180, 2], // 2 spaces per tab, max 80 chars per line
"max-len": [1, 120, 2], // 2 spaces per tab, max 80 chars per line
"new-cap": 1,
"newline-before-return": "error",
"no-array-constructor": 1,

1
.gitignore vendored
View File

@ -145,4 +145,3 @@ fabric.properties
/src/bundle.js
/src/bundle.js.map
/live/
!/output/

File diff suppressed because it is too large Load Diff

View File

@ -15,14 +15,6 @@
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.fa-xs {
font-size: .75em; }
.fa-sm {
font-size: .875em; }
/* makes the font 33% larger relative to the icon container */
.fa-lg {
font-size: 1.33333333em;
@ -211,23 +203,3 @@
.fa-home:before {
content: "\EA1E"
}
.fa-location-arrow:before {
content: "\EA76"
}
.fa-map-marker:before {
content: "\EA3D"
}
.fa-map-marker-hollow:before {
content: "\EA3E"
}
.fa-direction-filled:before {
content: "\E9D6"
}
.fa-direction-hollow:before {
content: "\E9D7"
}

View File

@ -1,31 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="fujicons.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<p>fa-back <i class=" fa fa-back"></i> </p>
<p>.fa-forward <i class=" fa fa-forward"></i> </p>
<p>.fa-globe <i class=" fa fa-globe"></i> <i class="fa"></i></p>
<p>.fa-up <i class=" fa fa-up"></i> </p>
<p>.fa-down <i class=" fa fa-down"></i> </p>
<p>.fa-work <i class=" fa fa-work"></i> </p>
<p>.fa-home <i class=" fa fa-home"></i> </p>
<p>.fa-location-arrow <i class=" fa fa-location-arrow"></i> </p>
<p>.fa-map-marker <i class=" fa fa-map-marker"></i> </p>
</body>
</html>

View File

@ -32,32 +32,10 @@ gulp.task('bundleBackbone', function () {
.pipe(gulp.dest('./live/js'));
});
gulp.task('liveBackbone', function () {
// set up the browserify instance on a task basis
const b = browserify({
'debug': true,
'entries': './src/v1/js/app.js'
});
return b.bundle()
.pipe(source('app.js'))
.pipe(buffer())
.pipe(stripDebug())
.pipe(rename('bundle.js'))
.pipe(sourcemaps.init({ 'loadMaps': true }))
// Add transformation tasks to the pipeline here.
// .pipe(uglify())
.on('error', gutil.log)
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('./live/js'));
});
gulp.task('bump', function() {
gulp.src('src/service-worker.js')
.pipe(bump({ 'key': 'version' }))
.pipe(gulp.dest('src'))
.pipe(gulp.dest('live'));
.pipe(gulp.dest('src'));
});
gulp.task('buildBackbone', ['bump', 'bundleBackbone'], function() {

View File

@ -1,14 +1,16 @@
const gulp = require('gulp');
const autoprefixer = require('gulp-autoprefixer');
const cssnano = require('gulp-cssnano');
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
const concat = require('gulp-concat');
const cache = require('gulp-cache');
const htmlmin = require('gulp-htmlmin');
const inject = require('gulp-inject');
const del = require('del');
const htmlreplace = require('gulp-html-replace');
const gulp = require('gulp'),
autoprefixer = require('gulp-autoprefixer'),
cssnano = require('gulp-cssnano'),
uglify = require('gulp-uglify'),
rename = require('gulp-rename'),
concat = require('gulp-concat'),
cache = require('gulp-cache'),
htmlmin = require('gulp-htmlmin'),
inject = require('gulp-inject'),
del = require('del'),
htmlreplace = require('gulp-html-replace');
const scss = require('gulp-scss');
const sass = require('gulp-sass');
@ -54,13 +56,13 @@ gulp.task('vendor', function() {
.pipe(concat('vendor.js'))
/* .pipe(uglify({ 'mangle': false }))*/
.pipe(gulp.dest('live/js'));
.pipe(gulp.dest(`live/js`));
});
gulp.task('fonts', function() {
return gulp.src('src/fonts.list')
.pipe(googleWebFonts(fontOptions))
.pipe(gulp.dest('live/fonts'))
.pipe(gulp.dest(`live/fonts`))
;
});
@ -69,6 +71,7 @@ gulp.task('gotham', function() {
gulp.src(['fonts/GothamSSm-Black.otf', 'fonts/GothamSSm-Bold.otf', 'fonts/GothamSSm-Book.otf', 'fonts/GothamSSm-Light.otf', 'fonts/GothamSSm-Medium.otf']).pipe(gulp.dest('live/fonts'));
});
gulp.task('fujicons', function() {
gulp.src(['fonts/fujicons.css']).pipe(gulp.dest('live/fonts'));
gulp.src(['fonts/fujicons.ttf']).pipe(gulp.dest('live/fonts'));

View File

@ -5,5 +5,3 @@ const requireDir = require('require-dir');
requireDir('./gulp');
gulp.task('default', ['bundleBackbone', 'styles', 'copy', 'customMUI', 'vendor', 'fonts', 'gotham', 'fujicons']);
gulp.task('live', ['liveBackbone', 'styles', 'copy', 'customMUI', 'vendor', 'fonts', 'gotham', 'fujicons']);

View File

@ -1,20 +0,0 @@
# Use root/example as user/password credentials
version: '3.1'
services:
mongo:
image: mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
mongo-express:
image: mongo-express
restart: always
ports:
- 8081:8081
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWORD: example

View File

@ -1,269 +0,0 @@
{
"@lang": "en-US",
"ResultSet": {
"@version": "2.0",
"@lang": "en-US",
"Error": "0",
"ErrorMessage": "No error",
"Locale": "en-US",
"Result": {
"yahoo_driving_directions": {
"routeHandle": "0",
"address": [
{
"type": "Origin",
"lat": "55.872407",
"lon": "-3.549003",
"line1": "",
"line2": "",
"line3": "",
"line4": "",
"country": ""
},
{
"type": "Destination",
"lat": "55.942673",
"lon": "-4.556334",
"line1": "",
"line2": "",
"line3": "",
"line4": "",
"country": ""
}
],
"total_distance": "81363",
"total_time": "62.0",
"total_time_with_traffic": "68.0",
"boundingbox": {
"north": "55.942587",
"south": "55.832605",
"east": "-3.540913",
"west": "-4.556462"
},
"route_id": "AIIACAAAAB4AAABSAAAAmQAAAJ4AAAB42mOYx8DAxMQABBVvKmufOO1OZ4CCuPnVYiuYF9kw/P8PEfiwnwEJcAHxoivLljMxFHUfqmnjPQHXaBBfI+bCsMgKj8bvHSxVjECL4YJpsZcOdANpUXaGwzI1DFxASQYJBicgCQAvuB+Jc1TTsQ==",
"directions": {
"route_leg": [
{
"@type": "PrivateRouteLeg",
"number": "1",
"lat": "55.872313",
"lon": "-3.547393",
"distance": "98",
"description": "Head northeast. Go for 98 m.",
"time": "0",
"time_with_traffic": "0",
"turn_angle": "0",
"exit_num": "",
"man_type": "0",
"street": ", "
},
{
"@type": "PrivateRouteLeg",
"number": "2",
"lat": "55.872978",
"lon": "-3.546385",
"distance": "252",
"description": "Take the 3rd exit from roundabout. Go for 252 m.",
"time": "1",
"time_with_traffic": "1",
"turn_angle": "-90",
"exit_num": "",
"man_type": "29",
"street": ", "
},
{
"@type": "PrivateRouteLeg",
"number": "3",
"lat": "55.872967",
"lon": "-3.543209",
"distance": "127",
"description": "Take the 2nd exit from Brotherton Roundabout roundabout. Go for 127 m.",
"time": "1",
"time_with_traffic": "1",
"turn_angle": "-90",
"exit_num": "",
"man_type": "29",
"street": ", "
},
{
"@type": "PrivateRouteLeg",
"number": "4",
"lat": "55.873493",
"lon": "-3.541557",
"distance": "2453",
"description": "Take the 1st exit from Rosebank Roundabout roundabout onto Simpson Parkway. Go for 2.5 km.",
"time": "3",
"time_with_traffic": "3",
"turn_angle": "-90",
"exit_num": "",
"man_type": "29",
"street": ", SIMPSON PARKWAY"
},
{
"@type": "PrivateRouteLeg",
"number": "5",
"lat": "55.885177",
"lon": "-3.557704",
"distance": "432",
"description": "Turn left onto A705. Go for 432 m.",
"time": "1",
"time_with_traffic": "1",
"turn_angle": "-90",
"exit_num": "",
"man_type": "9",
"street": "A705, "
},
{
"@type": "PrivateRouteLeg",
"number": "6",
"lat": "55.886142",
"lon": "-3.563454",
"distance": "623",
"description": "Take the 2nd exit from Toll Roundabout roundabout onto Starlaw Road (A779). Go for 623 m.",
"time": "1",
"time_with_traffic": "1",
"turn_angle": "-90",
"exit_num": "",
"man_type": "29",
"street": "A779, STARLAW ROAD"
},
{
"@type": "PrivateRouteLeg",
"number": "7",
"lat": "55.889865",
"lon": "-3.570009",
"distance": "1652",
"description": "Take the 1st exit from Tailend Roundabout roundabout onto Starlaw Road (A779). Go for 1.7 km.",
"time": "2",
"time_with_traffic": "2",
"turn_angle": "-90",
"exit_num": "",
"man_type": "29",
"street": "A779, STARLAW ROAD"
},
{
"@type": "PrivateRouteLeg",
"number": "8",
"lat": "55.890005",
"lon": "-3.596199",
"distance": "49437",
"description": "Take the 1st exit from Starlaw West Roundabout roundabout onto M8 toward Glasgow. Go for 49.4 km.",
"time": "33",
"time_with_traffic": "33",
"turn_angle": "-90",
"exit_num": "",
"man_type": "29",
"street": "M8, ",
"sign": "Glasgow"
},
{
"@type": "PrivateRouteLeg",
"number": "9",
"lat": "55.84886",
"lon": "-4.306791",
"distance": "14959",
"description": "Keep right onto M8. Go for 15.0 km.",
"time": "10",
"time_with_traffic": "10",
"turn_angle": "30",
"exit_num": "",
"man_type": "23",
"street": "M8, "
},
{
"@type": "PrivateRouteLeg",
"number": "10",
"lat": "55.898191",
"lon": "-4.483388",
"distance": "1391",
"description": "Take exit 30 toward Erskine Bridge/Erskine/Bishopton onto M898. Go for 1.4 km.",
"time": "1",
"time_with_traffic": "1",
"turn_angle": "-30",
"exit_num": "",
"man_type": "17",
"street": "M898, ",
"sign": "Bishopton, Erskine, Erskine Bridge"
},
{
"@type": "PrivateRouteLeg",
"number": "11",
"lat": "55.90745",
"lon": "-4.473388",
"distance": "2509",
"description": "Keep right onto A898 toward Erskine Br./Glasgow/Crianlarich/(A82). Go for 2.5 km.",
"time": "2",
"time_with_traffic": "2",
"turn_angle": "30",
"exit_num": "",
"man_type": "23",
"street": "A898, ",
"sign": "(A82), Crianlarich, Erskine Br., Glasgow"
},
{
"@type": "PrivateRouteLeg",
"number": "12",
"lat": "55.923564",
"lon": "-4.450718",
"distance": "3714",
"description": "Take ramp onto Great Western Road (A82) toward Crianlarich. Go for 3.7 km.",
"time": "3",
"time_with_traffic": "3",
"turn_angle": "-30",
"exit_num": "",
"man_type": "19",
"street": "A82, GREAT WESTERN ROAD",
"sign": "Crianlarich"
},
{
"@type": "PrivateRouteLeg",
"number": "13",
"lat": "55.931783",
"lon": "-4.502968",
"distance": "1656",
"description": "Take the 2nd exit from Dunglass Roundabout roundabout onto Dumbarton Road (A82) toward Crianlarich/Dumbarton. Go for 1.7 km.",
"time": "2",
"time_with_traffic": "2",
"turn_angle": "-90",
"exit_num": "",
"man_type": "29",
"street": "A82, DUMBARTON ROAD",
"sign": "Crianlarich, Dumbarton"
},
{
"@type": "PrivateRouteLeg",
"number": "14",
"lat": "55.935098",
"lon": "-4.526989",
"distance": "2060",
"description": "Turn left onto Glasgow Road (A814) toward Dumbarton/Town Centre/H'burgh. Go for 2.1 km.",
"time": "3",
"time_with_traffic": "3",
"turn_angle": "-90",
"exit_num": "",
"man_type": "9",
"street": "A814, GLASGOW ROAD",
"sign": "Dumbarton, H'burgh, Town Centre"
},
{
"@type": "PrivateRouteLeg",
"number": "15",
"lat": "55.942587",
"lon": "-4.556462",
"distance": "0",
"description": "Arrive at Glasgow Road (A814). Your destination is on the right.",
"time": "0",
"time_with_traffic": "0",
"turn_angle": "0",
"exit_num": "",
"man_type": "2",
"street": ", "
}
]
},
"copy_right": "Copyright &copy; 2018 Yahoo! Inc. All rights reserved. &copy; Navteq"
},
"geocode_results": null
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,215 +0,0 @@
{
"response": {
"result": [
{
"cards": [
{
"card_id": "c81eac4b-4553-3d60-85a6-178968bd5065",
"rendering_engine": "custom",
"type": "NEWS_DIGEST",
"type_display_name": "News Digest",
"ttl": 1518887858,
"layout": {
"template": "news_digest"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"TIME_OF_DAY_RANGE:EVENING": 1.0,
"TIME_OF_DAY_RANGE:DINNER": 1.0,
"STREAM_TYPE:MAIN": 1.0,
"rule_score": 0.0,
"TIER": 0.0,
"score": 0.55
},
"instrumentation": {
"rid": "cifu9m5d8bg5i",
"bucket": "ga"
}
},
{
"card_id": "83a014c3-c0a4-3242-b5a8-79d011b677d6",
"rendering_engine": "custom",
"type": "WEATHER",
"type_display_name": "Weather",
"ttl": 1518887858,
"layout": {
"template": "weather"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"TIME_OF_DAY_RANGE:EVENING": 1.0,
"TIME_OF_DAY_RANGE:DINNER": 1.0,
"STREAM_TYPE:MAIN": 1.0,
"rule_score": 0.0,
"TIER": 0.0,
"score": 0.5
},
"instrumentation": {
"rid": "cifu9m5d8bg5i",
"bucket": "ga"
}
},
{
"card_id": "bcacee7a-d79a-3e4e-a5b8-77c5b6480a8c",
"rendering_engine": "custom",
"type": "CALENDAR",
"type_display_name": "Calendar",
"ttl": 1518887858,
"layout": {
"template": "calendar"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"TIME_OF_DAY_RANGE:EVENING": 1.0,
"TIME_OF_DAY_RANGE:DINNER": 1.0,
"USER_LOCATION:OTHER": 1.0,
"STREAM_TYPE:MAIN": 1.0,
"rule_score": 2.0,
"TIER": 2.0,
"score": 0.25
},
"instrumentation": {
"rid": "cifu9m5d8bg5i",
"bucket": "ga"
}
},
{
"card_id": "858aae29-ddf0-3754-b02a-39d4bfbdbeaf",
"rendering_engine": "custom",
"type": "DIRECTIONS",
"type_display_name": "Directions",
"ttl": 1518887858,
"layout": {
"template": "directions"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"TIME_OF_DAY_RANGE:EVENING": 1.0,
"TIME_OF_DAY_RANGE:DINNER": 1.0,
"DAY_OF_WEEK_RANGE:WEEKDAY": 1.0,
"DAY_OF_WEEK_RANGE:THU_TO_SAT": 1.0,
"USER_LOCATION:OTHER": 1.0,
"USER_SPEED:STILL": 1.0,
"STREAM_TYPE:MAIN": 1.0,
"rule_score": 1.0,
"TIER": 1.0,
"score": 0.25
},
"instrumentation": {
"rid": "cifu9m5d8bg5i",
"bucket": "ga"
}
},
{
"card_id": "eea4f59a-e8a2-3e12-a917-96e254c416d5",
"rendering_engine": "custom",
"type": "VENUE_CHOOSER",
"type_display_name": "Around Me",
"ttl": 1518718658,
"layout": {
"template": "venue_chooser"
},
"data": {
"venues": [
{
"name": "Platform 1",
"category": "Platform",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/travel/trainstation_64.png",
"id": "4dfb1eaad4c01451df578109",
"provider": "foursquare",
"eid": "{\"card\":\"venue\",\"id\":\"4dfb1eaad4c01451df578109\"}"
},
{
"name": "Glasgow Central Railway Station (GLC)",
"category": "Train Station",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/travel/trainstation_64.png",
"id": "4b52f481f964a5204a8b27e3",
"provider": "foursquare",
"eid": "{\"card\":\"venue\",\"id\":\"4b52f481f964a5204a8b27e3\"}"
},
{
"name": "Denholms Bar",
"category": "Bar",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/nightlife/pub_64.png",
"id": "4c87adf49062ef3b155441c6",
"provider": "foursquare",
"eid": "{\"card\":\"venue\",\"id\":\"4c87adf49062ef3b155441c6\"}"
}
]
},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"USER_LOCATION:OTHER": 1.0,
"req_longitude": -4.259,
"USER_DIST_FROM_REQ_LOC:WITHIN_800M": 1.0,
"req_latitude": 55.857998,
"STREAM_TYPE:MAIN": 1.0,
"USER_LOCATION_POI_CONFIDENCE:HIGH": 1.0,
"rule_score": 2.0,
"TIER": 2.0,
"score": 0.25
},
"instrumentation": {
"rid": "cifu9m5d8bg5i",
"bucket": "ga"
}
},
{
"card_id": "f7b4def4-2367-3de4-9d11-ac8ddc9ebd10",
"rendering_engine": "custom",
"type": "POWER_SAVE",
"type_display_name": "Battery Saver",
"ttl": 1518887859,
"layout": {
"template": "power_save"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"STREAM_TYPE:MAIN": 1.0,
"rule_score": 0.0,
"TIER": 0.0,
"score": 0.0
},
"instrumentation": {
"rid": "cifu9m5d8bg5i",
"bucket": "ga"
}
},
{
"card_id": "4b5b8c71-58d2-3f26-abce-318e3d3a01d6",
"rendering_engine": "custom",
"type": "MORNING_NIGHT",
"type_display_name": "Set Alarm",
"ttl": 1518887858,
"layout": {
"template": "morning_night"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"TIME_OF_DAY_RANGE:EVENING": 1.0,
"TIME_OF_DAY_RANGE:DINNER": 1.0,
"USER_LOCATION:OTHER": 1.0,
"USER_SPEED:STILL": 1.0,
"STREAM_TYPE:MAIN": 1.0,
"rule_score": 0.0,
"TIER": 0

View File

@ -1,15 +0,0 @@
Html Asp Web Sql Delphi Vb Vbscript Php Ajax Mysql Sqlserver Javascript Node Nodejs jobs
http://www.jobsite.co.uk/cgi-bin/advsearch?rss_feed=1&daysback=1&jbe_id=21564698
http://www.jobsite.co.uk/advancedsearch?search_referer=internal
android-app://com.stepstone.jobsite/stjs/source/searchResults/what/IT/where//radius/0/sectors//locale/en_GB
https://www.jobsite.co.uk/cgi-bin/advsearch?rss_feed=1&skill_atleast=html,%20asp,%20web,%20sql,%20delphi,%20vb,%20vbscript,%20php,%20ajax,%20mysql,%20sqlserver,%20javascript,%20intranet,%20vmware,%20virtulization&location_include=Abu%20Dhabi&compare_resolved=RE_ABUDHABI_UNITEDARABEMIRATES&compare_search=Abu%20Dhabi&jobtype=X&search_emp_mkt_cd=ALL
https://www.jobsite.co.uk/cgi-bin/advsearch?rss_feed=1&skill_atleast=html%20,%20asp%20,%20web%20,%20sql%20,%20delphi%20,%20vb%20,%20vbscript%20,%20php%20,%20ajax%20,%20mysql%20,%20sqlserver%20,%20javascript%20,%20intranet%20,%20vmware%20,%20virtulization&location_include=London&location_within=10&reqd_salary=ANY|&daysback=7&scc=UK&compare_resolved=CO_LONDON&compare_search=London&search_emp_mkt_cd=ALL

View File

@ -1,222 +0,0 @@
{
"response": {
"result": [
{
"cards": [
{
"card_id": "4b5b8c71-58d2-3f26-abce-318e3d3a01d6",
"rendering_engine": "custom",
"type": "MORNING_NIGHT",
"type_display_name": "Set Alarm",
"ttl": 1518897897,
"layout": {
"template": "morning_night"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"USER_LOCATION:OTHER": 1.0,
"USER_SPEED:STILL": 1.0,
"TIME_OF_DAY_RANGE:NIGHT": 1.0,
"STREAM_TYPE:MAIN": 1.0,
"rule_score": 3.0,
"TIER": 3.0,
"score": 0.5
},
"instrumentation": {
"rid": "266ltl1d8bpv9",
"bucket": "ga"
}
},
{
"card_id": "83a014c3-c0a4-3242-b5a8-79d011b677d6",
"rendering_engine": "custom",
"type": "WEATHER",
"type_display_name": "Weather",
"ttl": 1518897897,
"layout": {
"template": "weather"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"TIME_OF_DAY_RANGE:NIGHT": 1.0,
"STREAM_TYPE:MAIN": 1.0,
"rule_score": 3.0,
"TIER": 3.0,
"score": 0.25
},
"instrumentation": {
"rid": "266ltl1d8bpv9",
"bucket": "ga"
}
},
{
"card_id": "c81eac4b-4553-3d60-85a6-178968bd5065",
"rendering_engine": "custom",
"type": "NEWS_DIGEST",
"type_display_name": "News Digest",
"ttl": 1518897897,
"layout": {
"template": "news_digest"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"TIME_OF_DAY_RANGE:NIGHT": 1.0,
"STREAM_TYPE:MAIN": 1.0,
"rule_score": 2.0,
"TIER": 2.0,
"score": 0.25
},
"instrumentation": {
"rid": "266ltl1d8bpv9",
"bucket": "ga"
}
},
{
"card_id": "bcacee7a-d79a-3e4e-a5b8-77c5b6480a8c",
"rendering_engine": "custom",
"type": "CALENDAR",
"type_display_name": "Calendar",
"ttl": 1518897897,
"layout": {
"template": "calendar"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"USER_LOCATION:OTHER": 1.0,
"TIME_OF_DAY_RANGE:NIGHT": 1.0,
"STREAM_TYPE:MAIN": 1.0,
"rule_score": 2.0,
"TIER": 2.0,
"score": 0.25
},
"instrumentation": {
"rid": "266ltl1d8bpv9",
"bucket": "ga"
}
},
{
"card_id": "eea4f59a-e8a2-3e12-a917-96e254c416d5",
"rendering_engine": "custom",
"type": "VENUE_CHOOSER",
"type_display_name": "Around Me",
"ttl": 1518728697,
"layout": {
"template": "venue_chooser"
},
"data": {
"venues": [
{
"name": "Partick Railway Station (PTK)",
"category": "Train Station",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/travel/trainstation_64.png",
"id": "4bbdf6ae4e069c74805b9fe3",
"provider": "foursquare",
"eid": "{\"card\":\"venue\",\"id\":\"4bbdf6ae4e069c74805b9fe3\"}"
},
{
"name": "Caffe Monza",
"category": "Coffee Shop",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/food/coffeeshop_64.png",
"id": "57ff424738fa621fceda6354",
"provider": "foursquare",
"eid": "{\"card\":\"venue\",\"id\":\"57ff424738fa621fceda6354\"}"
},
{
"name": "Stumps",
"category": "Pub",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/nightlife/pub_64.png",
"id": "4be1afa3edbb0f47e852a615",
"provider": "foursquare",
"eid": "{\"card\":\"venue\",\"id\":\"4be1afa3edbb0f47e852a615\"}"
}
]
},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"USER_LOCATION:OTHER": 1.0,
"req_longitude": -4.311023,
"USER_DIST_FROM_REQ_LOC:WITHIN_800M": 1.0,
"req_latitude": 55.869877,
"STREAM_TYPE:MAIN": 1.0,
"USER_LOCATION_POI_CONFIDENCE:HIGH": 1.0,
"rule_score": 2.0,
"TIER": 2.0,
"score": 0.25
},
"instrumentation": {
"rid": "266ltl1d8bpv9",
"bucket": "ga"
}
},
{
"card_id": "f7b4def4-2367-3de4-9d11-ac8ddc9ebd10",
"rendering_engine": "custom",
"type": "POWER_SAVE",
"type_display_name": "Battery Saver",
"ttl": 1518897897,
"layout": {
"template": "power_save"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"STREAM_TYPE:MAIN": 1.0,
"rule_score": 0.0,
"TIER": 0.0,
"score": 0.0
},
"instrumentation": {
"rid": "266ltl1d8bpv9",
"bucket": "ga"
}
},
{
"card_id": "858aae29-ddf0-3754-b02a-39d4bfbdbeaf",
"rendering_engine": "custom",
"type": "DIRECTIONS",
"type_display_name": "Directions",
"ttl": 1518897897,
"layout": {
"template": "directions"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"DAY_OF_WEEK_RANGE:WEEKDAY": 1.0,
"DAY_OF_WEEK_RANGE:THU_TO_SAT": 1.0,
"USER_LOCATION:OTHER": 1.0,
"USER_SPEED:STILL": 1.0,
"TIME_OF_DAY_RANGE:NIGHT": 1.0,
"STREAM_TYPE:MAIN": 1.0,
"rule_score": 1.0,
"TIER": 1.0,
"score": 0.0
},
"instrumentation": {
"rid": "266ltl1d8bpv9",
"bucket": "ga"
}
},
{
"card_id": "730f79c6-148d-39fd-bba1-1b3eafb8b6dc",
"rendering_engine": "custom",
"type": "MUSIC_PLAYING",
"t

View File

@ -1,76 +0,0 @@
{
"response": {
"result": [
{
"cards": [
{
"card_id": "9953c0e9-5b77-3162-bcf4-e19fcd1f541f",
"rendering_engine": "custom",
"type": "VENUE_INFO",
"type_display_name": "Venues",
"ttl": 1518744771,
"layout": {
"template": "venue_info"
},
"data": {
"name": "Domino's Pizza",
"category": "Pizza Place",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/food/pizza_64.png",
"id": "4bd2ca67a8b3a5939481685f",
"provider": "foursquare",
"tips": [
"Could really go a pizza",
"Bad for you but tastes so good!",
"Buy one get one free on collection yum!",
"Buy lots of food.It's yummy."
],
"images": [
"https://igx.4sqi.net/img/general/720x960/43992547_D3zLGLyZqgoVeL5Xy2ILve8FLR0Up7W55WgNJCvxylA.jpg",
"https://igx.4sqi.net/img/general/720x960/43992547_Lh1JDRDPQaWV197w64T27RAcB5GVepqKmXex5RvQ0FM.jpg"
],
"telephone": "",
"address": "Unit 3 Glasgow Rd",
"city": "Dumbarton",
"state": "West Dunbartonshire",
"zip": "G82 1QZ",
"latitude": 55.94369145249164,
"longitude": -4.561211789354899,
"twitter": {
"handle": "dominos_uk",
"viewIntent": "https://twitter.com/dominos_uk#Intent;action=android.intent.action.VIEW;package=com.twitter.android;end",
"tweetIntent": "#Intent;action=android.intent.action.SEND;component=com.twitter.android/.PostActivity;S.android.intent.extra.TEXT=@dominos_uk;end"
},
"yelp": {
"url": null,
"rating": 0.0,
"reviewCount": 0,
"viewIntent": null
}
},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"poi_latitude": 55.94369145249164,
"poi_longitude": -4.561211789354899,
"USER_LOCATION:OTHER": 1.0,
"req_longitude": -4.558437,
"req_latitude": 55.942837,
"USER_LOCATION_POI_CONFIDENCE:HIGH": 1.0,
"STREAM_TYPE": 1.0,
"rule_score": 0.0,
"TIER": 0.0,
"USER_DIST_FROM_REQ_LOC:WITHIN_100M": 1.0,
"score": 0.0
},
"instrumentation": {
"rid": "adbqe4hd8c9lj",
"bucket": "ga"
}
}
]
}
],
"error": null
}
}

View File

@ -1,68 +0,0 @@
{
"response": {
"result": [
{
"cards": [
{
"card_id": "9953c0e9-5b77-3162-bcf4-e19fcd1f541f",
"rendering_engine": "custom",
"type": "VENUE_INFO",
"type_display_name": "Venues",
"ttl": 1518745024,
"layout": {
"template": "venue_info"
},
"data": {
"name": "Delhi Darbar",
"category": "Indian Restaurant",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/food/indian_64.png",
"id": "4d2cbd3fae3a8cfaa6d9be70",
"provider": "foursquare",
"tips": [],
"images": [],
"telephone": "",
"address": "151 glasgow road",
"city": "Dumbarton",
"state": "West Dunbartonshire",
"zip": "G82 1RE",
"latitude": 55.94228694015362,
"longitude": -4.555356528181545,
"twitter": {
"handle": null,
"viewIntent": null,
"tweetIntent": null
},
"yelp": {
"url": "https://m.yelp.com/biz/delhi-darbar-dumbarton?adjust_creative=ogmBMO91tbdmscbTIaQEdA&utm_campaign=yelp_api&utm_medium=api_v2_search&utm_source=ogmBMO91tbdmscbTIaQEdA",
"rating": 2.0,
"reviewCount": 1,
"viewIntent": "https://m.yelp.com/biz/delhi-darbar-dumbarton?adjust_creative=ogmBMO91tbdmscbTIaQEdA&utm_campaign=yelp_api&utm_medium=api_v2_search&utm_source=ogmBMO91tbdmscbTIaQEdA#Intent;action=android.intent.action.VIEW;end"
}
},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"poi_latitude": 55.94228694015362,
"poi_longitude": -4.555356528181545,
"USER_LOCATION:OTHER": 1.0,
"req_longitude": -4.558437,
"req_latitude": 55.942837,
"USER_LOCATION_POI_CONFIDENCE:HIGH": 1.0,
"STREAM_TYPE": 1.0,
"rule_score": 0.0,
"TIER": 0.0,
"USER_DIST_FROM_REQ_LOC:WITHIN_100M": 1.0,
"score": 0.0
},
"instrumentation": {
"rid": "79o0u8pd8c9tf",
"bucket": "ga"
}
}
]
}
],
"error": null
}
}

View File

@ -1,151 +0,0 @@
{
"response": {
"result": [
{
"cards": [
{
"card_id": "7d5a35d4-a188-3960-abc6-20c671a12680",
"rendering_engine": "dunkv2",
"type": "MOVIE",
"type_display_name": "Movie",
"ttl": 1518971992,
"layout": {
"template": "movie"
},
"data": {
"releaseDate": {
"label": "Release Date",
"value": [
{
"text": "Feb 16, 2018"
}
]
},
"showtimes": {
"showtimes": [
{
"cinema": "Cinemark Movie Bistro and XD",
"times": [
{
"time": "18:00",
"url": "http://www.fandango.com/redirect.aspx?a=12215&dte=0&tid=AAXRY&tmid=162611&date=2018-02-17+18:00"
},
{
"time": "19:30",
"url": "http://www.fandango.com/redirect.aspx?a=12215&dte=0&tid=AAXRY&tmid=162611&date=2018-02-17+19:30"
},
{
"time": "20:30",
"url": "http://www.fandango.com/redirect.aspx?a=12215&dte=0&tid=AAXRY&tmid=162611&date=2018-02-17+20:30"
},
{
"time": "22:00",
"url": "http://www.fandango.com/redirect.aspx?a=12215&dte=0&tid=AAXRY&tmid=162611&date=2018-02-17+22:00"
},
{
"time": "23:45",
"url": "http://www.fandango.com/redirect.aspx?a=12215&dte=0&tid=AAXRY&tmid=162611&date=2018-02-17+23:45"
}
]
}
],
"seeMoreUrl": "http://www.fandango.com/"
},
"bio": {
"text": null,
"source": "Wikipedia",
"sourceUrl": "http://en.wikipedia.org/wiki/Black_Panther_(film)"
},
"rating": {
"rating": "97%",
"freshness": "fresh"
},
"director": {
"label": "Director",
"value": [
{
"text": "Ryan Coogler",
"url": "e5c88296-1312-4f17-b3aa-4b1a97f31aea"
}
]
},
"header": {
"title": "Black Panther",
"image": "http://d.yimg.com/sr/imgv1/1/4b9b0d15-2a77-3873-9387-0d258fdb555f"
},
"movieMeta": {
"meta": [
{
"text": "PG"
},
{
"text": "2h 14m"
},
{
"text": "Action"
}
]
}
},
"modules": [
{
"ref": [
"header"
],
"type": "header"
},
{
"ref": [
"rating"
],
"type": "ratingRottenTomatoRow"
},
{
"ref": [
"bio"
],
"type": "textWithSource"
},
{
"ref": [
"movieMeta"
],
"type": "movieInfo"
},
{
"ref": [
"releaseDate"
],
"type": "detailsWithText"
},
{
"ref": [
"director"
],
"type": "detailsWithText"
},
{
"ref": [
"showtimes"
],
"type": "showtimes"
}
],
"reason": "",
"notify": false,
"ranking_arguments": {
"rule_score": 0.0,
"TIER": 0.0,
"score": 0.0
},
"instrumentation": {
"rid": "2krc5vdd8gmmo",
"bucket": "ga"
}
}
]
}
],
"error": null
}
}

View File

@ -1,74 +0,0 @@
{
"tasks": {
"result": [
{
"type": "Night",
"confidence": 1.0,
"id": "night_default",
"payload": {
"type": "Default",
"value": {}
},
"instrument": {
"s_bucket": "ga",
"s_rid": "feobi2dd8hhdq"
},
"actions": []
},
{
"type": "Nearby",
"confidence": 0.01,
"id": "nearby_default",
"payload": {
"type": "Nearby",
"value": [
{
"name": "Delhi Darbar",
"category": "Indian Restaurant",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/food/indian_64.png",
"fsqId": "4d2cbd3fae3a8cfaa6d9be70",
"id": "4d2cbd3fae3a8cfaa6d9be70",
"provider": "foursquare"
},
{
"name": "East End Park",
"category": "Park",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/parks_outdoors/park_64.png",
"fsqId": "4ecab8a229c22cc610227f15",
"id": "4ecab8a229c22cc610227f15",
"provider": "foursquare"
},
{
"name": "Dumbarton Centre",
"category": "Professional & Other Places",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/building/default_64.png",
"fsqId": "4e3f996b52b1a04aff33cff8",
"id": "4e3f996b52b1a04aff33cff8",
"provider": "foursquare"
}
]
},
"instrument": {
"s_bucket": "ga",
"s_rid": "feobi2dd8hhdq"
},
"actions": []
},
{
"type": "Today",
"confidence": 1.0E-4,
"id": "today_default",
"payload": {
"type": "Default",
"value": {}
},
"instrument": {
"s_bucket": "ga",
"s_rid": "feobi2dd8hhdq"
},
"actions": []
}
],
"error": null
}
}

View File

@ -1,135 +0,0 @@
{
results: [
{
address_components: [
Array
],
formatted_address: '121 Glasgow Rd, Dumbarton G82 1RG, UK',
geometry: [
Object
],
place_id: 'ChIJY8xjaZ5SiEgRs6oL__V3lcI',
types: [
Array
]
},
{
address_components: [
Array
],
formatted_address: '1 Victoria St, Dumbarton G82, UK',
geometry: [
Object
],
place_id: 'EiAxIFZpY3RvcmlhIFN0LCBEdW1iYXJ0b24gRzgyLCBVSw',
types: [
Array
]
},
{
address_components: [
Array
],
formatted_address: 'Victoria Street, Dumbarton G82 1RG, UK',
geometry: [
Object
],
place_id: 'ChIJJcT_aZ5SiEgRuyQbdHkfmRs',
types: [
Array
]
},
{
address_components: [
Array
],
formatted_address: 'Dumbarton, UK',
geometry: [
Object
],
place_id: 'ChIJOYR9KlZNiEgRYt5m5bIwG38',
types: [
Array
]
},
{
address_components: [
Array
],
formatted_address: 'Glasgow Rd, Dumbarton G82 1RG, UK',
geometry: [
Object
],
place_id: 'ChIJfWuGQp5SiEgRCG7_J16QOo0',
types: [
Array
]
},
{
address_components: [
Array
],
formatted_address: 'Dumbarton G82, UK',
geometry: [
Object
],
place_id: 'ChIJW2_v1-lSiEgRklaIXybin1I',
types: [
Array
]
},
{
address_components: [
Array
],
formatted_address: 'Dumbarton G82, UK',
geometry: [
Object
],
place_id: 'ChIJOYR9KlZNiEgRUkdFvtYVs84',
types: [
Array
]
},
{
address_components: [
Array
],
formatted_address: 'West Dunbartonshire, UK',
geometry: [
Object
],
place_id: 'ChIJKxHgqUxSiEgRILNCBhpoDAM',
types: [
Array
]
},
{
address_components: [
Array
],
formatted_address: 'Scotland, UK',
geometry: [
Object
],
place_id: 'ChIJn6HyA8TiYUgRFAfDCdj6wec',
types: [
Array
]
},
{
address_components: [
Array
],
formatted_address: 'United Kingdom',
geometry: [
Object
],
place_id: 'ChIJqZHHQhE7WgIReiWIMkOg-MQ',
types: [
Array
]
}
],
status: 'OK'
}

View File

@ -1,138 +0,0 @@
{
"city": {
"id": 2650802,
"name": "Dumbarton",
"coord": {
"lon": -4.5707,
"lat": 55.9443
},
"country": "GB",
"population": 19878
},
"cod": "200",
"message": 2.9863702,
"cnt": 5,
"list": [
{
"dt": 1519300800,
"temp": {
"day": 3.46,
"min": 1.44,
"max": 3.46,
"night": 2.18,
"eve": 2.28,
"morn": 3.46
},
"pressure": 1022.89,
"humidity": 100,
"weather": [
{
"id": 800,
"main": "Clear",
"description": "sky is clear",
"icon": "01d"
}
],
"speed": 7.82,
"deg": 172,
"clouds": 68
},
{
"dt": 1519387200,
"temp": {
"day": 3.41,
"min": 1.71,
"max": 3.89,
"night": 1.71,
"eve": 2.94,
"morn": 2.48
},
"pressure": 1022.21,
"humidity": 100,
"weather": [
{
"id": 800,
"main": "Clear",
"description": "sky is clear",
"icon": "01d"
}
],
"speed": 8.46,
"deg": 166,
"clouds": 20
},
{
"dt": 1519473600,
"temp": {
"day": 2.46,
"min": 0.05,
"max": 4.05,
"night": 0.78,
"eve": 3.49,
"morn": 0.05
},
"pressure": 1027.74,
"humidity": 100,
"weather": [
{
"id": 801,
"main": "Clouds",
"description": "few clouds",
"icon": "02d"
}
],
"speed": 7.11,
"deg": 138,
"clouds": 12
},
{
"dt": 1519560000,
"temp": {
"day": 2.46,
"min": -0.55,
"max": 3.53,
"night": -0.55,
"eve": 2.35,
"morn": 0.09
},
"pressure": 1033.6,
"humidity": 100,
"weather": [
{
"id": 800,
"main": "Clear",
"description": "sky is clear",
"icon": "01d"
}
],
"speed": 6.11,
"deg": 139,
"clouds": 0
},
{
"dt": 1519646400,
"temp": {
"day": 1.71,
"min": -1.17,
"max": 1.75,
"night": 0.38,
"eve": 1.75,
"morn": -1.17
},
"pressure": 1029.06,
"humidity": 0,
"weather": [
{
"id": 600,
"main": "Snow",
"description": "light snow",
"icon": "13d"
}
],
"speed": 3.88,
"deg": 78,
"clouds": 24,
"snow": 0.15
}
]
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,634 +0,0 @@
{
"type": "rss 2.0",
"title": "Europe | Euronews RSS ",
"link": "http://www.euronews.com",
"language": "en",
"description": "Latest news from Euronews",
"copyright": "Euronews 2018",
"lastbuilddate": "Thu, 22 Feb 2018 20:39:00 +0100",
"pubdate": "Thu, 22 Feb 2018 20:39:00 +0100",
"ttl": "30",
"image": {
"link": "http://www.euronews.net/news",
"url": "http://www.euronews.net/media/rss/logo-rss.png",
"title": "news"
},
"atom10:link": [
{
"xmlns:atom10": "http://www.w3.org/2005/Atom",
"rel": "self",
"type": "application/rss+xml",
"href": "http://feeds.feedburner.com/euronews/en/news"
},
{
"xmlns:atom10": "http://www.w3.org/2005/Atom",
"rel": "hub",
"href": "http://pubsubhubbub.appspot.com/"
}
],
"feedburner:info": {
"uri": "euronews/en/news"
},
"items": [
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "EU moves to protect online shoppers",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/3ckY5TWu9u8/eu-moves-to-protect-online-shoppers",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/eu-moves-to-protect-online-shoppers"
},
"pubdate": "Thu, 22 Feb 2018 20:39:00 +0100",
"description": "MEPs back draft law which aims to harmonise protection of online and in-store purchases<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/3ckY5TWu9u8\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/eu-moves-to-protect-online-shoppers"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Talking cash and top jobs at EU summit",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/ZYoSjipmtiI/talking-cash-and-top-jobs-at-eu-summit",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/talking-cash-and-top-jobs-at-eu-summit"
},
"pubdate": "Thu, 22 Feb 2018 19:36:00 +0100",
"description": "EU leaders gather in Brussels to discuss the future face of EU, post-Brexit<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/ZYoSjipmtiI\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/talking-cash-and-top-jobs-at-eu-summit"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Amazon Rainforest 'heading to point of no return'",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/XfCqr0V1x_I/amazon-rainforest-heading-to-point-of-no-return-",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/amazon-rainforest-heading-to-point-of-no-return-"
},
"pubdate": "Thu, 22 Feb 2018 18:57:00 +0100",
"description": "Research suggests deforestation is leading the Amazon Rainforest to the point of no return.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/XfCqr0V1x_I\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/amazon-rainforest-heading-to-point-of-no-return-"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "The battle to provide healthcare in CAR",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/WuKdSziREH8/the-battle-to-provide-healthcare-in-car",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/the-battle-to-provide-healthcare-in-car"
},
"pubdate": "Thu, 22 Feb 2018 18:10:54 +0100",
"description": "As the conflict in CAR continues, aid workers struggle to provide healthcare to mothers and newborn babies.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/WuKdSziREH8\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/the-battle-to-provide-healthcare-in-car"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Flight delays at Charles de Gaulle as Air France pilots strike",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/T4nmsfbAPDk/flight-delays-at-charles-de-gaulle-as-air-france-pilots-strike",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/flight-delays-at-charles-de-gaulle-as-air-france-pilots-strike"
},
"pubdate": "Thu, 22 Feb 2018 17:33:00 +0100",
"description": "Air France unions gather for the first time since 1993 to protest over pay.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/T4nmsfbAPDk\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/flight-delays-at-charles-de-gaulle-as-air-france-pilots-strike"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Thousands of vacant posts leave UK health service suffering",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/rEuH2EX3XTU/thousands-of-vacant-posts-leave-uk-health-service-suffering",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/thousands-of-vacant-posts-leave-uk-health-service-suffering"
},
"pubdate": "Thu, 22 Feb 2018 17:15:00 +0100",
"description": "Official figures show 100,000 posts remain unfilled.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/rEuH2EX3XTU\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/thousands-of-vacant-posts-leave-uk-health-service-suffering"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Celebrations for the Chinese Lunar New Year",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/ZJPRSXyYJQE/celebrations-for-the-chinese-lunar-new-year",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/celebrations-for-the-chinese-lunar-new-year"
},
"pubdate": "Thu, 22 Feb 2018 16:54:00 +0100",
"description": "People have come together to celebrate Chinese Lunar New Year/ Spring Festival in South and Southwest China.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/ZJPRSXyYJQE\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/celebrations-for-the-chinese-lunar-new-year"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "'Archaic' definitions of the word 'feminine' not confined to English",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/i7JbOQU2Jl0/-archaic-definitions-of-the-word-feminine-not-confined-to-english",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/-archaic-definitions-of-the-word-feminine-not-confined-to-english"
},
"pubdate": "Thu, 22 Feb 2018 16:40:00 +0100",
"description": "'Delicacy and prettiness' are both used in the English definition of the word 'feminine,' whereas in Russian 'readiness for a sacrifice' is employed. How do other Euronews languages define femininity?<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/i7JbOQU2Jl0\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/-archaic-definitions-of-the-word-feminine-not-confined-to-english"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "The worlds biggest drinkers meet the EUs toughest alcohol laws",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/UKfsQBCZjAQ/the-world-s-biggest-drinkers-meet-the-eu-s-toughest-alcohol-laws",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/the-world-s-biggest-drinkers-meet-the-eu-s-toughest-alcohol-laws"
},
"pubdate": "Thu, 22 Feb 2018 16:36:00 +0100",
"description": "What happens when you raise the drinking age and restrict opening hours in a country renowned for its heavy consumption of alcohol?<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/UKfsQBCZjAQ\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/the-world-s-biggest-drinkers-meet-the-eu-s-toughest-alcohol-laws"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Florida shooting aftermath: How media errors can make mass shootings worse: View",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/_KHVpYXsk9c/florida-shooting-aftermath-how-media-errors-can-make-mass-shootings-worse",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/florida-shooting-aftermath-how-media-errors-can-make-mass-shootings-worse"
},
"pubdate": "Thu, 22 Feb 2018 16:31:00 +0100",
"description": "As the nation engages in yet another bout of introspection, journalists must also look inward.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/_KHVpYXsk9c\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/florida-shooting-aftermath-how-media-errors-can-make-mass-shootings-worse"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Why Latvia is one of Europe's most dangerous countries to drive in",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/4Wa2i4lbYR0/why-latvia-is-one-of-europe-s-most-dangerous-countries-to-drive-in",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/why-latvia-is-one-of-europe-s-most-dangerous-countries-to-drive-in"
},
"pubdate": "Thu, 22 Feb 2018 16:30:00 +0100",
"description": "Road traffic deaths have gone down in Latvia in recent years — but the Baltic state's roads remain the most deadly compared to most European countries. Euronews explains why<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/4Wa2i4lbYR0\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/why-latvia-is-one-of-europe-s-most-dangerous-countries-to-drive-in"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Number of EU citizens leaving UK at highest level since 2008",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/NVNPinxcOHg/number-of-eu-citizens-leaving-uk-at-highest-level-since-2008",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/number-of-eu-citizens-leaving-uk-at-highest-level-since-2008"
},
"pubdate": "Thu, 22 Feb 2018 16:03:00 +0100",
"description": "New figures show net migration to the UK from EU countries continues to slide after the Brexit vote. But more people continue to come to Britain than leave.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/NVNPinxcOHg\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/number-of-eu-citizens-leaving-uk-at-highest-level-since-2008"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Nigeria rescues some of its missing schoolgirls",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/oIXBIAg8VCE/nigeria-rescues-some-of-its-missing-schoolgirls",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/nigeria-rescues-some-of-its-missing-schoolgirls"
},
"pubdate": "Thu, 22 Feb 2018 15:56:00 +0100",
"description": "Nigeria rescues some of the missing schoolgirls who are said to have been kidnapped in a raid by Boko Haram in Yobe province earlier in the week.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/oIXBIAg8VCE\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/nigeria-rescues-some-of-its-missing-schoolgirls"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Egyptian police save falling child",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/anF33G2tvQo/egyptian-polce-save-falling-child",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/egyptian-polce-save-falling-child"
},
"pubdate": "Thu, 22 Feb 2018 15:55:00 +0100",
"description": "Three Egyptian policemen saved the life of a five-year-old boy as he fell from a third-floor-balcony in the city of Assuit.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/anF33G2tvQo\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/egyptian-polce-save-falling-child"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Elephants tranquilised and 'relocated' after destroying crops",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/SBbx1uimDes/elephants-tranquilised-and-relocated-after-destroying-crops",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/elephants-tranquilised-and-relocated-after-destroying-crops"
},
"pubdate": "Thu, 22 Feb 2018 15:13:00 +0100",
"description": "A major operation has begun to transport 30 elephants to a National Park in Kenya.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/SBbx1uimDes\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/elephants-tranquilised-and-relocated-after-destroying-crops"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Anthrax scare for Prince Harry and Meghan Markle",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/ifszS87MMWQ/anthrax-scare-for-prince-harry-and-meghan-markle",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/anthrax-scare-for-prince-harry-and-meghan-markle"
},
"pubdate": "Thu, 22 Feb 2018 15:12:00 +0100",
"description": "Scotland Yard is reportedly investigating after a package containing suspicious white powder was sent to the couple at Kensington Palace<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/ifszS87MMWQ\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/anthrax-scare-for-prince-harry-and-meghan-markle"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Theresa May bids to overcome Brexit divisions at Chequers hideaway",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/8-fUUbnwLJU/theresa-may-bids-to-overcome-brexit-divisions-at-chequers-hideaway",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/theresa-may-bids-to-overcome-brexit-divisions-at-chequers-hideaway"
},
"pubdate": "Thu, 22 Feb 2018 15:09:00 +0100",
"description": "The British prime minister has convened ministers to her country residence to settle disputes that have divided her cabinet and party, and frustrated negotiators in Brussels.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/8-fUUbnwLJU\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/theresa-may-bids-to-overcome-brexit-divisions-at-chequers-hideaway"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Syria: Ex fighter calls on West to act over Turkey's Afrin assault",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/VkEK6xqlrI4/syria-ex-fighter-calls-on-west-to-act-over-turkey-s-afrin-assault",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/syria-ex-fighter-calls-on-west-to-act-over-turkey-s-afrin-assault"
},
"pubdate": "Thu, 22 Feb 2018 14:52:00 +0100",
"description": "Former YPG fighter tells Euronews Ankara is using Daesh-linked fighters<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/VkEK6xqlrI4\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/syria-ex-fighter-calls-on-west-to-act-over-turkey-s-afrin-assault"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Scientists sound off after levitating ants breakthrough",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/_lDMq3yDgk0/scientists-sound-off-after-levitating-ants-breakthrough",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/scientists-sound-off-after-levitating-ants-breakthrough"
},
"pubdate": "Thu, 22 Feb 2018 14:29:00 +0100",
"description": "Researchers in England have worked out how to use sound to suspend objects in the air, paving the way for its possible use in medicine.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/_lDMq3yDgk0\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/scientists-sound-off-after-levitating-ants-breakthrough"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Hundreds of Filipino workers leave Kuwait amid diplomatic row",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/ku4wo4ErkTM/hundreds-of-filipino-workers-leave-kuwait-amid-diplomatic-row",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/hundreds-of-filipino-workers-leave-kuwait-amid-diplomatic-row"
},
"pubdate": "Thu, 22 Feb 2018 14:00:00 +0100",
"description": "Over 300 Filipino workers left Kuwait on Wednesday, joining hundreds more who have departed the Gulf state after the body of a Filipino woman was found in a freezer.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/ku4wo4ErkTM\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/hundreds-of-filipino-workers-leave-kuwait-amid-diplomatic-row"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "UN calls for ceasefire as Ghouta bombing continues",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/mII2bfKxAMg/un-calls-for-ceasefire-as-ghouta-bombing-continues",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/un-calls-for-ceasefire-as-ghouta-bombing-continues"
},
"pubdate": "Thu, 22 Feb 2018 13:45:00 +0100",
"description": "Aid groups say Russian and Syrian warplanes have pounded the last rebel enclave for a fifth straight day hitting civilian targets<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/mII2bfKxAMg\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/un-calls-for-ceasefire-as-ghouta-bombing-continues"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Baltics are murder capital of Europe, report finds",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/lcO5R2jC-rs/baltics-are-murder-capital-of-europe-report-finds",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/baltics-are-murder-capital-of-europe-report-finds"
},
"pubdate": "Thu, 22 Feb 2018 13:29:00 +0100",
"description": "Three Baltic states saw the highest recorded intentional homicides relative to their populations in 2015, according to data from the European Commission.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/lcO5R2jC-rs\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/baltics-are-murder-capital-of-europe-report-finds"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Polluting Poland told to put its people before the coal industry",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/oCJx3El2-4Q/polluting-poland-told-to-put-its-people-before-the-coal-industry",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/polluting-poland-told-to-put-its-people-before-the-coal-industry"
},
"pubdate": "Thu, 22 Feb 2018 12:48:00 +0100",
"description": "The European Court of Justice has formally ruled Poland is breaching air pollution limits, opening the door to a possible fine if it doesnt tackle the deadly problem.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/oCJx3El2-4Q\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/polluting-poland-told-to-put-its-people-before-the-coal-industry"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Trudeau criticised over Indian trip",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/zIoCLYsiYWE/trudeau-criticised-over-indian-trip",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/trudeau-criticised-over-indian-trip"
},
"pubdate": "Thu, 22 Feb 2018 12:02:00 +0100",
"description": "Some Canadian officials have criticised Justin Trudeau for wasting taxpayers money on the visit. There's only one day of official engagements set aside to create business connections.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/zIoCLYsiYWE\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/trudeau-criticised-over-indian-trip"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Two wounded in refugee camp food rationing protest",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/efoeaTokcAc/two-wounded-in-refugee-camp-food-rationing-protest",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/two-wounded-in-refugee-camp-food-rationing-protest"
},
"pubdate": "Thu, 22 Feb 2018 11:32:02 +0100",
"description": "At least two people have been reported shot and wounded in protests over food cuts provoked by UN funding shortages.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/efoeaTokcAc\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/two-wounded-in-refugee-camp-food-rationing-protest"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Strong emotions as Florida shooting families meet Trump",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/z3z8q0rEsm0/strong-emotions-as-florida-shooting-families-meet-trump",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/strong-emotions-as-florida-shooting-families-meet-trump"
},
"pubdate": "Thu, 22 Feb 2018 10:28:00 +0100",
"description": "Anger and tears marked a White House meeting between the US President and those affected by last week's school shooting in Parkland that left 17 people dead<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/z3z8q0rEsm0\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/strong-emotions-as-florida-shooting-families-meet-trump"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Trump reveals 'cheat sheet' on empathy at meeting with shooting survivors",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/wLYweZD0N00/trump-reveals-cheat-sheet-on-empathy-at-meeting-with-shooting-survivors",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/trump-reveals-cheat-sheet-on-empathy-at-meeting-with-shooting-survivors"
},
"pubdate": "Thu, 22 Feb 2018 10:18:00 +0100",
"description": "The president accidentally revealed a cue card with scribbled phrases including &quot;I hear you&quot; during a meeting with school shooting survivors at the White House.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/wLYweZD0N00\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/trump-reveals-cheat-sheet-on-empathy-at-meeting-with-shooting-survivors"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Brexit: How do EU countries' customs plans compare with the UK?",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/0CiR7liTSi4/brexit-how-do-eu-countries-customs-plans-compare-with-the-uk-",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/brexit-how-do-eu-countries-customs-plans-compare-with-the-uk-"
},
"pubdate": "Thu, 22 Feb 2018 08:00:00 +0100",
"description": "The Netherlands and France plan to hire hundreds of new customs officers in preparation for the UKs exit from the EU. The British government prefers to wait and see.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/0CiR7liTSi4\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/brexit-how-do-eu-countries-customs-plans-compare-with-the-uk-"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Dua Lipa and Stormzy scoop top gongs at Brit Awards",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/x1E4AYDIUKE/dua-lipa-and-stormzy-scoop-top-gongs-at-brit-awards",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/dua-lipa-and-stormzy-scoop-top-gongs-at-brit-awards"
},
"pubdate": "Thu, 22 Feb 2018 07:09:00 +0100",
"description": "Dua Lipa and Stormzy, two of Britains most exciting breakthrough pop acts, have beaten much more experienced competitors to take the top prizes at the Brit awards ceremony at Londons O2 Arena.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/x1E4AYDIUKE\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/dua-lipa-and-stormzy-scoop-top-gongs-at-brit-awards"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Dozens dead after Peru bus plunges into ravine",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/3jnI2kdQ_-U/dozens-dead-after-peru-bus-plunges-into-ravine",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/dozens-dead-after-peru-bus-plunges-into-ravine"
},
"pubdate": "Thu, 22 Feb 2018 07:05:00 +0100",
"description": "At least 44 people have died after a bus veered off a highway and over cliff in Peru on Wednesday, just weeks after 52 were killed in another bus crash in the country on January 2.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/3jnI2kdQ_-U\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/dozens-dead-after-peru-bus-plunges-into-ravine"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Grenade attack launched on US embassy in Montenegro",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/vZ5LymXhcYU/grenade-attack-launched-on-us-embassy-in-montenagro",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/grenade-attack-launched-on-us-embassy-in-montenagro"
},
"pubdate": "Thu, 22 Feb 2018 06:55:00 +0100",
"description": "The suspect who threw the explosive weapon then blew themselves up, the government there has said.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/vZ5LymXhcYU\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/grenade-attack-launched-on-us-embassy-in-montenagro"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Archaelogists discover first 'Copenhageners'",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/4bRM8O-aBWk/archaelogists-discover-first-copenhageners-",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/archaelogists-discover-first-copenhageners-"
},
"pubdate": "Thu, 22 Feb 2018 06:32:00 +0100",
"description": "The bones belong to men, women and children who are believed to have lived around one thousand years ago<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/4bRM8O-aBWk\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/archaelogists-discover-first-copenhageners-"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Amnesty International criticise world leaders in Annual Report",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/QBqQrU132eo/amnesty-international-criticise-world-leaders-in-annual-report",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/amnesty-international-criticise-world-leaders-in-annual-report"
},
"pubdate": "Thu, 22 Feb 2018 06:17:00 +0100",
"description": "Amnesty International has criticised world leaders for their use of hate speech and politics of fear.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/QBqQrU132eo\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/amnesty-international-criticise-world-leaders-in-annual-report"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Soderbergh's Unsane premiers in Berlin",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/1CbHTqb-PWU/soderberg-s-unsane-premiers-in-berlin",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/soderberg-s-unsane-premiers-in-berlin"
},
"pubdate": "Thu, 22 Feb 2018 06:15:00 +0100",
"description": "Claire Foy and Joshua Leonard star in Soderbergh's psychological thriller<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/1CbHTqb-PWU\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/soderberg-s-unsane-premiers-in-berlin"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Trump: 'Arm teachers to keep schools safe'",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/EAGdP9FeXFU/trump-arm-teachers-to-keep-schools-safe-",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/22/trump-arm-teachers-to-keep-schools-safe-"
},
"pubdate": "Thu, 22 Feb 2018 05:39:00 +0100",
"description": "The president made the comment during an emotional hour-long &quot;listening session&quot; at the White House with survivors of the Parkland shooting, who urged him not to let it happen again<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/EAGdP9FeXFU\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/22/trump-arm-teachers-to-keep-schools-safe-"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "'Space for civil society continued to shrink across Europe', report says",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/ckYz6CWuDS0/-space-for-civil-society-continued-to-shrink-across-europe-report-says",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/21/-space-for-civil-society-continued-to-shrink-across-europe-report-says"
},
"pubdate": "Wed, 21 Feb 2018 21:52:00 +0100",
"description": "The Amnesty International World report reviews topics such as freedom of expression, counter-terrorism laws, immigration laws, women's rights, and minority rights.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/ckYz6CWuDS0\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/21/-space-for-civil-society-continued-to-shrink-across-europe-report-says"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "EU moves to tackle terror financing",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/zWxxf6qW7SI/eu-moves-to-tackle-terror-financing",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/21/eu-moves-to-tackle-terror-financing"
},
"pubdate": "Wed, 21 Feb 2018 19:47:00 +0100",
"description": "More capabilities wanted to investigate and track down channels financing micro terrorism<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/zWxxf6qW7SI\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/21/eu-moves-to-tackle-terror-financing"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Hungary's ranking slides in latest Corruption Perceptions Index",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/yS7wpJMnr3k/hungary-s-ranking-slides-in-latest-corruption-perceptions-index",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/21/hungary-s-ranking-slides-in-latest-corruption-perceptions-index"
},
"pubdate": "Wed, 21 Feb 2018 19:34:00 +0100",
"description": "Hungary slipped 10 points in the last six years, which the Director of Transparency International EU said should serve as a warning to other members of the bloc.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/yS7wpJMnr3k\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/21/hungary-s-ranking-slides-in-latest-corruption-perceptions-index"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "The situation in East Ghouta 'can't be described with words,' says activist",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/Gji-qGHVmCs/heavy-bombardment-hits-several-towns-in-east-ghouta",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/21/heavy-bombardment-hits-several-towns-in-east-ghouta"
},
"pubdate": "Wed, 21 Feb 2018 19:16:00 +0100",
"description": "Unprecedented levels of bombing and shelling pounded Syrias opposition-held enclave East Ghouta on Wednesday (February 21).<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/Gji-qGHVmCs\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/21/heavy-bombardment-hits-several-towns-in-east-ghouta"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Afrin: a symptom of Syria's complex conflict",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/qkTTW-gG4Es/afrin-a-symptom-of-syria-s-complex-conflict",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/21/afrin-a-symptom-of-syria-s-complex-conflict"
},
"pubdate": "Wed, 21 Feb 2018 18:07:00 +0100",
"description": "As pro-Syrian government forces enter Afrin, where Turkey has launched an offensive, there's a risk of a new confrontation<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/qkTTW-gG4Es\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/21/afrin-a-symptom-of-syria-s-complex-conflict"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Ghouta: 'We are waiting for our turn to die'",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/Xbr3aDj6_QE/ghouta-we-are-waiting-for-our-turn-to-die-",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/21/ghouta-we-are-waiting-for-our-turn-to-die-"
},
"pubdate": "Wed, 21 Feb 2018 18:05:00 +0100",
"description": "Residents in the besieged eastern Ghouta district near the Syrian capital Damascus are enduring one of the most intense bombardments of the near eight-year conflict<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/Xbr3aDj6_QE\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/21/ghouta-we-are-waiting-for-our-turn-to-die-"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "America's most-loved evangelist Billy Graham dies",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/hGNzoS4Wo2E/america-s-most-loved-evangelist-billy-graham-dies",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/21/america-s-most-loved-evangelist-billy-graham-dies"
},
"pubdate": "Wed, 21 Feb 2018 17:24:00 +0100",
"description": "Friend to 12 presidents and the first revivalist preacher to make a national impact via television and the media, he established a model for building a proseletysing church that kept the loyalty of its congregation, a model some later tele-evangelists copied to get fabulously rich.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/hGNzoS4Wo2E\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/21/america-s-most-loved-evangelist-billy-graham-dies"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Chicken emergency: Police called over KFC closures in UK",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/124yqvUr3-0/chicken-emergency-police-called-over-kfc-closures-in-uk",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/21/chicken-emergency-police-called-over-kfc-closures-in-uk"
},
"pubdate": "Wed, 21 Feb 2018 16:55:00 +0100",
"description": "Security forces have urged the public not to contact them over the fried chicken 'crisis' that has forced hundreds of KFC outlets to close<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/124yqvUr3-0\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/21/chicken-emergency-police-called-over-kfc-closures-in-uk"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "UK unemployment increases",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/G9tHNIEDxrE/uk-unemployment-increases",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/21/uk-unemployment-increases"
},
"pubdate": "Wed, 21 Feb 2018 16:51:00 +0100",
"description": "The UK jobless rate rises for the first time since 2016, but wages have risen.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/G9tHNIEDxrE\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/21/uk-unemployment-increases"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Which European languages are endangered?",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/oKV3BzWsOgQ/which-european-languages-are-endangered-",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/21/which-european-languages-are-endangered-"
},
"pubdate": "Wed, 21 Feb 2018 15:50:00 +0100",
"description": "Discover how many languages are endangered — or dead — in Europe, as UNESCO reveals its latest findings.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/oKV3BzWsOgQ\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/21/which-european-languages-are-endangered-"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Turkey warns of 'grave consequences' in Afrin",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/ApABolNu4tU/turkey-warns-of-grave-consequences-in-afrin",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/21/turkey-warns-of-grave-consequences-in-afrin"
},
"pubdate": "Wed, 21 Feb 2018 15:29:00 +0100",
"description": "Turkey warns of grave consequences across the border in Afrin after pro-Syrian government forces move into the Kurdish region.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/ApABolNu4tU\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/21/turkey-warns-of-grave-consequences-in-afrin"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Theresa May's post-Brexit wish",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/wGrf7cjDVcM/theresa-may-s-post-brexit-wish",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/21/theresa-may-s-post-brexit-wish"
},
"pubdate": "Wed, 21 Feb 2018 15:05:00 +0100",
"description": "The UK Prime Minister says she wants all EU citizens lawfully living in Britain to remain after Brexit in 2019. Theresa May is also promising a streamlined system for them to register to be able to stay.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/wGrf7cjDVcM\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/21/theresa-may-s-post-brexit-wish"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "German aide lands top job at EU Commission",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/yNhA7y1tLfc/german-aide-lands-top-job-at-eu-commission",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/21/german-aide-lands-top-job-at-eu-commission"
},
"pubdate": "Wed, 21 Feb 2018 14:42:00 +0100",
"description": "Martin Selmayr to take up reigns of Secretary-General in Brussels reshuffle<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/yNhA7y1tLfc\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/21/german-aide-lands-top-job-at-eu-commission"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "Pyeongchang 2018 round-up: Broken bones and concussion plague ski cross",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/BqxKI0ZgbuU/pyeongchang-2018-round-up-broken-bones-and-concussion-plague-ski-cross",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/21/pyeongchang-2018-round-up-broken-bones-and-concussion-plague-ski-cross"
},
"pubdate": "Wed, 21 Feb 2018 14:25:00 +0100",
"description": "The men's cross-country skiing competition saw numerous collisions between athletes, with one being carried away from the course in a stretcher.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/BqxKI0ZgbuU\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/21/pyeongchang-2018-round-up-broken-bones-and-concussion-plague-ski-cross"
},
{
"text": "\r\n \r\n \r\n \r\n \r\n \r\n ",
"title": "'Youre an idiot': Hungarys foreign minister blasts Luxembourg counterpart",
"link": "http://feedproxy.google.com/~r/euronews/en/news/~3/JRaefnp5u58/-you-re-an-idiot-hungary-s-foreign-minister-tells-his-luxembourg-counterpart",
"guid": {
"ispermalink": "false",
"text": "http://www.euronews.com/2018/02/21/-you-re-an-idiot-hungary-s-foreign-minister-tells-his-luxembourg-counterpart"
},
"pubdate": "Wed, 21 Feb 2018 14:19:00 +0100",
"description": "Hungarys foreign minister Peter Szijjarto has hit back at Jean Asselborns claims that Viktor Orban was a “dictator”.<img src=\"http://feeds.feedburner.com/~r/euronews/en/news/~4/JRaefnp5u58\" height=\"1\" width=\"1\" alt=\"\"/>",
"feedburner:origlink": "http://www.euronews.com/2018/02/21/-you-re-an-idiot-hungary-s-foreign-minister-tells-his-luxembourg-counterpart"
}
]
}

View File

@ -1,14 +0,0 @@
{ name: 'Tesco',
category: 'Grocery Store',
icon: 'https://ss3.4sqi.net/img/categories_v2/shops/food_grocery_64.png',
id: '4c5ff51213791b8d0d5c4eaf',
provider: 'foursquare',
address: '23-25 Sinclair Street, Helensburgh, Argyll and Bute, G84 8SR, United Kingdom',
city: 'Helensburgh',
state: 'Argyll and Bute',
postcode: 'G84 8SR',
twitter: 'uktescooffers',
facebook: '',
url: 'http://www.tesco.com',
latitude: 56.00348039818216,
longitude: -4.733884334564209 }

View File

@ -1,75 +0,0 @@
{
"response": {
"result": [
{
"cards": [
{
"card_id": "9953c0e9-5b77-3162-bcf4-e19fcd1f541f",
"rendering_engine": "custom",
"type": "VENUE_INFO",
"type_display_name": "Venues",
"ttl": 1519654292,
"layout": {
"template": "venue_info"
},
"data": {
"name": "Speirs Wharf",
"category": "Pool",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/parks_outdoors/pool_64.png",
"id": "5211c15a11d2c83298e7f8c2",
"provider": "foursquare",
"tips": [],
"images": [
"https://igx.4sqi.net/img/general/640x640/72939115_8s_CraZskGLT5uJz5DzRiyBvKXgy6BobQBH5u0Vcsy4.jpg",
"https://igx.4sqi.net/img/general/960x364/62519220_Z_xAdlllLg7Mb1BUt1b9G18IKTpF1jyeNqGCMo0WhRs.jpg",
"https://igx.4sqi.net/img/general/960x541/24390977_Ws2HHTyM1zKBlvejccG1BxGTt0hKBURtWQOPPxYc7IM.jpg",
"https://igx.4sqi.net/img/general/960x960/149524__j5bRwPX5zy5RmOu-uleVtQ-KekAS-rXAJLgc_JjipY.jpg",
"https://igx.4sqi.net/img/general/640x640/4894760_ZOelH_F7ljq0Mjk6Zzs7KHH8-Dn470lbq4IfFg7WGiM.jpg",
"https://igx.4sqi.net/img/general/640x640/4894760_kW7NmETQYJxkGfBBnhHhQdDHcVouBj7OWpZBbyy0OTM.jpg"
],
"telephone": "",
"address": "",
"city": "",
"state": "",
"zip": "",
"latitude": 55.872669822119796,
"longitude": -4.257480441815151,
"twitter": {
"handle": null,
"viewIntent": null,
"tweetIntent": null
},
"yelp": {
"url": null,
"rating": 0.0,
"reviewCount": 0,
"viewIntent": null
}
},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"poi_latitude": 55.872669822119796,
"poi_longitude": -4.257480441815151,
"USER_LOCATION:OTHER": 1.0,
"req_longitude": -4.2577868,
"req_latitude": 55.86399,
"USER_LOCATION_POI_CONFIDENCE:HIGH": 1.0,
"STREAM_TYPE": 1.0,
"rule_score": 0.0,
"TIER": 0.0,
"USER_DIST_FROM_REQ_LOC:WITHIN_100M": 1.0,
"score": 0.0
},
"instrumentation": {
"rid": "fn62krdd981s4",
"bucket": "ga"
}
}
]
}
],
"error": null
}
}

View File

@ -1,52 +0,0 @@
{
name: 'The Howlin\' Wolf',
category: 'Pub',
icon: 'https://ss3.4sqi.net/img/categories_v2/nightlife/pub_64.png',
id: '53220210498e48f21ce03d27',
provider: 'foursquare',
address: '100 Bath Street, Glasgow, Glasgow City, G2 2EN, United Kingdom',
city: 'Glasgow',
state: 'Glasgow City',
postcode: 'G2 2EN',
twitter: 'howlinwolfglas',
facebook: '',
url: 'http://www.thehowlinwolf.co.uk',
latitude: 55.86402651957014,
longitude: -4.258141552002198,
yelp: {
url: 'https://www.yelp.com/biz/the-howlin-wolf-glasgow?adjust_creative=s8FdwjzKWCpdbkUzShvAgg&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=s8FdwjzKWCpdbkUzShvAgg',
rating: 4,
reviewCount: 30,
viewIntent: 'https://m.yelp.com/biz/the-howlin-wolf-glasgow?adjust_creative=s8FdwjzKWCpdbkUzShvAgg&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=s8FdwjzKWCpdbkUzShvAgg'
},
images: [
'https://igx.4sqi.net/img/general/433515976_lL1o2001e_4IdVrc5rXaLN7XdRzY032ijY4Pk_tprTQ.jpg',
'https://igx.4sqi.net/img/general/416812_hnsd8kPtRy3LQqkbXsK2FZEFec4LuMAJEJuD0CIsf9M.jpg',
'https://igx.4sqi.net/img/general/4504842_DReLMGngYECDU7QOvwrhjrDaICya3tc01ZXffvSak6E.jpg',
'https://irs0.4sqi.net/img/general/351988952_cVhgBPp6YNC1tF2JmHiz7Du27Nn2yxe9l7QMjiD4rY4.jpg',
'https://igx.4sqi.net/img/general/6298052_z1DEllNhhP4rk6hmGIsK1LipUffRZdbaiBJULSdtJqo.jpg',
'https://igx.4sqi.net/img/general/38762746_H3alb1lXPtZPjjL1bpUIE8UHYa71X3iAXXLvLuhEbqg.jpg'
],
tips: [
'Thank you for the good... good music!!!!!!',
'Great music',
'Everybody was so Friendly and the food is Tasty. My First haggis 🍺🍽',
'Hamburguesa The Wolf.',
'The pizza bread starter is really tasty and the fajitas are amazing! So much chicken 😍',
'Go for the drink but stay for the live music! Great atmosphere on a lively night. There\'s better food nearby though...',
'Best burger ever! Try on the wolf burger! Hyde portion, I was able to share mine with friend!',
'Nice selection of beer and ciders. Amazing Nachos cajun chicken! Great staff with nice girls. Live music!',
'Beer and long Island ice teas',
'Great atmosphere. Large selection of beers on tap and bottle. Friendly staff and good pizza\'s on offer',
'Great music, great drinks, good prices',
'Great rock n roll pub.',
'Great live music, good food, great service, good list of wine (chilean and argentinean also)',
'Nice place - live music but only till 10 when we went. Great atmosphere, cocktail was delicious but slightly smaller than usual - friendly staff.',
'Great beer selection and atmosphere. Try the anchor steam beer.',
'Nice atmosphere, good music & drinks. Would recommend a live music night.',
'One of Bath Streets latest additions, The Howlin Wolf offers up something for the soul brother in all of us. The sticky honey barbeque wings are dy-no-mite as is the four cheese pizza.',
'Superb selection of beers, very impressed.',
'Nice place, love the central table.',
'Magnfico garito que encandilara a los más melomanos! Hilo musical de lujo, hamburguesas de muerte... Y música en directo!!!!'
]
}

View File

@ -1,38 +0,0 @@
{
"type": "Feature",
"properties": {
"track_fid": 0,
"track_seg_id": 0,
"track_seg_point_id": 0,
"ele": 2.399993896484375,
"time": "2017\/11\/02 11:33:52+00",
"magvar": null,
"geoidheight": null,
"name": null,
"cmt": null,
"desc": null,
"src": null,
"link1_href": null,
"link1_text": null,
"link1_type": null,
"link2_href": null,
"link2_text": null,
"link2_type": null,
"sym": null,
"type": null,
"fix": null,
"sat": null,
"hdop": null,
"vdop": null,
"pdop": null,
"ageofdgpsdata": null,
"dgpsid": null
},
"geometry": {
"type": "Point",
"coordinates": [
-4.570887079462409,
55.949230408295989
]
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,234 +0,0 @@
{
"currently": {
"icon": "rain",
"temperature": 2.62,
"summary": "Light Rain",
"precip": 0.99,
"precipType": "rain",
"tempMax": 3.92,
"tempMin": 1.54
},
"forcastToday": [
{
"time": "5 PM",
"icon": "cloudy",
"temp": 3.38,
"precip": 0.15
},
{
"time": "6 PM",
"icon": "cloudy",
"temp": 3.21,
"precip": 0.08
},
{
"time": "7 PM",
"icon": "cloudy",
"temp": 3.17,
"precip": 0.08
},
{
"time": "8 PM",
"icon": "cloudy",
"temp": 3.07,
"precip": 0.09
},
{
"time": "9 PM",
"icon": "cloudy",
"temp": 2.97,
"precip": 0.11
},
{
"time": "10 PM",
"icon": "cloudy",
"temp": 2.87,
"precip": 0.12
},
{
"time": "11 PM",
"icon": "cloudy",
"temp": 2.76,
"precip": 0.13
},
{
"time": "12 AM",
"icon": "cloudy",
"temp": 2.69,
"precip": 0.14
},
{
"time": "1 AM",
"icon": "partly-cloudy-night",
"temp": 2.55,
"precip": 0.12
},
{
"time": "2 AM",
"icon": "partly-cloudy-night",
"temp": 2.61,
"precip": 0.11
},
{
"time": "3 AM",
"icon": "partly-cloudy-night",
"temp": 2.66,
"precip": 0.1
},
{
"time": "4 AM",
"icon": "partly-cloudy-night",
"temp": 2.69,
"precip": 0.07
},
{
"time": "5 AM",
"icon": "partly-cloudy-night",
"temp": 2.68,
"precip": 0.08
},
{
"time": "6 AM",
"icon": "partly-cloudy-night",
"temp": 2.69,
"precip": 0.1
},
{
"time": "7 AM",
"icon": "partly-cloudy-night",
"temp": 2.71,
"precip": 0.14
},
{
"time": "8 AM",
"icon": "partly-cloudy-day",
"temp": 2.73,
"precip": 0.25
},
{
"time": "9 AM",
"icon": "cloudy",
"temp": 2.79,
"precip": 0.33
},
{
"time": "10 AM",
"icon": "cloudy",
"temp": 2.91,
"precip": 0.33
},
{
"time": "11 AM",
"icon": "cloudy",
"temp": 3.26,
"precip": 0.3
},
{
"time": "12 PM",
"icon": "cloudy",
"temp": 3.73,
"precip": 0.28
},
{
"time": "1 PM",
"icon": "cloudy",
"temp": 4.79,
"precip": 0.31
},
{
"time": "2 PM",
"icon": "partly-cloudy-day",
"temp": 5.83,
"precip": 0.35
},
{
"time": "3 PM",
"icon": "partly-cloudy-day",
"temp": 6.48,
"precip": 0.35
},
{
"time": "4 PM",
"icon": "partly-cloudy-day",
"temp": 6.36,
"precip": 0.29
},
{
"time": "5 PM",
"icon": "partly-cloudy-day",
"temp": 5.85,
"precip": 0.2
}
],
"dailyForecast": [
{
"time": "Wednesday",
"icon": "snow",
"tempHigh": 6.48,
"tempLow": 1.49,
"precip": 0.67,
"precipType": "rain"
},
{
"time": "Thursday",
"icon": "partly-cloudy-night",
"tempHigh": 7.3,
"tempLow": 2.41,
"precip": 0.58,
"precipType": "rain"
},
{
"time": "Friday",
"icon": "partly-cloudy-day",
"tempHigh": 6.74,
"tempLow": 0.01,
"precip": 0.59,
"precipType": "rain"
},
{
"time": "Saturday",
"icon": "snow",
"tempHigh": 5.78,
"tempLow": 1.51,
"precip": 0.51,
"precipType": "snow"
},
{
"time": "Sunday",
"icon": "snow",
"tempHigh": 6.12,
"tempLow": 1.58,
"precip": 0.77,
"precipType": "rain"
},
{
"time": "Monday",
"icon": "wind",
"tempHigh": 4.83,
"tempLow": 2.88,
"precip": 0.67,
"precipType": "rain"
},
{
"time": "Tuesday",
"icon": "partly-cloudy-day",
"tempHigh": 7.32,
"tempLow": 3.44,
"precip": 0.42,
"precipType": "rain"
}
],
"details": {
"summary": "Mixed precipitation today through Sunday, with temperatures rising to 7°C next Tuesday.",
"icon": "rain",
"humidity": 0.89,
"visibility": 4.88,
"uvIndex": 1,
"sunriseTime": "06:58",
"sunsetTime": "18:03",
"moonphase": "Waning gibbous",
"moonPhaseVal": 0.66,
"windSpeed": 9.23,
"pressure": 986.37
}
}

View File

@ -1,236 +0,0 @@
{
"currently": {
"icon": "partly-cloudy-night",
"temperature": 2.43,
"summary": "Mostly Cloudy",
"precip": 0,
"tempMax": 3.92,
"tempMin": 1.57,
"windBearing": 71,
"windBearingRead": "ENE"
},
"forcastToday": [
{
"time": "9 PM",
"icon": "partly-cloudy-night",
"temp": 2.42,
"precip": 0.05
},
{
"time": "10 PM",
"icon": "partly-cloudy-night",
"temp": 2.44,
"precip": 0.03
},
{
"time": "11 PM",
"icon": "partly-cloudy-night",
"temp": 2.53,
"precip": 0.05
},
{
"time": "12 AM",
"icon": "partly-cloudy-night",
"temp": 2.49,
"precip": 0.06
},
{
"time": "1 AM",
"icon": "partly-cloudy-night",
"temp": 2.41,
"precip": 0.05
},
{
"time": "2 AM",
"icon": "partly-cloudy-night",
"temp": 2.34,
"precip": 0.05
},
{
"time": "3 AM",
"icon": "partly-cloudy-night",
"temp": 2.34,
"precip": 0.06
},
{
"time": "4 AM",
"icon": "partly-cloudy-night",
"temp": 2.41,
"precip": 0.12
},
{
"time": "5 AM",
"icon": "partly-cloudy-night",
"temp": 2.54,
"precip": 0.22
},
{
"time": "6 AM",
"icon": "snow",
"temp": 2.64,
"precip": 0.28
},
{
"time": "7 AM",
"icon": "partly-cloudy-night",
"temp": 2.71,
"precip": 0.25
},
{
"time": "8 AM",
"icon": "partly-cloudy-day",
"temp": 2.73,
"precip": 0.18
},
{
"time": "9 AM",
"icon": "partly-cloudy-day",
"temp": 2.77,
"precip": 0.13
},
{
"time": "10 AM",
"icon": "partly-cloudy-day",
"temp": 2.79,
"precip": 0.13
},
{
"time": "11 AM",
"icon": "cloudy",
"temp": 2.97,
"precip": 0.15
},
{
"time": "12 PM",
"icon": "cloudy",
"temp": 3.21,
"precip": 0.17
},
{
"time": "1 PM",
"icon": "partly-cloudy-day",
"temp": 3.73,
"precip": 0.19
},
{
"time": "2 PM",
"icon": "partly-cloudy-day",
"temp": 4.29,
"precip": 0.21
},
{
"time": "3 PM",
"icon": "partly-cloudy-day",
"temp": 4.68,
"precip": 0.24
},
{
"time": "4 PM",
"icon": "partly-cloudy-day",
"temp": 4.66,
"precip": 0.29
},
{
"time": "5 PM",
"icon": "partly-cloudy-day",
"temp": 4.46,
"precip": 0.33
},
{
"time": "6 PM",
"icon": "partly-cloudy-night",
"temp": 4.09,
"precip": 0.35
},
{
"time": "7 PM",
"icon": "cloudy",
"temp": 3.82,
"precip": 0.34
},
{
"time": "8 PM",
"icon": "cloudy",
"temp": 3.45,
"precip": 0.35
},
{
"time": "9 PM",
"icon": "cloudy",
"temp": 3.17,
"precip": 0.38
}
],
"dailyForecast": [
{
"time": "Wednesday",
"icon": "snow",
"tempHigh": 4.68,
"tempLow": 1.99,
"precip": 0.65,
"precipType": "rain"
},
{
"time": "Thursday",
"icon": "partly-cloudy-day",
"tempHigh": 6.46,
"tempLow": 2.75,
"precip": 0.66,
"precipType": "rain"
},
{
"time": "Friday",
"icon": "partly-cloudy-day",
"tempHigh": 7.59,
"tempLow": 0.57,
"precip": 0.36,
"precipType": "rain"
},
{
"time": "Saturday",
"icon": "rain",
"tempHigh": 6.18,
"tempLow": 3.29,
"precip": 0.7,
"precipType": "rain"
},
{
"time": "Sunday",
"icon": "rain",
"tempHigh": 6.46,
"tempLow": 3.65,
"precip": 0.8,
"precipType": "rain"
},
{
"time": "Monday",
"icon": "rain",
"tempHigh": 7.17,
"tempLow": 3.4,
"precip": 0.83,
"precipType": "rain"
},
{
"time": "Tuesday",
"icon": "cloudy",
"tempHigh": 7.92,
"tempLow": 3.69,
"precip": 0.5,
"precipType": "rain"
}
],
"details": {
"summary": "Light rain throughout the week, with temperatures rising to 8°C next Tuesday.",
"icon": "rain",
"humidity": 0.9,
"visibility": 4.73,
"uvIndex": 1,
"sunriseTime": "06:58",
"sunsetTime": "18:03",
"moonphase": "Waning gibbous",
"moonPhaseVal": 0.66,
"windSpeed": 8.47,
"pressure": 986.7
},
"time": 1520371758
}

View File

@ -1,27 +0,0 @@
[
{
"formattedAddress": "Great Western Rd, Glasgow G60, UK",
"latitude": 55.9324385,
"longitude": -4.494635400000001,
"extra": {
"googlePlaceId": "ChIJ91nIDvJNiEgR3AFlA0Qm5uE",
"confidence": 0.7,
"premise": null,
"subpremise": null,
"neighborhood": "West Dunbartonshire",
"establishment": null
},
"administrativeLevels": {
"level2long": "West Dunbartonshire",
"level2short": "West Dunbartonshire",
"level1long": "Scotland",
"level1short": "Scotland"
},
"streetName": "Great Western Road",
"city": "Glasgow",
"country": "United Kingdom",
"countryCode": "GB",
"zipcode": "G60",
"provider": "google"
}
]

View File

@ -1,327 +0,0 @@
{
"@lang": "en-US",
"ResultSet": {
"@version": "2.0",
"@lang": "en-US",
"Error": "0",
"ErrorMessage": "No error",
"Locale": "en-US",
"Result": {
"yahoo_driving_directions": {
"routeHandle": "0",
"address": [
{
"type": "Origin",
"lat": "55.942592",
"lon": "-4.556346",
"line1": "",
"line2": "",
"line3": "",
"line4": "",
"country": ""
},
{
"type": "Destination",
"lat": "55.872443",
"lon": "-3.548992",
"line1": "",
"line2": "",
"line3": "",
"line4": "",
"country": ""
}
],
"total_distance": "83339",
"total_time": "65.0",
"total_time_with_traffic": "70.0",
"boundingbox": {
"north": "55.942587",
"south": "55.832605",
"east": "-3.541074",
"west": "-4.556462"
},
"route_id": "AIUACAAAAB4AAABRAAAAlgAAAKAAAAB42mNYwMDAxMQABI+6DtXs5zyRzgAFBvE1Yi4Mi6wY/v+HCDywZ0ACXEBs/kYnl4nhz5vK2okuu+Ea4+ZXi61gXmSDR2PShr4NjECL4YJs6Qcz5wJpB4aEhgeMQClGrglVHA4OTAw+/ADTGiAC9jefAA==",
"directions": {
"route_leg": [
{
"@type": "PrivateRouteLeg",
"number": "1",
"lat": "55.942587",
"lon": "-4.556462",
"distance": "2060",
"description": "Head toward Bruce Street on Glasgow Road (A814). Go for 2.1 km.",
"time": "3",
"time_with_traffic": "3",
"turn_angle": "0",
"exit_num": "",
"man_type": "0",
"street": "A814, GLASGOW ROAD"
},
{
"@type": "PrivateRouteLeg",
"number": "2",
"lat": "55.935098",
"lon": "-4.526989",
"distance": "1616",
"description": "Continue on Dumbarton Road (A82). Go for 1.6 km.",
"time": "2",
"time_with_traffic": "2",
"turn_angle": "0",
"exit_num": "",
"man_type": "11",
"street": "A82, DUMBARTON ROAD"
},
{
"@type": "PrivateRouteLeg",
"number": "3",
"lat": "55.931944",
"lon": "-4.503633",
"distance": "3334",
"description": "Take the 2nd exit from Dunglass Roundabout roundabout onto Great Western Road (A82) toward Glasgow/Erskine Bridge/(A898). Go for 3.3 km.",
"time": "3",
"time_with_traffic": "3",
"turn_angle": "-90",
"exit_num": "",
"man_type": "29",
"street": "A82, GREAT WESTERN ROAD",
"sign": "(A898), Erskine Bridge, Glasgow"
},
{
"@type": "PrivateRouteLeg",
"number": "4",
"lat": "55.926161",
"lon": "-4.452403",
"distance": "2919",
"description": "Take ramp onto A898 toward Erskine Bridge/Paisley/(M898). Go for 2.9 km.",
"time": "2",
"time_with_traffic": "2",
"turn_angle": "-30",
"exit_num": "",
"man_type": "19",
"street": "A898, ",
"sign": "(M898), Erskine Bridge, Paisley"
},
{
"@type": "PrivateRouteLeg",
"number": "5",
"lat": "55.910207",
"lon": "-4.472519",
"distance": "1152",
"description": "Keep right onto M898 toward Paisley/Glasgow Airport/Greenock/(M8). Go for 1.2 km.",
"time": "1",
"time_with_traffic": "1",
"turn_angle": "30",
"exit_num": "",
"man_type": "23",
"street": "M898, ",
"sign": "(M8), Glasgow Airport, Greenock, Paisley"
},
{
"@type": "PrivateRouteLeg",
"number": "6",
"lat": "55.901495",
"lon": "-4.481091",
"distance": "396",
"description": "Keep left onto M898 toward Paisley/Airports. Go for 396 m.",
"time": "0",
"time_with_traffic": "0",
"turn_angle": "-30",
"exit_num": "",
"man_type": "21",
"street": "M898, ",
"sign": "Airports, Paisley"
},
{
"@type": "PrivateRouteLeg",
"number": "7",
"lat": "55.898287",
"lon": "-4.483226",
"distance": "64579",
"description": "Keep left onto M8. Go for 64.6 km.",
"time": "42",
"time_with_traffic": "42",
"turn_angle": "-30",
"exit_num": "",
"man_type": "21",
"street": "M8, "
},
{
"@type": "PrivateRouteLeg",
"number": "8",
"lat": "55.895294",
"lon": "-3.596402",
"distance": "240",
"description": "Take exit 3A toward Bathgate/(A89)/Broxburn/Livingston West/(A779). Go for 240 m.",
"time": "0",
"time_with_traffic": "0",
"turn_angle": "-30",
"exit_num": "",
"man_type": "17",
"street": ", ",
"sign": "(A779), (A89), Bathgate, Broxburn, Livingston West"
},
{
"@type": "PrivateRouteLeg",
"number": "9",
"lat": "55.897204",
"lon": "-3.595244",
"distance": "420",
"description": "Take the 1st exit from roundabout onto Carnegie Road (A779) toward Glasgow/(M8)/Livingston/Bathgate/(A89)/Broxburn. Go for 420 m.",
"time": "1",
"time_with_traffic": "1",
"turn_angle": "-90",
"exit_num": "",
"man_type": "29",
"street": "A779, CARNEGIE ROAD",
"sign": "(A89), (M8), A779, Bathgate, Broxburn, Glasgow, Livingston"
},
{
"@type": "PrivateRouteLeg",
"number": "10",
"lat": "55.897193",
"lon": "-3.601885",
"distance": "840",
"description": "Take the 1st exit from Boghall Roundabout roundabout onto A779 toward Glasgow/(M8)/Livingston. Go for 840 m.",
"time": "1",
"time_with_traffic": "1",
"turn_angle": "-90",
"exit_num": "",
"man_type": "29",
"street": "A779, ",
"sign": "(M8), A779, Glasgow, Livingston"
},
{
"@type": "PrivateRouteLeg",
"number": "11",
"lat": "55.890466",
"lon": "-3.596713",
"distance": "1622",
"description": "Take the 1st exit from Starlaw West Roundabout roundabout onto Starlaw Road (A779) toward Livingston/Kirkton Campus/Alba Centre/Starlaw Park. Go for 1.6 km.",
"time": "2",
"time_with_traffic": "2",
"turn_angle": "-90",
"exit_num": "",
"man_type": "29",
"street": "A779, STARLAW ROAD",
"sign": "Alba Centre, Kirkton Campus, Livingston, Starlaw Park"
},
{
"@type": "PrivateRouteLeg",
"number": "12",
"lat": "55.89009",
"lon": "-3.570975",
"distance": "657",
"description": "Take the 3rd exit from Tailend Roundabout roundabout onto Starlaw Road (A779). Go for 657 m.",
"time": "1",
"time_with_traffic": "1",
"turn_angle": "-90",
"exit_num": "",
"man_type": "29",
"street": "A779, STARLAW ROAD"
},
{
"@type": "PrivateRouteLeg",
"number": "13",
"lat": "55.886743",
"lon": "-3.563787",
"distance": "486",
"description": "Take the 2nd exit from Toll Roundabout roundabout onto A705. Go for 486 m.",
"time": "1",
"time_with_traffic": "1",
"turn_angle": "-90",
"exit_num": "",
"man_type": "29",
"street": "A705, "
},
{
"@type": "PrivateRouteLeg",
"number": "14",
"lat": "55.885638",
"lon": "-3.557596",
"distance": "2131",
"description": "Turn right onto Simpson Parkway (B7015). Go for 2.1 km.",
"time": "3",
"time_with_traffic": "3",
"turn_angle": "90",
"exit_num": "",
"man_type": "13",
"street": "B7015, SIMPSON PARKWAY"
},
{
"@type": "PrivateRouteLeg",
"number": "15",
"lat": "55.876765",
"lon": "-3.542415",
"distance": "345",
"description": "Continue on Simpson Parkway. Go for 345 m.",
"time": "0",
"time_with_traffic": "0",
"turn_angle": "0",
"exit_num": "",
"man_type": "11",
"street": ", SIMPSON PARKWAY"
},
{
"@type": "PrivateRouteLeg",
"number": "16",
"lat": "55.873793",
"lon": "-3.541074",
"distance": "197",
"description": "Take the 3rd exit from Rosebank Roundabout roundabout. Go for 197 m.",
"time": "1",
"time_with_traffic": "1",
"turn_angle": "-90",
"exit_num": "",
"man_type": "29",
"street": ", "
},
{
"@type": "PrivateRouteLeg",
"number": "17",
"lat": "55.872957",
"lon": "-3.542737",
"distance": "222",
"description": "Take the 2nd exit from Brotherton Roundabout roundabout. Go for 222 m.",
"time": "1",
"time_with_traffic": "1",
"turn_angle": "-90",
"exit_num": "",
"man_type": "29",
"street": ", "
},
{
"@type": "PrivateRouteLeg",
"number": "18",
"lat": "55.873075",
"lon": "-3.546073",
"distance": "123",
"description": "Take the 1st exit from roundabout. Go for 123 m.",
"time": "0",
"time_with_traffic": "0",
"turn_angle": "-90",
"exit_num": "",
"man_type": "29",
"street": ", "
},
{
"@type": "PrivateRouteLeg",
"number": "19",
"lat": "55.872313",
"lon": "-3.547393",
"distance": "0",
"description": "Arrive at your destination.",
"time": "0",
"time_with_traffic": "0",
"turn_angle": "0",
"exit_num": "",
"man_type": "2",
"street": ", "
}
]
},
"copy_right": "Copyright &copy; 2018 Yahoo! Inc. All rights reserved. &copy; Navteq"
},
"geocode_results": null
}
}
}

View File

@ -1,74 +0,0 @@
{
"id": "53220210498e48f21ce03d27",
"name": "The Howlin' Wolf",
"category": "Pub",
"icon": "https://ss3.4sqi.net/img/categories_v2/nightlife/pub_64.png",
"provider": "foursquare",
"address": "100 Bath Street, Glasgow, Glasgow City, G2 2EN, United Kingdom",
"city": "Glasgow",
"state": "Glasgow City",
"postcode": "G2 2EN",
"twitter": "howlinwolfglas",
"facebook": "",
"url": "http://www.thehowlinwolf.co.uk",
"latitude": 55.86402651957014,
"longitude": -4.258141552002198,
"images": [
"https://igx.4sqi.net/img/general/640x480/433515976_lL1o2001e_4IdVrc5rXaLN7XdRzY032ijY4Pk_tprTQ.jpg",
"https://igx.4sqi.net/img/general/640x853/416812_hnsd8kPtRy3LQqkbXsK2FZEFec4LuMAJEJuD0CIsf9M.jpg",
"https://igx.4sqi.net/img/general/640x640/4504842_DReLMGngYECDU7QOvwrhjrDaICya3tc01ZXffvSak6E.jpg",
"https://irs0.4sqi.net/img/general/640x480/351988952_cVhgBPp6YNC1tF2JmHiz7Du27Nn2yxe9l7QMjiD4rY4.jpg",
"https://igx.4sqi.net/img/general/640x640/6298052_z1DEllNhhP4rk6hmGIsK1LipUffRZdbaiBJULSdtJqo.jpg",
"https://igx.4sqi.net/img/general/640x640/38762746_H3alb1lXPtZPjjL1bpUIE8UHYa71X3iAXXLvLuhEbqg.jpg"
],
"tips": [
"Thank you for the good... good music!!!!!!",
"Great music",
"Everybody was so Friendly and the food is Tasty. My First haggis 🍺🍽",
"Hamburguesa The Wolf.",
"The pizza bread starter is really tasty and the fajitas are amazing! So much chicken 😍",
"Go for the drink but stay for the live music! Great atmosphere on a lively night. There's better food nearby though...",
"Best burger ever! Try on the wolf burger! Hyde portion, I was able to share mine with friend!",
"Nice selection of beer and ciders. Amazing Nachos cajun chicken! Great staff with nice girls. Live music!",
"Beer and long Island ice teas",
"Great atmosphere. Large selection of beers on tap and bottle. Friendly staff and good pizza's on offer",
"Great music, great drinks, good prices",
"Great rock n roll pub.",
"Great live music, good food, great service, good list of wine (chilean and argentinean also)",
"Nice place - live music but only till 10 when we went. Great atmosphere, cocktail was delicious but slightly smaller than usual - friendly staff.",
"Great beer selection and atmosphere. Try the anchor steam beer.",
"Nice atmosphere, good music & drinks. Would recommend a live music night.",
"One of Bath Streets latest additions, The Howlin Wolf offers up something for the soul brother in all of us. The sticky honey barbeque wings are dy-no-mite as is the four cheese pizza.",
"Superb selection of beers, very impressed.",
"Nice place, love the central table.",
"Magnfico garito que encandilara a los más melomanos! Hilo musical de lujo, hamburguesas de muerte... Y música en directo!!!!"
],
"yelp": {
"url": "https://www.yelp.com/biz/the-howlin-wolf-glasgow?adjust_creative=s8FdwjzKWCpdbkUzShvAgg&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=s8FdwjzKWCpdbkUzShvAgg",
"rating": 4,
"reviewCount": 31,
"viewIntent": "https://m.yelp.com/biz/the-howlin-wolf-glasgow?adjust_creative=s8FdwjzKWCpdbkUzShvAgg&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=s8FdwjzKWCpdbkUzShvAgg"
},
"tweets": [
"The Hoojamammas will be rockin' our stage from 6pm until 8pm. Come and join in the festive fun! https://t.co/hyZq5OdKjf",
"See this? It's magic...and was recorded right here at the wolf. #blues #liveatthewolf https://t.co/QAxHNc8bVQ",
"Want... https://t.co/k9esRXRfPo",
"Its all going down right now folks!\n\nCome along and jam... https://t.co/kg74iKJ5sP",
"Do you wanna taco bout them blues?\n\nWe are willing to have that conversation this lunchtime, and we can tell its go… https://t.co/OEqEGCgmO7",
"After that Saturday, we sure as hell need a pick me up to get us howlin' again, what could be better than a blues s… https://t.co/aLk05aeUu2",
"Live music tonight! Pablo Jones is hitting our stage at 6pm, bringing you all the best blues.",
"Saturday 28th. The Witchin' Hour. Halloween event - prize for best dressed! Be there, if you dare... https://t.co/Az7kPIaYWS",
"Its Sunday... which means delicious Roast and a whole host of blues, including out jam session at 9pm... Come to pa… https://t.co/gTs6W3War0",
"Lunchtime... \n\nSweet taco salvation #blueslunch https://t.co/C0Wdl0Ul89",
"Its Sunday, which means good old roast served till 10pm... oh and all the blues you could dream of... See ya soon. https://t.co/CY9AmlJzW0",
"RT @bbnscotland: BBN Spotlight: The Queens Head Hotel is the National Award winner in the Hotel Bar category. Find out about more at: https…",
"RT @bbnscotland: BBN Spotlight: @SLTAssociation represents all sectors of the Scottish Licensed Trade Industry. Find out more: https://t.co…",
"RT @bbnscotland: Find out about what Best Bar None brings to your local nightlife, with awards schemes promoting success and safety! https:…",
"RT @bbnscotland: Some key statistics and helpful advice on the #OnePunchTwoLives campaign by @policescotland https://t.co/WhBNR5cepJ",
"Today's the day! Come and cure yourselves with some Bourbon Roast and Bourbon Bloody Marys! Perfect start to a Sund… https://t.co/vP3cPe5mjK",
"Tomorrow is the launch for our #BourbonRoast - Every Sunday an American Twist on our classic, also serving Bourbon… https://t.co/uuQeQlzRk5",
"Want to have a blues Christmas? Get in touch now!! https://t.co/JrMIOyGjg7",
"...and they did it! Well done @BagONailsGLAS we are all so proud! https://t.co/BdGgb8Ghgk",
"Just want to say good luck to our sister bar @BagONailsGLAS as they are up for Best Independent Bar at The Dram Awa… https://t.co/mnXkzNtbYo"
]
}

View File

@ -1,10 +0,0 @@
[2,1,6,26,255,76,0,2,21,172,253,6,94,195,192,17,227,155,190,26,81,73,50,172,1,0,0,4,160,194,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
[2,1,6,26,255,76,0,2,21,172,253,6,94,195,192,17,227,155,190,26,81,73,50,172,1,0,0,4,160,194,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
[2,1,6,26,255,76,0,2,21,172,253,6,94,195,192,17,227,155,190,26,81,73,50,172,1,0,0,4,160,194,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
[2,1,6,26,255,76,0,2,21,172,253,6,94,195,192,17,227,155,190,26,81,73,50,172,1,0,0,4,160,194,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
[2,1,6,3,3,170,254,20,22,170,254,16,235,1,98,108,117,101,117,112,98,101,97,99,111,110,115,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
[2,1,6,4,22,15,24,100,4,22,0,136,11,17,9,66,108,117,101,85,112,45,48,55,45,48,48,49,49,56,52,17,7,149,226,237,235,27,160,57,138,223,75,211,142,0,117,200,163,0,0,0,0,0,0,0,0,0,0,0,0,0]
[2,1,6,17,22,26,24,110,42,252,8,111,42,86,19,109,42,240,120,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
[2,1,6,3,3,170,254,20,22,170,254,16,235,1,98,108,117,101,117,112,98,101,97,99,111,110,115,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
[2,1,6,4,22,15,24,100,4,22,0,136,11,17,9,66,108,117,101,85,112,45,48,55,45,48,48,49,49,56,52,17,7,149,226,237,235,27,160,57,138,223,75,211,142,0,117,200,163,0,0,0,0,0,0,0,0,0,0,0,0,0]
[2,1,6,3,3,170,254,20,22,170,254,16,235,1,98,108,117,101,117,112,98,101,97,99,111,110,115,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

View File

@ -1,131 +0,0 @@
{
"documentation": "https://opencagedata.com/api",
"licenses": [
{
"name": "CC-BY-SA",
"url": "https://creativecommons.org/licenses/by-sa/3.0/"
},
{
"name": "ODbL",
"url": "https://opendatacommons.org/licenses/odbl/summary/"
}
],
"rate": {
"limit": 2500,
"remaining": 2476,
"reset": 1541116800
},
"results": [
{
"annotations": {
"DMS": {
"lat": "51° 30' 31.50360'' N",
"lng": "0° 4' 2.84520'' E"
},
"MGRS": "30UYC0349610480",
"Maidenhead": "IO91xm12vc",
"Mercator": {
"x": -7509.279,
"y": 6678318.702
},
"OSGB": {
"easting": 534210.466,
"gridref": "TQ 342 806",
"northing": 180638.989
},
"OSM": {
"edit_url": "https://www.openstreetmap.org/edit?node=469785883#map=17/51.50875/-0.06746",
"url": "https://www.openstreetmap.org/?mlat=51.50875&mlon=-0.06746#map=17/51.50875/-0.06746"
},
"callingcode": 44,
"currency": {
"alternate_symbols": [],
"decimal_mark": ".",
"html_entity": "&#x00A3;",
"iso_code": "GBP",
"iso_numeric": 826,
"name": "British Pound",
"smallest_denomination": 1,
"subunit": "Penny",
"subunit_to_unit": 100,
"symbol": "£",
"symbol_first": 1,
"thousands_separator": ","
},
"flag": "🇬🇧",
"geohash": "gcpvn2yuhphkj3chfu0y",
"qibla": 119.06,
"sun": {
"rise": {
"apparent": 1541055300,
"astronomical": 1541048460,
"civil": 1541053140,
"nautical": 1541050800
},
"set": {
"apparent": 1541089980,
"astronomical": 1541096760,
"civil": 1541092080,
"nautical": 1541094420
}
},
"timezone": {
"name": "Europe/London",
"now_in_dst": 0,
"offset_sec": 0,
"offset_string": 0,
"short_name": "GMT"
},
"what3words": {
"words": "paid.radio.drove"
}
},
"bounds": {
"northeast": {
"lat": 51.508851,
"lng": -0.067357
},
"southwest": {
"lat": 51.508651,
"lng": -0.067557
}
},
"components": {
"ISO_3166-1_alpha-2": "GB",
"_type": "bus_stop",
"bus_stop": "The Highway",
"city": "London",
"country": "United Kingdom",
"country_code": "gb",
"political_union": "European Union",
"postcode": "SE15",
"road": "Vaughan Way",
"road_reference": 48668,
"road_type": "bus_stop",
"state": "England",
"state_district": "Greater London",
"suburb": "St.George in the East"
},
"confidence": 9,
"formatted": "The Highway, Vaughan Way, London SE15, United Kingdom",
"geometry": {
"lat": 51.508751,
"lng": -0.067457
}
}
],
"status": {
"code": 200,
"message": "OK"
},
"stay_informed": {
"blog": "https://blog.opencagedata.com",
"twitter": "https://twitter.com/opencagedata"
},
"thanks": "For using an OpenCage Data API",
"timestamp": {
"created_http": "Thu, 01 Nov 2018 12:24:22 GMT",
"created_unix": 1541075062
},
"total_results": 1
}

View File

@ -1 +0,0 @@
{"response":{"result":[{"cards":[{"card_id":"9953c0e9-5b77-3162-bcf4-e19fcd1f541f","rendering_engine":"custom","type":"VENUE_INFO","type_display_name":"Venues","ttl":1518712127,"layout":{"template":"venue_info"},"data":{"name":"Meadow Centre","category":"Gym Pool","iconUrl":"https://ss3.4sqi.net/img/categories_v2/parks_outdoors/pool_64.png","id":"4bd49bb9cfa7b713237424da","provider":"foursquare","tips":["Great swimming pool with a wave machine every 30 minutes - but could be warmer"],"images":["https://igx.4sqi.net/img/general/6016x4016/212169387_Sk6ObrC2WhtKFKZgTQG5UDeFJr9BH1WmjhUI_qkRqlw.jpg"],"telephone":"","address":"","city":"","state":"","zip":"","latitude":55.947152440274564,"longitude":-4.564007641621031,"twitter":{"handle":null,"viewIntent":null,"tweetIntent":null},"yelp":{"url":"https://m.yelp.com/biz/meadow-leisure-centre-dumbarton?adjust_creative=ogmBMO91tbdmscbTIaQEdA&utm_campaign=yelp_api&utm_medium=api_v2_search&utm_source=ogmBMO91tbdmscbTIaQEdA","rating":3.5,"reviewCount":2,"viewIntent":"https://m.yelp.com/biz/meadow-leisure-centre-dumbarton?adjust_creative=ogmBMO91tbdmscbTIaQEdA&utm_campaign=yelp_api&utm_medium=api_v2_search&utm_source=ogmBMO91tbdmscbTIaQEdA#Intent;action=android.intent.action.VIEW;end"}},"modules":{},"reason":"","notify":false,"ranking_arguments":{"poi_latitude":55.947152440274564,"poi_longitude":-4.564007641621031,"USER_LOCATION:OTHER":1.0,"req_longitude":-4.5666,"req_latitude":55.95,"USER_LOCATION_POI_CONFIDENCE:HIGH":1.0,"STREAM_TYPE":1.0,"rule_score":0.0,"TIER":0.0,"USER_DIST_FROM_REQ_LOC:WITHIN_100M":1.0,"score":0.0},"instrumentation":{"rid":"3un9llld8b9pf","bucket":"ga"}}]}],"error":null}}

View File

@ -1,72 +0,0 @@
{
"response": {
"result": [
{
"cards": [
{
"card_id": "9953c0e9-5b77-3162-bcf4-e19fcd1f541f",
"rendering_engine": "custom",
"type": "VENUE_INFO",
"type_display_name": "Venues",
"ttl": 1518712127,
"layout": {
"template": "venue_info"
},
"data": {
"name": "Meadow Centre",
"category": "Gym Pool",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/parks_outdoors/pool_64.png",
"id": "4bd49bb9cfa7b713237424da",
"provider": "foursquare",
"tips": [
"Great swimming pool with a wave machine every 30 minutes - but could be warmer"
],
"images": [
"https://igx.4sqi.net/img/general/6016x4016/212169387_Sk6ObrC2WhtKFKZgTQG5UDeFJr9BH1WmjhUI_qkRqlw.jpg"
],
"telephone": "",
"address": "",
"city": "",
"state": "",
"zip": "",
"latitude": 55.947152440274564,
"longitude": -4.564007641621031,
"twitter": {
"handle": null,
"viewIntent": null,
"tweetIntent": null
},
"yelp": {
"url": "https://m.yelp.com/biz/meadow-leisure-centre-dumbarton?adjust_creative=ogmBMO91tbdmscbTIaQEdA&utm_campaign=yelp_api&utm_medium=api_v2_search&utm_source=ogmBMO91tbdmscbTIaQEdA",
"rating": 3.5,
"reviewCount": 2,
"viewIntent": "https://m.yelp.com/biz/meadow-leisure-centre-dumbarton?adjust_creative=ogmBMO91tbdmscbTIaQEdA&utm_campaign=yelp_api&utm_medium=api_v2_search&utm_source=ogmBMO91tbdmscbTIaQEdA#Intent;action=android.intent.action.VIEW;end"
}
},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"poi_latitude": 55.947152440274564,
"poi_longitude": -4.564007641621031,
"USER_LOCATION:OTHER": 1.0,
"req_longitude": -4.5666,
"req_latitude": 55.95,
"USER_LOCATION_POI_CONFIDENCE:HIGH": 1.0,
"STREAM_TYPE": 1.0,
"rule_score": 0.0,
"TIER": 0.0,
"USER_DIST_FROM_REQ_LOC:WITHIN_100M": 1.0,
"score": 0.0
},
"instrumentation": {
"rid": "3un9llld8b9pf",
"bucket": "ga"
}
}
]
}
],
"error": null
}
}

View File

@ -1 +0,0 @@
{"response":{"result":[{"cards":[{"card_id":"83a014c3-c0a4-3242-b5a8-79d011b677d6","rendering_engine":"custom","type":"WEATHER","type_display_name":"Weather","ttl":1518881309,"layout":{"template":"weather"},"data":{},"modules":{},"reason":"","notify":false,"ranking_arguments":{"STREAM_TYPE:MAIN":1.0,"TIME_OF_DAY_RANGE:AFTERNOON":1.0,"rule_score":0.0,"TIER":0.0,"score":0.25},"instrumentation":{"rid":"cjo8c3hd8b9ot","bucket":"ga"}},{"card_id":"c81eac4b-4553-3d60-85a6-178968bd5065","rendering_engine":"custom","type":"NEWS_DIGEST","type_display_name":"News Digest","ttl":1518881309,"layout":{"template":"news_digest"},"data":{},"modules":{},"reason":"","notify":false,"ranking_arguments":{"STREAM_TYPE:MAIN":1.0,"TIME_OF_DAY_RANGE:AFTERNOON":1.0,"rule_score":0.0,"TIER":0.0,"score":0.25},"instrumentation":{"rid":"cjo8c3hd8b9ot","bucket":"ga"}},{"card_id":"bcacee7a-d79a-3e4e-a5b8-77c5b6480a8c","rendering_engine":"custom","type":"CALENDAR","type_display_name":"Calendar","ttl":1518881309,"layout":{"template":"calendar"},"data":{},"modules":{},"reason":"","notify":false,"ranking_arguments":{"USER_LOCATION:OTHER":1.0,"STREAM_TYPE:MAIN":1.0,"TIME_OF_DAY_RANGE:AFTERNOON":1.0,"rule_score":2.0,"TIER":2.0,"score":0.25},"instrumentation":{"rid":"cjo8c3hd8b9ot","bucket":"ga"}},{"card_id":"eea4f59a-e8a2-3e12-a917-96e254c416d5","rendering_engine":"custom","type":"VENUE_CHOOSER","type_display_name":"Around Me","ttl":1518712109,"layout":{"template":"venue_chooser"},"data":{"venues":[{"name":"Meadow Centre","category":"Gym Pool","iconUrl":"https://ss3.4sqi.net/img/categories_v2/parks_outdoors/pool_64.png","id":"4bd49bb9cfa7b713237424da","provider":"foursquare","eid":"{\"card\":\"venue\",\"id\":\"4bd49bb9cfa7b713237424da\"}"},{"name":"Dumbarton","category":"Town","iconUrl":"https://ss3.4sqi.net/img/categories_v2/parks_outdoors/neighborhood_64.png","id":"4b519b3ef964a5209e5027e3","provider":"foursquare","eid":"{\"card\":\"venue\",\"id\":\"4b519b3ef964a5209e5027e3\"}"},{"name":"St James' Retail Park","category":"Shopping Plaza","iconUrl":"https://ss3.4sqi.net/img/categories_v2/shops/mall_64.png","id":"4b86d734f964a520e2a031e3","provider":"foursquare","eid":"{\"card\":\"venue\",\"id\":\"4b86d734f964a520e2a031e3\"}"}]},"modules":{},"reason":"","notify":false,"ranking_arguments":{"USER_LOCATION:OTHER":1.0,"req_longitude":-4.5666,"USER_DIST_FROM_REQ_LOC:WITHIN_800M":1.0,"req_latitude":55.95,"STREAM_TYPE:MAIN":1.0,"USER_LOCATION_POI_CONFIDENCE:HIGH":1.0,"rule_score":2.0,"TIER":2.0,"score":0.25},"instrumentation":{"rid":"cjo8c3hd8b9ot","bucket":"ga"}},{"card_id":"f7b4def4-2367-3de4-9d11-ac8ddc9ebd10","rendering_engine":"custom","type":"POWER_SAVE","type_display_name":"Battery Saver","ttl":1518881310,"layout":{"template":"power_save"},"data":{},"modules":{},"reason":"","notify":false,"ranking_arguments":{"STREAM_TYPE:MAIN":1.0,"rule_score":0.0,"TIER":0.0,"score":0.0},"instrumentation":{"rid":"cjo8c3hd8b9ot","bucket":"ga"}},{"card_id":"4b5b8c71-58d2-3f26-abce-318e3d3a01d6","rendering_engine":"custom","type":"MORNING_NIGHT","type_display_name":"Set Alarm","ttl":1518881309,"layout":{"template":"morning_night"},"data":{},"modules":{},"reason":"","notify":false,"ranking_arguments":{"USER_LOCATION:OTHER":1.0,"USER_SPEED:STILL":1.0,"STREAM_TYPE:MAIN":1.0,"TIME_OF_DAY_RANGE:AFTERNOON":1.0,"rule_score":0.0,"TIER":0.0,"score":0.0},"instrumentation":{"rid":"cjo8c3hd8b9ot","bucket":"ga"}},{"card_id":"858aae29-ddf0-3754-b02a-39d4bfbdbeaf","rendering_engine":"custom","type":"DIRECTIONS","type_display_name":"Directions","ttl":1518881309,"layout":{"template":"directions"},"data":{},"modules":{},"reason":"","notify":false,"ranking_arguments":{"DAY_OF_WEEK_RANGE:WEEKDAY":1.0,"DAY_OF_WEEK_RANGE:THU_TO_SAT":1.0,"USER_LOCATION:OTHER":1.0,"USER_SPEED:STILL":1.0,"STREAM_TYPE:MAIN":1.0,"TIME_OF_DAY_RANGE:AFTERNOON":1.0,"rule_score":1.0,"TIER":1.0,"score":0.0},"instrumentation":{"rid":"cjo8c3hd8b9ot","bucket":"ga"}},{"card_id":"730f79c6-148d-39fd-bba1-1b3eafb8b6dc","rendering_engine":"custom","type"

View File

@ -1,221 +0,0 @@
{
"response": {
"result": [
{
"cards": [
{
"card_id": "83a014c3-c0a4-3242-b5a8-79d011b677d6",
"rendering_engine": "custom",
"type": "WEATHER",
"type_display_name": "Weather",
"ttl": 1518881309,
"layout": {
"template": "weather"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"STREAM_TYPE:MAIN": 1.0,
"TIME_OF_DAY_RANGE:AFTERNOON": 1.0,
"rule_score": 0.0,
"TIER": 0.0,
"score": 0.25
},
"instrumentation": {
"rid": "cjo8c3hd8b9ot",
"bucket": "ga"
}
},
{
"card_id": "c81eac4b-4553-3d60-85a6-178968bd5065",
"rendering_engine": "custom",
"type": "NEWS_DIGEST",
"type_display_name": "News Digest",
"ttl": 1518881309,
"layout": {
"template": "news_digest"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"STREAM_TYPE:MAIN": 1.0,
"TIME_OF_DAY_RANGE:AFTERNOON": 1.0,
"rule_score": 0.0,
"TIER": 0.0,
"score": 0.25
},
"instrumentation": {
"rid": "cjo8c3hd8b9ot",
"bucket": "ga"
}
},
{
"card_id": "bcacee7a-d79a-3e4e-a5b8-77c5b6480a8c",
"rendering_engine": "custom",
"type": "CALENDAR",
"type_display_name": "Calendar",
"ttl": 1518881309,
"layout": {
"template": "calendar"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"USER_LOCATION:OTHER": 1.0,
"STREAM_TYPE:MAIN": 1.0,
"TIME_OF_DAY_RANGE:AFTERNOON": 1.0,
"rule_score": 2.0,
"TIER": 2.0,
"score": 0.25
},
"instrumentation": {
"rid": "cjo8c3hd8b9ot",
"bucket": "ga"
}
},
{
"card_id": "eea4f59a-e8a2-3e12-a917-96e254c416d5",
"rendering_engine": "custom",
"type": "VENUE_CHOOSER",
"type_display_name": "Around Me",
"ttl": 1518712109,
"layout": {
"template": "venue_chooser"
},
"data": {
"venues": [
{
"name": "Meadow Centre",
"category": "Gym Pool",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/parks_outdoors/pool_64.png",
"id": "4bd49bb9cfa7b713237424da",
"provider": "foursquare",
"eid": "{\"card\":\"venue\",\"id\":\"4bd49bb9cfa7b713237424da\"}"
},
{
"name": "Dumbarton",
"category": "Town",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/parks_outdoors/neighborhood_64.png",
"id": "4b519b3ef964a5209e5027e3",
"provider": "foursquare",
"eid": "{\"card\":\"venue\",\"id\":\"4b519b3ef964a5209e5027e3\"}"
},
{
"name": "St James' Retail Park",
"category": "Shopping Plaza",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/shops/mall_64.png",
"id": "4b86d734f964a520e2a031e3",
"provider": "foursquare",
"eid": "{\"card\":\"venue\",\"id\":\"4b86d734f964a520e2a031e3\"}"
}
]
},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"USER_LOCATION:OTHER": 1.0,
"req_longitude": -4.5666,
"USER_DIST_FROM_REQ_LOC:WITHIN_800M": 1.0,
"req_latitude": 55.95,
"STREAM_TYPE:MAIN": 1.0,
"USER_LOCATION_POI_CONFIDENCE:HIGH": 1.0,
"rule_score": 2.0,
"TIER": 2.0,
"score": 0.25
},
"instrumentation": {
"rid": "cjo8c3hd8b9ot",
"bucket": "ga"
}
},
{
"card_id": "f7b4def4-2367-3de4-9d11-ac8ddc9ebd10",
"rendering_engine": "custom",
"type": "POWER_SAVE",
"type_display_name": "Battery Saver",
"ttl": 1518881310,
"layout": {
"template": "power_save"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"STREAM_TYPE:MAIN": 1.0,
"rule_score": 0.0,
"TIER": 0.0,
"score": 0.0
},
"instrumentation": {
"rid": "cjo8c3hd8b9ot",
"bucket": "ga"
}
},
{
"card_id": "4b5b8c71-58d2-3f26-abce-318e3d3a01d6",
"rendering_engine": "custom",
"type": "MORNING_NIGHT",
"type_display_name": "Set Alarm",
"ttl": 1518881309,
"layout": {
"template": "morning_night"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"USER_LOCATION:OTHER": 1.0,
"USER_SPEED:STILL": 1.0,
"STREAM_TYPE:MAIN": 1.0,
"TIME_OF_DAY_RANGE:AFTERNOON": 1.0,
"rule_score": 0.0,
"TIER": 0.0,
"score": 0.0
},
"instrumentation": {
"rid": "cjo8c3hd8b9ot",
"bucket": "ga"
}
},
{
"card_id": "858aae29-ddf0-3754-b02a-39d4bfbdbeaf",
"rendering_engine": "custom",
"type": "DIRECTIONS",
"type_display_name": "Directions",
"ttl": 1518881309,
"layout": {
"template": "directions"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"DAY_OF_WEEK_RANGE:WEEKDAY": 1.0,
"DAY_OF_WEEK_RANGE:THU_TO_SAT": 1.0,
"USER_LOCATION:OTHER": 1.0,
"USER_SPEED:STILL": 1.0,
"STREAM_TYPE:MAIN": 1.0,
"TIME_OF_DAY_RANGE:AFTERNOON": 1.0,
"rule_score": 1.0,
"TIER": 1.0,
"score": 0.0
},
"instrumentation": {
"rid": "cjo8c3hd8b9ot",
"bucket": "ga"
}
},
{
"card_id": "730f79c6-148d-39fd-bba1-1b3eafb8b6dc",
"rendering_engine": "custom",
"type"

View File

@ -1 +0,0 @@
{"response":{"result":[{"cards":[{"card_id":"83a014c3-c0a4-3242-b5a8-79d011b677d6","rendering_engine":"custom","type":"WEATHER","type_display_name":"Weather","ttl":1518881309,"layout":{"template":"weather"},"data":{},"modules":{},"reason":"","notify":false,"ranking_arguments":{"STREAM_TYPE:MAIN":1.0,"TIME_OF_DAY_RANGE:AFTERNOON":1.0,"rule_score":0.0,"TIER":0.0,"score":0.25},"instrumentation":{"rid":"cjo8c3hd8b9ot","bucket":"ga"}},{"card_id":"c81eac4b-4553-3d60-85a6-178968bd5065","rendering_engine":"custom","type":"NEWS_DIGEST","type_display_name":"News Digest","ttl":1518881309,"layout":{"template":"news_digest"},"data":{},"modules":{},"reason":"","notify":false,"ranking_arguments":{"STREAM_TYPE:MAIN":1.0,"TIME_OF_DAY_RANGE:AFTERNOON":1.0,"rule_score":0.0,"TIER":0.0,"score":0.25},"instrumentation":{"rid":"cjo8c3hd8b9ot","bucket":"ga"}},{"card_id":"bcacee7a-d79a-3e4e-a5b8-77c5b6480a8c","rendering_engine":"custom","type":"CALENDAR","type_display_name":"Calendar","ttl":1518881309,"layout":{"template":"calendar"},"data":{},"modules":{},"reason":"","notify":false,"ranking_arguments":{"USER_LOCATION:OTHER":1.0,"STREAM_TYPE:MAIN":1.0,"TIME_OF_DAY_RANGE:AFTERNOON":1.0,"rule_score":2.0,"TIER":2.0,"score":0.25},"instrumentation":{"rid":"cjo8c3hd8b9ot","bucket":"ga"}},{"card_id":"eea4f59a-e8a2-3e12-a917-96e254c416d5","rendering_engine":"custom","type":"VENUE_CHOOSER","type_display_name":"Around Me","ttl":1518712109,"layout":{"template":"venue_chooser"},"data":{"venues":[{"name":"Meadow Centre","category":"Gym Pool","iconUrl":"https://ss3.4sqi.net/img/categories_v2/parks_outdoors/pool_64.png","id":"4bd49bb9cfa7b713237424da","provider":"foursquare","eid":"{\"card\":\"venue\",\"id\":\"4bd49bb9cfa7b713237424da\"}"},{"name":"Dumbarton","category":"Town","iconUrl":"https://ss3.4sqi.net/img/categories_v2/parks_outdoors/neighborhood_64.png","id":"4b519b3ef964a5209e5027e3","provider":"foursquare","eid":"{\"card\":\"venue\",\"id\":\"4b519b3ef964a5209e5027e3\"}"},{"name":"St James' Retail Park","category":"Shopping Plaza","iconUrl":"https://ss3.4sqi.net/img/categories_v2/shops/mall_64.png","id":"4b86d734f964a520e2a031e3","provider":"foursquare","eid":"{\"card\":\"venue\",\"id\":\"4b86d734f964a520e2a031e3\"}"}]},"modules":{},"reason":"","notify":false,"ranking_arguments":{"USER_LOCATION:OTHER":1.0,"req_longitude":-4.5666,"USER_DIST_FROM_REQ_LOC:WITHIN_800M":1.0,"req_latitude":55.95,"STREAM_TYPE:MAIN":1.0,"USER_LOCATION_POI_CONFIDENCE:HIGH":1.0,"rule_score":2.0,"TIER":2.0,"score":0.25},"instrumentation":{"rid":"cjo8c3hd8b9ot","bucket":"ga"}},{"card_id":"f7b4def4-2367-3de4-9d11-ac8ddc9ebd10","rendering_engine":"custom","type":"POWER_SAVE","type_display_name":"Battery Saver","ttl":1518881310,"layout":{"template":"power_save"},"data":{},"modules":{},"reason":"","notify":false,"ranking_arguments":{"STREAM_TYPE:MAIN":1.0,"rule_score":0.0,"TIER":0.0,"score":0.0},"instrumentation":{"rid":"cjo8c3hd8b9ot","bucket":"ga"}},{"card_id":"4b5b8c71-58d2-3f26-abce-318e3d3a01d6","rendering_engine":"custom","type":"MORNING_NIGHT","type_display_name":"Set Alarm","ttl":1518881309,"layout":{"template":"morning_night"},"data":{},"modules":{},"reason":"","notify":false,"ranking_arguments":{"USER_LOCATION:OTHER":1.0,"USER_SPEED:STILL":1.0,"STREAM_TYPE:MAIN":1.0,"TIME_OF_DAY_RANGE:AFTERNOON":1.0,"rule_score":0.0,"TIER":0.0,"score":0.0},"instrumentation":{"rid":"cjo8c3hd8b9ot","bucket":"ga"}},{"card_id":"858aae29-ddf0-3754-b02a-39d4bfbdbeaf","rendering_engine":"custom","type":"DIRECTIONS","type_display_name":"Directions","ttl":1518881309,"layout":{"template":"directions"},"data":{},"modules":{},"reason":"","notify":false,"ranking_arguments":{"DAY_OF_WEEK_RANGE:WEEKDAY":1.0,"DAY_OF_WEEK_RANGE:THU_TO_SAT":1.0,"USER_LOCATION:OTHER":1.0,"USER_SPEED:STILL":1.0,"STREAM_TYPE:MAIN":1.0,"TIME_OF_DAY_RANGE:AFTERNOON":1.0,"rule_score":1.0,"TIER":1.0,"score":0.0},"instrumentation":{"rid":"cjo8c3hd8b9ot","bucket":"ga"}},{"card_id":"730f79c6-148d-39fd-bba1-1b3eafb8b6dc","rendering_engine":"custom","type"

View File

@ -1,218 +0,0 @@
{
"response": {
"result": [
{
"cards": [
{
"card_id": "83a014c3-c0a4-3242-b5a8-79d011b677d6",
"rendering_engine": "custom",
"type": "WEATHER",
"type_display_name": "Weather",
"ttl": 1518885169,
"layout": {
"template": "weather"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"STREAM_TYPE:MAIN": 1.0,
"TIME_OF_DAY_RANGE:AFTERNOON": 1.0,
"rule_score": 0.0,
"TIER": 0.0,
"score": 0.25
},
"instrumentation": {
"rid": "dj9n835d8bdhh",
"bucket": "ga"
}
},
{
"card_id": "c81eac4b-4553-3d60-85a6-178968bd5065",
"rendering_engine": "custom",
"type": "NEWS_DIGEST",
"type_display_name": "News Digest",
"ttl": 1518885169,
"layout": {
"template": "news_digest"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"STREAM_TYPE:MAIN": 1.0,
"TIME_OF_DAY_RANGE:AFTERNOON": 1.0,
"rule_score": 0.0,
"TIER": 0.0,
"score": 0.25
},
"instrumentation": {
"rid": "dj9n835d8bdhh",
"bucket": "ga"
}
},
{
"card_id": "bcacee7a-d79a-3e4e-a5b8-77c5b6480a8c",
"rendering_engine": "custom",
"type": "CALENDAR",
"type_display_name": "Calendar",
"ttl": 1518885169,
"layout": {
"template": "calendar"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"USER_LOCATION:OTHER": 1.0,
"STREAM_TYPE:MAIN": 1.0,
"TIME_OF_DAY_RANGE:AFTERNOON": 1.0,
"rule_score": 2.0,
"TIER": 2.0,
"score": 0.25
},
"instrumentation": {
"rid": "dj9n835d8bdhh",
"bucket": "ga"
}
},
{
"card_id": "eea4f59a-e8a2-3e12-a917-96e254c416d5",
"rendering_engine": "custom",
"type": "VENUE_CHOOSER",
"type_display_name": "Around Me",
"ttl": 1518715969,
"layout": {
"template": "venue_chooser"
},
"data": {
"venues": [
{
"name": "Meadow Centre",
"category": "Gym Pool",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/parks_outdoors/pool_64.png",
"id": "4bd49bb9cfa7b713237424da",
"provider": "foursquare",
"eid": "{\"card\":\"venue\",\"id\":\"4bd49bb9cfa7b713237424da\"}"
},
{
"name": "Dumbarton",
"category": "Town",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/parks_outdoors/neighborhood_64.png",
"id": "4b519b3ef964a5209e5027e3",
"provider": "foursquare",
"eid": "{\"card\":\"venue\",\"id\":\"4b519b3ef964a5209e5027e3\"}"
},
{
"name": "St James' Retail Park",
"category": "Shopping Plaza",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/shops/mall_64.png",
"id": "4b86d734f964a520e2a031e3",
"provider": "foursquare",
"eid": "{\"card\":\"venue\",\"id\":\"4b86d734f964a520e2a031e3\"}"
}
]
},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"USER_LOCATION:OTHER": 1.0,
"req_longitude": -4.5666,
"USER_DIST_FROM_REQ_LOC:WITHIN_800M": 1.0,
"req_latitude": 55.95,
"STREAM_TYPE:MAIN": 1.0,
"USER_LOCATION_POI_CONFIDENCE:HIGH": 1.0,
"rule_score": 2.0,
"TIER": 2.0,
"score": 0.25
},
"instrumentation": {
"rid": "dj9n835d8bdhh",
"bucket": "ga"
}
},
{
"card_id": "4b5b8c71-58d2-3f26-abce-318e3d3a01d6",
"rendering_engine": "custom",
"type": "MORNING_NIGHT",
"type_display_name": "Set Alarm",
"ttl": 1518885169,
"layout": {
"template": "morning_night"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"USER_LOCATION:OTHER": 1.0,
"USER_SPEED:STILL": 1.0,
"STREAM_TYPE:MAIN": 1.0,
"TIME_OF_DAY_RANGE:AFTERNOON": 1.0,
"rule_score": 0.0,
"TIER": 0.0,
"score": 0.0
},
"instrumentation": {
"rid": "dj9n835d8bdhh",
"bucket": "ga"
}
},
{
"card_id": "730f79c6-148d-39fd-bba1-1b3eafb8b6dc",
"rendering_engine": "custom",
"type": "MUSIC_PLAYING",
"type_display_name": "Music Player",
"ttl": 1518885169,
"layout": {
"template": "music_playing"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"STREAM_TYPE:MAIN": 1.0,
"rule_score": 0.0,
"TIER": 0.0,
"score": 0.0
},
"instrumentation": {
"rid": "dj9n835d8bdhh",
"bucket": "ga"
}
},
{
"card_id": "ee966fd9-7ca1-368c-b56c-427013d5b9e9",
"rendering_engine": "custom",
"type": "ARTIST_INFO",
"type_display_name": "Artist Info",
"ttl": 1518885169,
"layout": {
"template": "artist_info"
},
"data": {},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"STREAM_TYPE:MAIN": 1.0,
"rule_score": 0.0,
"TIER": 0.0,
"score": 0.0
},
"instrumentation": {
"rid": "dj9n835d8bdhh",
"bucket": "ga"
}
}
]
}
],
"error": null
}
}

View File

@ -1 +0,0 @@
{"response":{"result":[{"cards":[{"

View File

@ -1,197 +0,0 @@
{
"venues": {
"result": [
{
"id": "502f600fe4b0d68f37a8a954",
"name": "Dumbarton Library",
"primary_category": {
"id": "",
"name": "Library",
"icon_url": "https://ss3.4sqi.net/img/categories_v2/building/library_64.png",
"primary": true
},
"provider": "foursquare"
},
{
"id": "4da1ee597aee5481d57ccbfe",
"name": "Dumbarton Indoor Bowling Club",
"primary_category": {
"id": "",
"name": "Bowling Alley",
"icon_url": "https://ss3.4sqi.net/img/categories_v2/arts_entertainment/bowling_64.png",
"primary": true
},
"provider": "foursquare"
},
{
"id": "4bd49bb9cfa7b713237424da",
"name": "Meadow Centre",
"primary_category": {
"id": "",
"name": "Gym Pool",
"icon_url": "https://ss3.4sqi.net/img/categories_v2/parks_outdoors/pool_64.png",
"primary": true
},
"provider": "foursquare"
},
{
"id": "4b519b3ef964a5209e5027e3",
"name": "Dumbarton",
"primary_category": {
"id": "",
"name": "Town",
"icon_url": "https://ss3.4sqi.net/img/categories_v2/parks_outdoors/neighborhood_64.png",
"primary": true
},
"provider": "foursquare"
},
{
"id": "51794b55e4b0dcb307a7f456",
"name": "Dumbarton Golf Club",
"primary_category": {
"id": "",
"name": "Golf Course",
"icon_url": "https://ss3.4sqi.net/img/categories_v2/parks_outdoors/golfcourse_64.png",
"primary": true
},
"provider": "foursquare"
},
{
"id": "4b86d734f964a520e2a031e3",
"name": "St James' Retail Park",
"primary_category": {
"id": "",
"name": "Shopping Plaza",
"icon_url": "https://ss3.4sqi.net/img/categories_v2/shops/mall_64.png",
"primary": true
},
"provider": "foursquare"
},
{
"id": "534552a3498e2ea01380de54",
"name": "BT Exchange, Dumbarton",
"primary_category": {
"id": "",
"name": "Building",
"icon_url": "https://ss3.4sqi.net/img/categories_v2/building/default_64.png",
"primary": true
},
"provider": "foursquare"
},
{
"id": "507a8fb1e4b0112fc410d415",
"name": "knoxland astroturf",
"primary_category": {
"id": "",
"name": "Soccer Field",
"icon_url": "https://ss3.4sqi.net/img/categories_v2/arts_entertainment/stadium_soccer_64.png",
"primary": true
},
"provider": "foursquare"
},
{
"id": "4f9e8385e4b030992bbe03fb",
"name": "River City",
"primary_category": {
"id": "",
"name": "General Entertainment",
"icon_url": "https://ss3.4sqi.net/img/categories_v2/arts_entertainment/default_64.png",
"primary": true
},
"provider": "foursquare"
},
{
"id": "4fcdd2a8e4b0844bff5bb5a9",
"name": "dumbriton housing offices",
"primary_category": {
"id": "",
"name": "Building",
"icon_url": "https://ss3.4sqi.net/img/categories_v2/building/default_64.png",
"primary": true
},
"provider": "foursquare"
},
{
"id": "4e9d7dc12c5b8638e56fb11d",
"name": "Elm Road Depot",
"primary_category": {
"id": "",
"name": "Government Building",
"icon_url": "https://ss3.4sqi.net/img/categories_v2/building/government_64.png",
"primary": true
},
"provider": "foursquare"
},
{
"id": "566326c9498e32e22b667471",
"name": "Screwfix",
"primary_category": {
"id": "",
"name": "Hardware Store",
"icon_url": "https://ss3.4sqi.net/img/categories_v2/shops/hardware_64.png",
"primary": true
},
"provider": "foursquare"
},
{
"id": "53eb211f498eb4d043818684",
"name": "Ben View",
"primary_category": {
"id": "",
"name": "Community Center",
"icon_url": "https://ss3.4sqi.net/img/categories_v2/building/default_64.png",
"primary": true
},
"provider": "foursquare"
},
{
"id": "4d83aeca02eb54818e011ff5",
"name": "Waverley Bar",
"primary_category": {
"id": "",
"name": "Beer Garden",
"icon_url": "https://ss3.4sqi.net/img/categories_v2/nightlife/beergarden_64.png",
"primary": true
},
"provider": "foursquare"
},
{
"id": "4da2f63f9935a093c2cdbe6f",
"name": "Homebase",
"primary_category": {
"id": "",
"name": "Hardware Store",
"icon_url": "https://ss3.4sqi.net/img/categories_v2/shops/hardware_64.png",
"primary": true
},
"provider": "foursquare"
},
{
"id": "4de6668d2271f377c2a964c7",
"name": "Halfords",
"primary_category": {
"id": "",
"name": "Automotive Shop",
"icon_url": "https://ss3.4sqi.net/img/categories_v2/shops/automotive_64.png",
"primary": true
},
"provider": "foursquare"
},
{
"id": "4e03bc3bc65b59b611d879f2",
"name": "Lennox Bar",
"primary_category": {
"id": "",
"name": "Bar",
"icon_url": "https://ss3.4sqi.net/img/categories_v2/nightlife/pub_64.png",
"primary": true
},
"provider": "foursquare"
},
{
"id": "55f2bcf4498e8e1293c25d5c",
"name": "Pets at Home",
"primary_category": {
"id": "",
"name": "Pet Store",
"icon_url": "https://s

View File

@ -1 +0,0 @@
{"response":{"result":[{"cards":[{"card_id":"326b2e00-b861-3a3f-963c-9df9e8be0a5b","rendering_engine":"dunkv2","type":"MOVIES","type_display_name":"Recommended Movies","ttl":1518892410,"layout":{"template":"movies"},"data":{"bef7f3d4-4b02-3442-8a1e-6a67ee127a58-ACEMultiMovieHeader-a14a36a5241607e6abdec363f6503f3d":{"title":"In Theaters Near You"},"bef7f3d4-4b02-3442-8a1e-6a67ee127a58-AviateMultiMovieCarousel-8668c11c465a5be5340ba9f198434887":{"title":"Recommended Movies","movieList":"movies","movies":[{"title":"Black Panther","image":"http://d.yimg.com/sr/imgv1/1/858174ff-550c-38df-8777-f5d688dfb773","rating":"97%","freshness":"fresh","meta":[{"text":"Action"}],"movieUrl":"action://app/requery?q=Black%20Panther&eid={\"card\":\"movie\",\"id\":\"b2561e1d-580f-42cd-828c-6adc4cc7231f\"}"},{"title":"The Greatest Showman","image":"http://d.yimg.com/sr/imgv1/1/f4cd972a-941d-38c9-8b5b-2cb48e6771b3","rating":"55%","freshness":"rotten","meta":[{"text":"Biography"}],"movieUrl":"action://app/requery?q=The%20Greatest%20Showman&eid={\"card\":\"movie\",\"id\":\"79fd73fa-5bbe-39ab-85da-e95bd4e20059\"}"},{"title":"Jumanji: Welcome to the Jungle","image":"http://d.yimg.com/sr/imgv1/1/3e2d9fef-f4f1-33fd-9d94-289e8b4c221d","rating":"76%","freshness":"fresh","meta":[{"text":"Action"}],"movieUrl":"action://app/requery?q=Jumanji%3A%20Welcome%20to%20the%20Jungle&eid={\"card\":\"movie\",\"id\":\"dca60337-76f1-4bc3-a91b-d23820f19873\"}"}]}},"modules":[{"type":"header","id":"a14a36a5241607e6abdec363f6503f3d","ref":["bef7f3d4-4b02-3442-8a1e-6a67ee127a58-ACEMultiMovieHeader-a14a36a5241607e6abdec363f6503f3d"],"instrumentation":{"name":"ACEMultiMovieHeader","keys":{"template":"header"}}},{"type":"moviesCarousel","id":"8668c11c465a5be5340ba9f198434887","ref":["bef7f3d4-4b02-3442-8a1e-6a67ee127a58-AviateMultiMovieCarousel-8668c11c465a5be5340ba9f198434887"],"instrumentation":{"name":"AviateMultiMovieCarousel","keys":{"template":"moviesCarousel"}}}],"reason":"","notify":false,"ranking_arguments":{"STREAM_TYPE:MAIN":1.0,"TIME_OF_DAY_RANGE:AFTERNOON":1.0,"rule_score":0.0,"TIER":0.0,"DAY_OF_WEEK:SAT":1.0,"score":0.5},"instrumentation":{"rid":"19661d9d8gmaq","bucket":"ga"}},{"card_id":"83a014c3-c0a4-3242-b5a8-79d011b677d6","rendering_engine":"custom","type":"WEATHER","type_display_name":"Weather","ttl":1519058010,"layout":{"template":"weather"},"data":{},"modules":{},"reason":"","notify":false,"ranking_arguments":{"STREAM_TYPE:MAIN":1.0,"TIME_OF_DAY_RANGE:AFTERNOON":1.0,"rule_score":0.0,"TIER":0.0,"score":0.25},"instrumentation":{"rid":"19661d9d8gmaq","bucket":"ga"}},{"card_id":"c81eac4b-4553-3d60-85a6-178968bd5065","rendering_engine":"custom","type":"NEWS_DIGEST","type_display_name":"News Digest","ttl":1519058010,"layout":{"template":"news_digest"},"data":{},"modules":{},"reason":"","notify":false,"ranking_arguments":{"STREAM_TYPE:MAIN":1.0,"TIME_OF_DAY_RANGE:AFTERNOON":1.0,"rule_score":0.0,"TIER":0.0,"score":0.25},"instrumentation":{"rid":"19661d9d8gmaq","bucket":"ga"}},{"card_id":"bcacee7a-d79a-3e4e-a5b8-77c5b6480a8c","rendering_engine":"custom","type":"CALENDAR","type_display_name":"Calendar","ttl":1519058010,"layout":{"template":"calendar"},"data":{},"modules":{},"reason":"","notify":false,"ranking_arguments":{"USER_LOCATION:OTHER":1.0,"STREAM_TYPE:MAIN":1.0,"TIME_OF_DAY_RANGE:AFTERNOON":1.0,"rule_score":2.0,"TIER":2.0,"score":0.25},"instrumentation":{"rid":"19661d9d8gmaq","bucket":"ga"}},{"card_id":"4b5b8c71-58d2-3f26-abce-318e3d3a01d6","rendering_engine":"custom","type":"MORNING_NIGHT","type_display_name":"Set Alarm","ttl":1519058010,"layout":{"template":"morning_night"},"data":{},"modules":{},"reason":"","notify":false,"ranking_arguments":{"USER_LOCATION:OTHER":1.0,"USER_SPEED:STILL":1.0,"STREAM_TYPE:MAIN":1.0,"TIME_OF_DAY_RANGE:AFTERNOON":1.0,"rule_score":0.0,"TIER":0.0,"score":0.0},"instrumentation":{"rid":"19661d9d8gmaq","bucket":"ga"}},{"card_id":"730f79c6-148d-39fd-bba1-1b3eafb8b6dc","rendering_engine":"custom","type":"MUSIC_PLAYING","type_display_name":"Music Play

View File

@ -1,72 +0,0 @@
{
"response": {
"result": [
{
"cards": [
{
"card_id": "9953c0e9-5b77-3162-bcf4-e19fcd1f541f",
"rendering_engine": "custom",
"type": "VENUE_INFO",
"type_display_name": "Venues",
"ttl": 1518712127,
"layout": {
"template": "venue_info"
},
"data": {
"name": "Meadow Centre",
"category": "Gym Pool",
"iconUrl": "https://ss3.4sqi.net/img/categories_v2/parks_outdoors/pool_64.png",
"id": "4bd49bb9cfa7b713237424da",
"provider": "foursquare",
"tips": [
"Great swimming pool with a wave machine every 30 minutes - but could be warmer"
],
"images": [
"https://igx.4sqi.net/img/general/6016x4016/212169387_Sk6ObrC2WhtKFKZgTQG5UDeFJr9BH1WmjhUI_qkRqlw.jpg"
],
"telephone": "",
"address": "",
"city": "",
"state": "",
"zip": "",
"latitude": 55.947152440274564,
"longitude": -4.564007641621031,
"twitter": {
"handle": null,
"viewIntent": null,
"tweetIntent": null
},
"yelp": {
"url": "https://m.yelp.com/biz/meadow-leisure-centre-dumbarton?adjust_creative=ogmBMO91tbdmscbTIaQEdA&utm_campaign=yelp_api&utm_medium=api_v2_search&utm_source=ogmBMO91tbdmscbTIaQEdA",
"rating": 3.5,
"reviewCount": 2,
"viewIntent": "https://m.yelp.com/biz/meadow-leisure-centre-dumbarton?adjust_creative=ogmBMO91tbdmscbTIaQEdA&utm_campaign=yelp_api&utm_medium=api_v2_search&utm_source=ogmBMO91tbdmscbTIaQEdA#Intent;action=android.intent.action.VIEW;end"
}
},
"modules": {},
"reason": "",
"notify": false,
"ranking_arguments": {
"poi_latitude": 55.947152440274564,
"poi_longitude": -4.564007641621031,
"USER_LOCATION:OTHER": 1.0,
"req_longitude": -4.5666,
"req_latitude": 55.95,
"USER_LOCATION_POI_CONFIDENCE:HIGH": 1.0,
"STREAM_TYPE": 1.0,
"rule_score": 0.0,
"TIER": 0.0,
"USER_DIST_FROM_REQ_LOC:WITHIN_100M": 1.0,
"score": 0.0
},
"instrumentation": {
"rid": "3un9llld8b9pf",
"bucket": "ga"
}
}
]
}
],
"error": null
}
}

8247
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -6,85 +6,74 @@
"scripts": {
"test": "mocha"
},
"engines": {
"node": "=8.17.0"
},
"author": "",
"license": "ISC",
"dependencies": {
"apicache": "^1.2.3",
"apicache": "^1.2.1",
"backbone": "^1.3.3",
"browserify": "^16.2.3",
"browserify": "^16.1.0",
"cheerio": "^1.0.0-rc.2",
"cors": "^2.8.5",
"dark-sky-api": "^0.6.32",
"dateformat": "^3.0.3",
"dark-sky-api": "^0.6.3",
"debug-logger": "^0.4.1",
"del": "^3.0.0",
"elapsed": "0.0.7",
"eslint": "^4.19.1",
"express": "^4.16.4",
"eslint": "^4.19.0",
"express": "^4.16.3",
"fecha": "^2.3.3",
"feedme": "^1.2.0",
"geolocation": "^0.2.0",
"gulp-autoprefixer": "^4.1.0",
"gulp-bump": "^3.1.3",
"gulp-cache": "^1.1.1",
"gulp-autoprefixer": "^5.0.0",
"gulp-bump": "^3.1.0",
"gulp-cache": "^1.0.2",
"gulp-concat": "^2.6.1",
"gulp-cssnano": "^2.1.3",
"gulp-cssnano": "^2.1.2",
"gulp-html-replace": "^1.6.2",
"gulp-htmlmin": "^4.0.0",
"gulp-inject": "^4.3.2",
"gulp-uglify": "^3.0.1",
"gulp-inject": "^4.3.1",
"gulp-uglify": "^3.0.0",
"hh-mm-ss": "^1.2.0",
"humanize-duration": "^3.17.0",
"humanize-duration": "^3.13.0",
"jquery": "^3.3.1",
"jsonfile": "^5.0.0",
"leaflet": "^1.4.0",
"lodash": "^4.17.11",
"log4js": "^2.11.0",
"leaflet": "^1.3.1",
"lodash": "^4.17.5",
"log4js": "^2.5.3",
"log4js-node-mongodb": "^2.2.1",
"loggy": "^1.0.4",
"loggy": "^1.0.2",
"memory-cache": "^0.2.0",
"moment": "^2.24.0",
"muicss": "^0.9.41",
"moment": "^2.21.0",
"muicss": "^0.9.38",
"node-foursquare-venues": "^1.1.0",
"openweather-apis": "^3.3.5",
"redaxios": "^0.2.0",
"request-json": "^0.6.4",
"request-promise-native": "^1.0.5",
"request-json": "^0.6.3",
"strict-uri-encode": "^2.0.0",
"string": "^3.3.3",
"sugar": "^2.0.6",
"sugar": "^2.0.4",
"twitter": "^1.7.1",
"uglifyify": "^4.0.5",
"underscore": "^1.9.1",
"winston": "^2.4.4",
"winston-mongodb": "^4.0.3",
"yelp-fusion": "^2.2.1"
"underscore": "^1.8.3",
"winston": "^2.4.1",
"winston-mongodb": "^4.0.0-rc1",
"yelp-fusion": "^2.0.3"
},
"devDependencies": {
"expect.js": "^0.3.1",
"gulp": "3.9.1",
"gulp-google-webfonts": "0.0.14",
"gulp-rename": "^1.4.0",
"gulp-sass": "^3.2.1",
"gulp": "^3.9.1",
"gulp-google-webfonts": "^1.0.0",
"gulp-rename": "^1.2.2",
"gulp-sass": "^3.1.0",
"gulp-scss": "^1.4.0",
"gulp-sourcemaps": "^2.6.4",
"gulp-strip-debug": "^2.0.0",
"gulp-uglify-es": "^1.0.4",
"gulp-strip-debug": "^3.0.0",
"gulp-uglify-es": "^1.0.1",
"lodash.assign": "^4.2.0",
"mocha": "^5.2.0",
"node-fetch": "^2.3.0",
"mocha": "^5.0.4",
"node-fetch": "^2.1.1",
"node-geocoder": "^3.22.0",
"require-dir": "^1.2.0",
"requirejs": "^2.3.6",
"sinon": "^4.5.0",
"tape": "^4.9.2",
"tape-promise": "^4.0.0",
"require-dir": "^1.0.0",
"requirejs": "^2.3.5",
"sinon": "^4.4.6",
"vinyl-buffer": "^1.0.1",
"vinyl-source-stream": "^2.0.0",
"watchify": "^3.11.0",
"whatwg-fetch": "^2.0.4"
"whatwg-fetch": "^2.0.3"
}
}

110
server.js
View File

@ -8,46 +8,29 @@ const foursquare = require('./server/foursquare');
const rightbyme = require('./server/RightByMe');
const agenda = require('./server/agenda');
const directions = require('./server/directions');
const geocode = require('./server/geocode');
const cors = require('cors');
logger.level = 'debug';
const app = express();
app.use(cors());
const port = process.env.PORT || 8110;
const sitePath = 'live';
apicache.options({ 'debug': true });
const cache = apicache.middleware;
const standardError = {
'error':'There was an error'
};
app.use(express.static(path.join(__dirname, sitePath)));
// app.get('/weather', cache('15 minutes'), (req, res) => {
const asyncMiddleware = fn =>
(req, res, next) => {
Promise.resolve(fn(req, res, next))
.catch(next);
};
app.get('/weather', (req, res) => {
if (req.query.hasOwnProperty('ll'))
weather.doGetOpenWeather(req.query.ll)
.then((d) => {
res.set('Cache-Control', 'public, max-age=1800');
res.send(d);
}).catch((e) => {
logger.error(e);
res.status(500).send(Object.assign(standardError, { 'source':'weather', 'e':e }));
res.status(500).send('There was an error!');
});
else {
@ -64,11 +47,10 @@ app.get('/forecast', (req, res) => {
weather.doGetFullForcast(req.query.ll)
.then((d) => {
res.set('Cache-Control', 'public, max-age=1800');
res.send(d);
}).catch((e) => {
logger.error(e);
res.status(500).send(Object.assign(standardError, { 'source':'forecast', 'e':e }));
res.status(500).send('There was an error!');
});
else {
@ -84,11 +66,10 @@ app.get('/weatheralert', cache('15 minutes'), (req, res) => {
// doGetDarkSkyWeather
weather.doGetDarkSkyWeather(req.query.ll)
.then((d) => {
res.set('Cache-Control', 'public, max-age=1800');
res.send(d);
}).catch((e) => {
logger.error(e);
res.status(500).send(Object.assign(standardError, { 'source':'weatheralert', 'e':e }));
res.status(500).send('There was an error!');
});
else {
@ -103,15 +84,12 @@ app.get('/fsexplore', cache('15 minutes'), (req, res) => {
const ll = req.query.ll;
const limit = req.query.hasOwnProperty('ll') ? req.query.limit : 3;
const section = req.query.hasOwnProperty('section') ? req.query.section : 'topPicks';
const query = req.query.hasOwnProperty('query') ? req.query.query : '';
console.log('req.query', req.query);
foursquare.doGetFourSquareExplore(ll, limit, section, query)
foursquare.doGetFourSquareExplore(ll, limit, section)
.then((d) => {
res.set('Cache-Control', 'public, max-age=900');
res.send(d);
}).catch((e) => {
logger.error(e);
res.status(500).send(Object.assign(standardError, { 'source':'fsexplore', 'e':e }));
res.status(500).send('There was an error!');
});
}
@ -122,36 +100,14 @@ app.get('/fsexplore', cache('15 minutes'), (req, res) => {
}
});
app.get('/geocode', /* cache('15 minutes'),*/ (req, res) => {
if (req.query.hasOwnProperty('ll')) {
const ll = req.query.ll;
console.log('ll', ll);
geocode.doGetGeocode(ll)
.then((d) => {
res.set('Cache-Control', 'public, max-age=900');
res.send(d);
}).catch((e) => {
logger.error(e);
res.status(500).send(Object.assign(standardError, { 'source':'geocode', 'e':e }));
});
}
else {
// throw new Error('Weather: LL missing');
logger.warn('FS: LL missing');
res.status(500).send('LL Missing');
}
});
app.get('/rightbyme', cache('86400 seconds'), (req, res) => {
app.get('/rightbyme', cache('15 minutes'), (req, res) => {
if (req.query.hasOwnProperty('ll'))
rightbyme.doGetRightByMe(req.query.ll)
.then((d) => {
res.set('Cache-Control', 'public, max-age=86400');
res.send(d);
}).catch((e) => {
logger.error(e);
res.status(500).send(Object.assign(standardError, { 'source':'rightbyme', 'e':e }));
res.status(500).send('There was an error!');
});
else {
@ -165,11 +121,10 @@ app.get('/nearbydetail', cache('15 minutes'), (req, res) => {
if (req.query.hasOwnProperty('id'))
rightbyme.doGetMoreDetail(req.query.id)
.then((d) => {
res.set('Cache-Control', 'public, max-age=1800');
res.send(d);
}).catch((e) => {
logger.error(e);
res.status(500).send(Object.assign(standardError, { 'source':'nearbydetail', 'e':e }));
res.status(500).send('There was an error!');
});
else {
@ -181,7 +136,6 @@ app.get('/nearbydetail', cache('15 minutes'), (req, res) => {
app.get('/news', cache('15 minutes'), (req, res) => {
euronews.getEuroNews().then((d) => {
res.set('Cache-Control', 'public, max-age=1800');
res.send(d);
}).catch((e) => {
if (e.message === '304:Not changed') {
@ -190,7 +144,7 @@ app.get('/news', cache('15 minutes'), (req, res) => {
}
else {
logger.error(e);
res.status(500).send(Object.assign(standardError, { 'source':'news', 'e':e }));
res.status(500).send('There was an error!');
}
});
});
@ -201,11 +155,10 @@ app.get('/article', cache('1 hour'), (req, res) => {
euronews.getArticle(req.query.guid)
.then((d) => {
res.set('Cache-Control', 'public, max-age=3600');
res.send(d);
}).catch((e) => {
logger.error(e);
res.status(500).send(Object.assign(standardError, { 'source':'article', 'e':e }));
res.status(500).send('There was an error!');
});
}
else {
@ -218,25 +171,23 @@ app.get('/article', cache('1 hour'), (req, res) => {
app.get('/agenda', cache('15 minutes'), (req, res) => {
agenda.doTodaysAgenda()
.then((d) => {
res.set('Cache-Control', 'public, max-age=900');
res.send(d);
}).catch((e) => {
logger.error(e);
res.status(500).send(Object.assign(standardError, { 'source':'agenda', 'e':e }));
res.status(500).send('There was an error!');
});
});
app.get('/oldtraffic', cache('5 minutes'), (req, res) => {
app.get('/traffic', cache('5 minutes'), (req, res) => {
logger.debug(req.query);
if (req.query.hasOwnProperty('olat'))
directions.getTraffic(req.query.olat, req.query.olon, req.query.dlat, req.query.dlon)
.then((d) => {
res.set('Cache-Control', 'public, max-age=900');
res.send(d);
}).catch((e) => {
logger.error(e);
res.status(500).send(Object.assign(standardError, { 'source':'oldtraffic', 'e':e }));
res.status(500).send('There was an error!');
});
else {
@ -245,41 +196,6 @@ app.get('/oldtraffic', cache('5 minutes'), (req, res) => {
res.status(500).send('oLat Missing');
}
});
app.get('/incidents', cache('5 minutes'), (req, res) => {
logger.debug(req.query);
directions.getIncidents()
.then((d) => {
logger.debug(d);
res.set('Cache-Control', 'public, max-age=300');
res.send(d);
}).catch((e) => {
logger.error(e);
res.status(500).send(Object.assign(standardError, { 'source':'incidents', 'e':e }));
});
});
app.get('/traffic', cache('5 minutes'), asyncMiddleware(async (req, res, next) => {
logger.debug(req.query);
if (req.query.hasOwnProperty('olat'))
await directions.doGetEstDirectionsWithIncidents(req.query.olat, req.query.olon, req.query.dlat, req.query.dlon).then((b) => {
// logger.debug('b', b);
res.set('Cache-Control', 'public, max-age=300');
res.send(b);
}).catch((e) => {
logger.error(e);
res.status(500).send(Object.assign(standardError, { 'source':'traffic', 'e':e }));
});
else {
// throw new Error('Weather: LL missing');
logger.warn('FS: oLat missing');
res.status(500).send('oLat Missing');
}
}));
app.listen(port, (err) => {
if (err)
return logger.error('Server error:', err);

View File

@ -1,35 +1,23 @@
const logger = require('log4js').getLogger('RightByMe');
const foursquare = require('node-foursquare-venues')('IXXFUGW3NC3DEVS2V5EU4NV4CL5E12AYGUPIR2D3U3B5DX4B', 'MZRIJDCEKUMVERA1OKVAIZI0TYAEBD3W2A2AGPTPI5TOLL1D', '20181111');
const foursquare = require('node-foursquare-venues')('IXXFUGW3NC3DEVS2V5EU4NV4CL5E12AYGUPIR2D3U3B5DX4B', 'MZRIJDCEKUMVERA1OKVAIZI0TYAEBD3W2A2AGPTPI5TOLL1D', '20170801');
const Twitter = require('twitter');
const yelp = require('yelp-fusion');
const jsonfile = require('jsonfile');
const dateformat = require('dateformat');
const client = yelp.client('YlF_b6D149xr_xnrrYudlSnpn1A53b67vALlIK2HnD0ymBXQocRvPW3KjGN8jZNw0KnyAqxGaOzU7CLVPr84_KbnTxutNRXFVR9axmRqGN6ccda1xahoZo58KC2GWnYx');
const { get, isEmpty, has } = require('lodash');
const { reduceExplore, reduceYelp, reduceFullFS, reduceTwitter, reducePhotos } = require('./reducers/rightbyme');
const { reduceExplore, reduceYelp, reduceFullFS, reduceTwitter } = require('./reducers/rightbyme');
const twitterClient = new Twitter({
'consumer_key': 'bJvwgjA9O52j7rC6mqoeefPLO',
'consumer_secret': 'NB6ASJxxMI9yaOgTAlWEpd18J1BdtIOYb4iz1HivIVpPqSLBY5',
'access_token_key': '4773651-Ix1Qemdg4k02UV6A4ZRmwgD94eEPmYb6Y77QkzpWZA',
'access_token_secret': 'RweUNv147YCAglOqk8myOVNuoVBvo6F9HPT3kM5ERQtR2'
'access_token_key': '4773651-1IrcQuKzEBQYe89Ooe0wCEP3reiyJZ1SQl003b5DoU',
'access_token_secret': 'AHWGNQLAVGrXeUU3FU1ubdro4z5zc5igeiN4B9qI99xIt'
});
logger.level = 'debug';
// google api key AIzaSyBl7O9LHIthCagcqIaDkQ4um_hghYG5reE
function nowTS() {
const now = new Date();
// return dateformat(now, 'yymmddMMHH');
return '';
}
function doFSVenueSearch(ll, data = {}) {
let payLoad = Object.assign({}, data);
logger.debug('>> doFSVenueSearch');
@ -45,7 +33,7 @@ function doFSVenueSearch(ll, data = {}) {
if (isEmpty(payLoad))
foursquare.venues.search(fsObj, function(err, fsData) {
if (err) {
logger.debug('doFSVenueSearch', err);
logger.debug(err);
return reject(err);
}
@ -56,8 +44,6 @@ function doFSVenueSearch(ll, data = {}) {
payLoad = reduceExplore(fsP1);
jsonfile.writeFileSync(`output/${payLoad.id}-FSVenueSearch.json`, fsData);
return resolve(payLoad);
}
}
@ -98,9 +84,6 @@ function doFSVenueExplore(ll) {
payLoad = reduceExplore(fsP1);
}
logger.debug(payLoad);
// jsonfile.writeFileSync(`output/${payLoad.id}-FSVenueExplore.json`, fsData);
return resolve(payLoad);
}
});
@ -131,11 +114,9 @@ function doYelpSearch(data = {}) {
payLoad.yelp = reduceYelp(yelpReply);
jsonfile.writeFileSync(`output/${payLoad.id}-yelp.json`, response);
return resolve(payLoad);
}).catch(e => {
console.error('doYelpSearch', e);
console.error(e);
return reject(e);
});
@ -160,48 +141,11 @@ function doFSGetFullVenue(data = {}) {
if (err)
return reject(err);
else {
// console.log(JSON.stringify(fsData));
console.log(JSON.stringify(fsData));
const initPayload = (has(payLoad, 'name')) ? {} : reduceExplore(get(fsData, 'response.venue'));
const partPayload = reduceFullFS(get(fsData, 'response.venue'));
const newPayload = Object.assign(payLoad, initPayload, partPayload);
jsonfile.writeFileSync(`output/${payLoad.id}-FSGetFullVenue.json`, fsData);
return resolve(newPayload);
}
});
}
else
return resolve(payLoad);
});
}
function doFSGetPhotos(data = {}) {
const payLoad = Object.assign({}, data);
logger.debug('>> doFSGetPhotos');
// https://api.foursquare.com/v2/venues/4c5ff51213791b8d0d5c4eaf?client_id=IXXFUGW3NC3DEVS2V5EU4NV4CL5E12AYGUPIR2D3U3B5DX4B&client_secret=MZRIJDCEKUMVERA1OKVAIZI0TYAEBD3W2A2AGPTPI5TOLL1D&v=20180224
return new Promise((resolve, reject) => {
if (!isEmpty(payLoad)) {
// stuff
// more
const id = payLoad.id;
foursquare.venues.photos(id, { 'limit':16 }, function(err, fsData) {
if (err)
return reject(err);
else {
// console.log(JSON.stringify(fsData));
jsonfile.writeFileSync('output/FSGetPhotos.json', fsData);
logger.debug('fsData', JSON.stringify(fsData));
const initPayload = (has(payLoad, 'name')) ? {} : reduceExplore(get(fsData, 'response.venue'));
const partPayload = reducePhotos(fsData);
const newPayload = Object.assign(payLoad, initPayload, partPayload);
// payLoad.images = partPayload;
jsonfile.writeFileSync(`output/${payLoad.id}-FSGetPhotos.json`, fsData);
return resolve(newPayload);
}
});
@ -223,11 +167,8 @@ function doTweetSearch(data = {}) {
const params = { 'screen_name': payLoad.twitter };
twitterClient.get('statuses/user_timeline', params, function(error, tweets, response) {
if (error) {
console.error('doTweetSearch', error);
if (error)
return reject(error);
}
else {
// const partPayload = reduceFullFS(get(fsData, 'response.venue'));
// const newPayload = Object.assign(payLoad, partPayload);
@ -237,8 +178,6 @@ function doTweetSearch(data = {}) {
payLoad.tweets = reducedTweets;
jsonfile.writeFileSync(`output/${payLoad.id}-Tweets.json`, tweets);
return resolve(payLoad);
}
});
@ -288,8 +227,7 @@ function doGetRightByMe(ll) {
// res.status(500).send('There was an error!');
})
.then((d) => {
logger.info('Final', d.name, d.id);
jsonfile.writeFileSync(`output/${d.id}-doGetRightByMe.json`, d);
logger.info('Final', d.name, d.id);;
return resolve(d);
});
@ -325,8 +263,7 @@ function doGetMoreDetail(id) {
// res.status(500).send('There was an error!');
})
.then((d) => {
logger.info('Final', (d.name || '***** Name Missing'), d.id);
jsonfile.writeFileSync(`output/${d.id}-doGetMoreDetail.json`, d);
logger.info('Final', d.name, d.id);
return resolve(d);
});

View File

@ -1,40 +1,22 @@
const request = require('request');
const FeedMe = require('feedme');
const http = require('http');
const logger = require('log4js').getLogger('Directions');
logger.level = 'debug';
const { reduceEstDirections, reduceIncidents, combine } = require('./reducers/directions');
const { reduceEstDirections } = require('./reducers/directions');
module.exports = {
'getTraffic': doGetEstDirections,
'getIncidents' : doGetTraffic,
doGetEstDirectionsWithIncidents
'getTraffic': doGetEstDirections
};
const headers = {};
const lastGood = {};
//
// https://maps.googleapis.com/maps/api/directions/json?origin=Toronto&destination=Montreal&key=AIzaSyBl7O9LHIthCagcqIaDkQ4um_hghYG5reE
async function doGetEstDirectionsWithIncidents(olat, olon, dlat, dlon) {
let traff = await doGetEstDirections(olat, olon, dlat, dlon);
let incid = await doGetTraffic();
logger.debug('after...');
let combined = combine(traff, incid);
return combined;
}
async function doGetEstDirections(olat, olon, dlat, dlon) {
function doGetEstDirections(olat, olon, dlat, dlon) {
logger.debug('doGetEstDirections');
const url = `https://sgws2.maps.yahoo.com/Directions?time=now&cache=n&flags=J&olat=${olat}&olon=${olon}&dlat=${dlat}&dlon=${dlon}&mode=11`;
const url = `https://sgws2.maps.yahoo.com/Directions?time=now&cache=n&flags=J&olat=${olat}&olon=${olon}&dlat=${dlat}&dlon=${dlon}`;
logger.debug(url);
return new Promise(function(resolve, reject) {
request(url, function(err, resp, body) {
if (err)
@ -47,7 +29,6 @@ async function doGetEstDirections(olat, olon, dlat, dlon) {
output.timestamp = new Date().getTime();
console.log(output);
return resolve(output);
}, function(error, response, body) {
console.log(response);
@ -60,61 +41,3 @@ async function doGetEstDirections(olat, olon, dlat, dlon) {
});
});
}
async function doGetTraffic() {
logger.debug('doGetTraffic');
return new Promise((resolve, reject) => {
// https://trafficscotland.org/rss/feeds/currentincidents.aspx
const options = {
'hostname': 'trafficscotland.org',
'path': '/rss/feeds/currentincidents.aspx',
'method': 'GET',
'headers': headers
};
http.get(options, (res) => {
const { statusCode } = res;
const contentType = res.headers['content-type'];
const reqLastModified = res.headers['date'];
logger.debug(res.headers);
let error;
logger.debug('contentType', contentType);
if (statusCode !== 200 && statusCode !== 304)
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`);
else if (!/^application\/rss\+xml/.test(contentType) && statusCode === 200)
error = new Error('Invalid content-type.\n' +
`Expected application/rss+xml but received ${contentType}`);
if (error) {
logger.error(error.message);
// consume response data to free up memory
res.resume();
return reject(error);
}
if ( statusCode === 200) {
headers['If-Modified-Since'] = reqLastModified;
const parser = new FeedMe(true);
res.pipe(parser);
parser.on('end', () => {
lastGood.page = reduceIncidents(parser.done());
logger.info('Traffic Feed cached');
// return resolve(parser.done());
return resolve(lastGood.page);
});
}
else if (statusCode === 304) {
logger.info('Traffic Feed changed');
return resolve(lastGood.page);
}
});
});
}

View File

@ -3,7 +3,7 @@ const fecha = require('fecha');
const request = require('request');
const http = require('http');
const { reduceArticle, reduceArticleV2 } = require('./reducers/euronews');
const { reduceArticle } = require('./reducers/euronews');
const logger = require('log4js').getLogger('Euronews');
logger.level = 'debug';
@ -40,7 +40,7 @@ class Template {
function doGetEuroNews() {
return new Promise((resolve, reject) => {
logger.info('doGetEuroNews:Retrieving Euronews Headlines..');
logger.info('Retrieving Euronews Headlines..');
// http://feeds.feedburner.com/euronews/en/home/
// http://feeds.feedburner.com/euronews/en/news/
@ -105,8 +105,6 @@ function doGetArticle(guid = '') {
const ampURL = `${url[1]}amp/${url[2]}`;
logger.debug('ampURL', ampURL);
return new Promise(function(resolve, reject) {
request(ampURL, function(err, resp, body) {
if (err)
@ -114,9 +112,7 @@ function doGetArticle(guid = '') {
return reject(err);
// Throw err;
const output = reduceArticleV2(body);
logger.debug(JSON.stringify(output));
const output = reduceArticle(body);
return resolve(output);
}, function(error, response, body) {

View File

@ -3,26 +3,20 @@ const foursquare = require('node-foursquare-venues')('IXXFUGW3NC3DEVS2V5EU4NV4CL
logger.level = 'debug';
function doGetFourSquareExplore(ll, limit = 3, section = 'topPicks', query = '') {
function doGetFourSquareExplore(ll, limit = 3, section = 'topPicks') {
const [lat, long ] = ll.split(',');
console.log('>> query', query);
return new Promise((resolve, reject) => {
const fsObj = {
'll': ll,
'section': section,
'v': '20170801',
'limit': limit,
'radius': 800
};
if (query === '' )
fsObj.section = section;
else
fsObj.query = query;
console.log('>> fsObj', fsObj);
foursquare.venues.explore(fsObj, function(err, fsData) {
logger.error(err);
logger.debug(err);
if (err)
return reject(err);
else

View File

@ -1,96 +0,0 @@
const NodeGeocoder = require('node-geocoder');
const logger = require('log4js').getLogger('GeoCode');
const { reduceOpencage } = require('./reducers/opencage');
logger.level = 'debug';
const options = {
'provider': 'opencage',
// Optional depending on the providers
'httpAdapter': 'https', // Default
'apiKey': '893ab539eca84b5ca7a54cb03ef23443', // for Mapquest, OpenCage, Google Premier
'formatter': null // 'gpx', 'string', ...
};
const geocoder = NodeGeocoder(options);
function doGetGeocode(ll) {
return new Promise((resolve, reject) => {
const [lat, lon ] = ll.split(',');
const latlong = { lat, lon };
logger.debug(latlong);
geocoder.reverse(latlong)
.then(function(res) {
if (res.hasOwnProperty('raw')) {
const result = reduceOpencage(res.raw);
return resolve(result[0]);
}
else
return resolve(res[0]);
})
.catch(function(err) {
logger.error(err);
return reject(err);
});
});
}
module.exports = { doGetGeocode };
/*
opencage
{
"latitude": 51.508751,
"longitude": -0.067457,
"country": "United Kingdom",
"city": "London",
"state": "England",
"zipcode": "SE15",
"streetName": "Vaughan Way",
"countryCode": "gb",
"suburb": "St.George in the East",
"extra": {
"flag": "🇬🇧",
"confidence": 9,
"confidenceKM": 0.5,
"map": "https://www.openstreetmap.org/?mlat=51.50875&mlon=-0.06746#map=17/51.50875/-0.06746"
}
}
google
[
{
"administrativeLevels": {
"level1long": "England",
"level1short": "England",
"level2long": "Northamptonshire",
"level2short": "Northamptonshire"
},
"city": "Northampton",
"country": "United Kingdom",
"countryCode": "GB",
"extra": {
"confidence": 0.7,
"establishment": "Daventy depot",
"googlePlaceId": "ChIJI8H0WFUVd0gRIIFzNwDQAuM",
"neighborhood": "Kilsby",
"premise": null,
"subpremise": null
},
"formattedAddress": "Daventy depot, Kilsby, Northampton NN6 7GY, UK",
"latitude": 52.3546726,
"longitude": -1.1741823,
"provider": "google",
"zipcode": "NN6 7GY"
}
]
*/

View File

@ -1,358 +0,0 @@
var readabilityVersion = '2';
var readStyle = 'style-ebook';
var readSize = 'size-medium';
var readMargin = 'margin-wide';
(function() {
// removing all existing scripts so they don't cause conflicts...
var docscripts = document.getElementsByTagName('script');
for (k = 0;k < docscripts.length; k++)
if (docscripts[k].src != null && ! docscripts[k].src.match(/readability|[Cc]lippability/))
docscripts[k].parentNode.removeChild(docscripts[k]);
// let's just load jQuery and get it over with
var gjs = document.createElement('SCRIPT');
gjs.type = 'text/javascript';
gjs.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js';
document.getElementsByTagName('head')[0].appendChild(gjs);
gjs.onload = gjs.onreadystatechange = function() {
$('script').each(function() {
// jQuery gets scripts inside of conditional comments far more easily than I could figure out
if (! this.src.match(/readability|[Cc]lippability|jquery\.min\.js$/)) $(this).remove();
});
};
var objOverlay = document.createElement('div');
var objinnerDiv = document.createElement('div');
objOverlay.id = 'readOverlay';
objinnerDiv.id = 'readInner';
// Apply user-selected styling:
document.body.className = readStyle;
objOverlay.className = readStyle;
objinnerDiv.className = `${readMargin } ${ readSize}`;
objinnerDiv.appendChild(grabArticle()); // Get the article and place it inside the inner Div
objOverlay.appendChild(objinnerDiv); // Insert the inner div into the overlay
// For totally hosed HTML, add body node that can't be found because of bad HTML or something.
if(document.body == null) {
body = document.createElement('body');
document.body = body;
}
document.body.innerHTML = '';
// Inserts the new content :
document.body.insertBefore(objOverlay, document.body.firstChild);
var o = document.body.firstChild;
return o.innerHTML;
})();
function getElementsByClassName(classname, node) {
if(!node) node = document.getElementsByTagName('body')[0];
var a = [];
var re = new RegExp(`\\b${ classname }\\b`);
var els = node.getElementsByTagName('*');
for(var i = 0, j = els.length; i < j; i++)
if(re.test(els[i].className))a.push(els[i]);
return a;
}
function grabArticle() {
var allParagraphs = document.getElementsByTagName('p');
var topDivCount = 0;
var topDiv = null;
var topDivParas;
var articleContent = document.createElement('DIV');
var articleTitle = document.createElement('H1');
var articleFooter = document.createElement('DIV');
// Replace all doubled-up <BR> tags with <P> tags, and remove fonts.
var pattern = new RegExp ('<br/?>[ \r\n\s]*<br/?>', 'g');
document.body.innerHTML = document.body.innerHTML.replace(pattern, '</p><p>').replace(/<\/?font[^>]*>/g, '');
// Grab the title from the <title> tag and inject it as the title.
articleTitle.innerHTML = document.title;
articleContent.appendChild(articleTitle);
// Study all the paragraphs and find the chunk that has the best score.
// A score is determined by things like: Number of <p>'s, commas, special classes, etc.
for (var j = 0; j < allParagraphs.length; j++) {
parentNode = allParagraphs[j].parentNode;
// Initialize readability data
if(typeof parentNode.readability === 'undefined') {
parentNode.readability = { 'contentScore': 0 };
// Look for a special classname
if(parentNode.className.match(/(comment|meta|footer|footnote)/))
parentNode.readability.contentScore -= 50;
else if(parentNode.className.match(/((^|\\s)(post|hentry|entry[-]?(content|text|body)?|article[-]?(content|text|body)?)(\\s|$))/))
parentNode.readability.contentScore += 25;
// Look for a special ID
if(parentNode.id.match(/(comment|meta|footer|footnote)/))
parentNode.readability.contentScore -= 50;
else if(parentNode.id.match(/^(post|hentry|entry[-]?(content|text|body)?|article[-]?(content|text|body)?)$/))
parentNode.readability.contentScore += 25;
}
// Add a point for the paragraph found
if(getInnerText(allParagraphs[j]).length > 10)
parentNode.readability.contentScore++;
// Add points for any commas within this paragraph
parentNode.readability.contentScore += getCharCount(allParagraphs[j]);
}
// Assignment from index for performance. See http://www.peachpit.com/articles/article.aspx?p=31567&seqNum=5
for(nodeIndex = 0; (node = document.getElementsByTagName('*')[nodeIndex]); nodeIndex++)
if(typeof node.readability !== 'undefined' && (topDiv == null || node.readability.contentScore > topDiv.readability.contentScore))
topDiv = node;
if(topDiv == null) {
topDiv = document.createElement('div');
topDiv.innerHTML = 'Sorry, clippable was unable to parse this page for content. If you feel like it should have been able to, please <a href="http://brettterpstra.com/contact">let us know.</a>';
}
// REMOVES ALL STYLESHEETS ...
for (var k = 0;k < document.styleSheets.length; k++)
if (document.styleSheets[k].href != null && document.styleSheets[k].href.lastIndexOf('readability') == -1)
document.styleSheets[k].disabled = true;
var sh = getElementsByClassName('syntaxhighlighter');
for (var i = 0;i < sh.length;i++) {
var bar = getElementsByClassName('toolbar', sh[i]);
if (bar.length > 0)
for (var bn = 0;bn < bar.length;bn++)
bar[bn].parentNode.removeChild(bar[bn]);
var numbers = getElementsByClassName('number', sh[i]);
if (numbers.length > 0)
for (var num = 0;num < numbers.length;num++)
numbers[num].parentNode.removeChild(numbers[num]);
}
var dp = getElementsByClassName('dp-highlighter');
for (var d = 0;d < dp.length;d++)
dp[d].parentNode.removeChild(dp[d]);
var sth = getElementsByClassName('standardLighter');
for (d = 0;d < sth.length;d++)
sth[d].parentNode.removeChild(sth[d]);
// Remove all style tags in head (not doing this on IE) :
var styleTags = document.getElementsByTagName('style');
for (var l = 0;l < styleTags.length; l++)
if (navigator.appName != 'Microsoft Internet Explorer')
styleTags[l].textContent = '';
topDiv = killCodeSpans(topDiv); // removes span tags
cleanStyles(topDiv); // Removes all style attributes
topDiv = killDivs(topDiv); // Goes in and removes DIV's that have more non <p> stuff than <p> stuff
topDiv = killBreaks(topDiv); // Removes any consecutive <br />'s into just one <br />
// Cleans out junk from the topDiv just in case:
topDiv = clean(topDiv, 'form');
// topDiv = clean(topDiv, "object");
topDiv = clean(topDiv, 'table', 8);
topDiv = clean(topDiv, 'h1');
// topDiv = clean(topDiv, "h2");
topDiv = clean(topDiv, 'iframe');
// Add the footer and contents:
articleFooter.id = 'readFooter';
articleFooter.innerHTML = `\
<a href='http://lab.arc90.com/experiments/readability'><img src='http://lab.arc90.com/experiments/readability/images/footer-readability.png'></a>\
<a href='http://www.arc90.com'><img src='http://lab.arc90.com/experiments/readability/images/footer-arc90.png'></a>\
<a href='http://www.twitter.com/arc90' class='footer-twitterLink'>Follow us on Twitter &raquo;</a>\
<div class='footer-right' >\
<span class='version'>Readability version ${ readabilityVersion }</span>\
</div>\
`;
articleContent.appendChild(topDiv);
// articleContent.appendChild(articleFooter);
document.onkeyup = docOnKeyup;
return articleContent;
}
function docOnKeyup(ev) {
var keyID = null;
if (navigator.appName == 'Microsoft Internet Explorer')
keyID = event.keyCode;
else
keyID = (window.event) ? event.keyCode : ev.keyCode;
var bgcolor, fgcolor, acolor;
switch (keyID) {
case 27: // escape
document.location.reload(true);
break;
case 37: // left arrow
bgcolor = '#222';
fgcolor = '#F3EFCE';
acolor = '#A19F89';
break;
case 39: // right arrow
bgcolor = '#fff';
fgcolor = '#333';
acolor = '#276F78';
break;
case 46: // delete
bgcolor = '#eee';
fgcolor = '#333';
acolor = '#blue';
break;
}
body = document.getElementById('readOverlay');
// body.className = body.className.replace('/\blightened\b/','') + " darkened";
body.style.backgroundColor = bgcolor;
body.style.color = fgcolor;
var alinks = body.getElementsByTagName('a');
for (var lc = 0;lc < alinks.length;lc++)
alinks[lc].style.color = acolor;
}
// Get the inner text of a node - cross browser compatibly.
function getInnerText(e) {
if (navigator.appName == 'Microsoft Internet Explorer')
return e.innerText;
else
return e.textContent;
}
// Get character count
function getCharCount ( e, s ) {
s = s || ',';
return getInnerText(e).split(s).length;
}
function cleanStyles( e ) {
e = e || document;
var cur = e.firstChild;
// If we had a bad node, there's not much we can do.
if(!e)
return;
// Remove any root styles, if we're able.
if(typeof e.removeAttribute === 'function')
e.removeAttribute('style');
// Go until there are no more child nodes
while ( cur != null ) {
if ( cur.nodeType == 1 ) {
// Remove style attribute(s) :
cur.removeAttribute('style');
cleanStyles( cur );
}
cur = cur.nextSibling;
}
}
function killDivs ( e ) {
var divsList = e.getElementsByTagName( 'div' );
var curDivLength = divsList.length;
// Gather counts for other typical elements embedded within.
// Traverse backwards so we can remove nodes at the same time without effecting the traversal.
for (var i = curDivLength - 1; i >= 0; i--) {
var p = divsList[i].getElementsByTagName('p').length;
var img = divsList[i].getElementsByTagName('img').length;
var li = divsList[i].getElementsByTagName('li').length;
var a = divsList[i].getElementsByTagName('a').length;
var embed = divsList[i].getElementsByTagName('embed').length;
var object = divsList[i].getElementsByTagName('object').length;
var pre = divsList[i].getElementsByTagName('pre').length;
var code = divsList[i].getElementsByTagName('code').length;
var divId = divsList[i].id;
var divClass = divsList[i].className;
var sphereit = divsList[i].innerHTML.match('<!-- sphereit') == null ? 0 : 1;
// If the number of commas is less than 10 (bad sign) ...
if ( getCharCount(divsList[i]) < 10 )
// And the number of non-paragraph elements is more than paragraphs
// or other ominous signs :
if (( img > p || li > p || a > p || p == 0 || divId.match('comment') != null || divClass.match('comment') != null || divId.match('share') != null || divClass.match('share') != null) && ( pre == 0 && code == 0 && embed == 0 && object == 0 && sphereit == 0 )) {
if (!p == 0 && img == 1) divsList[i].parentNode.removeChild(divsList[i]);
}
var stopwords = ['comment', 'share', 'footer', '^ad'];
for (var sw = 0;sw < stopwords.length;sw++) {
regex = new RegExp(stopwords[sw]);
if (divId.match(regex) != null || divClass.match(regex) != null) {
console.log(`matched ${stopwords[sw]}`);
divsList[i].parentNode.removeChild(divsList[i]);
}
}
// if (divId.match("comment") != null || divClass.match("comment") != null || divId.match("share") != null || divClass.match("share") != null || divClass.match("footer") != null || divId.match("footer") != null || divClass.match(/^ad/) != null || divId.match(/^ad/) != null) {
// divsList[i].parentNode.removeChild(divsList[i]);
// }
}
return e;
}
function killBreaks ( e ) {
e.innerHTML = e.innerHTML.replace(/(<br\s*\/?>(\s|&nbsp;?)*){1,}/g, '<br />');
return e;
}
function killCodeSpans ( e ) {
e.innerHTML = e.innerHTML.replace(/<\/?\s?span(?:[^>]+)?>/g, '');
return e;
}
function clean(e, tags, minWords) {
var targetList;
var y;
if (tags == 'table') {
targetList = e.getElementsByTagName( tags );
minWords = minWords || 1000000;
for (y = 0; y < targetList.length; y++) {
// If the text content isn't laden with words, remove the child:
cells = targetList[y].getElementsByTagName('td').length;
if (cells < minWords)
targetList[y].parentNode.removeChild(targetList[y]);
}
}
else {
targetList = e.getElementsByTagName( tags );
minWords = minWords || 1000000;
for (y = 0; y < targetList.length; y++)
// If the text content isn't laden with words, remove the child:
if (getCharCount(targetList[y], ' ') < minWords && targetList[y].tagName != 'pre')
targetList[y].parentNode.removeChild(targetList[y]);
}
return e;
}
function convert(e, tagId) {
var children, parent, newNode;
var elems = document.getElementsByTagName(tagId);
for (y = 0; y < elems.length; y++) {
children = elems[y].childNodes;
parent = elems[y].parentNode;
newNode = document.createElement('span');
newNode.setAttribute('style', 'font-weight:bold');
for(var i = 0;i < children.length;i++)
newNode.appendChild(children[i]);
parent.replaceChild(newNode, elems[y]);
}
return e;
}

View File

@ -1,6 +1,6 @@
const logger = require('log4js').getLogger('Directions 🔧');
const { get, isEmpty, has, uniq } = require('lodash');
const { get, isEmpty, has } = require('lodash');
const humanizeDuration = require('humanize-duration');
logger.level = 'debug';
@ -10,20 +10,16 @@ const htmlTidy = /<(\/*?)(?!(em|p|br\s*\/|strong|h1|h2|h3))\w+?.+?>/gim;
function reduceEstDirections(body = '') {
if (body === '') return {};
// logger.debug(body);
const jBody = JSON.parse(body);
const obj = {};
const { ResultSet } = jBody;
const streets = [];
const steps = [];
if (has(ResultSet, 'Result')) {
const directions = get(ResultSet, 'Result.yahoo_driving_directions');
const route = get(directions, 'directions.route_leg');
obj.totalTime = parseFloat(get(directions, 'total_time'));
obj.totalTimeWithTraffic = parseFloat(get(directions, 'total_time_with_traffic'));
obj.readable = humanizeDuration((obj.totalTimeWithTraffic !== 0 ? obj.totalTimeWithTraffic : obj.totalTime) * 60 * 1000);
obj.readable = humanizeDuration(obj.totalTimeWithTraffic * 60 * 1000);
obj.timePercentage = ((obj.totalTime * ( obj.totalTimeWithTraffic / 100 )) + obj.totalTime) - 100;
@ -43,52 +39,9 @@ function reduceEstDirections(body = '') {
obj.traffic = 'no traffic';
obj.className = 'trafficNone';
}
for (const item of route) {
if (item.hasOwnProperty('street')) {
const street = item.street.split(',');
if (street[0] !== '') streets.push(street[0]);
}
if (has(item, 'description')) {
steps.push(item.description);
}
}
obj.directions = steps;
obj.streets = uniq(streets);
}
return obj;
}
function reduceIncidents(body = '') {
if (body === '') return [];
const workObj = Object.assign({}, body);
const incidents = [];
const items = get(workObj, 'items');
for (const item of items) {
const title = item.title.split(' ');
incidents.push({
'title' : item.title,
'description': item.description,
'road' : title[0]
});
}
return incidents;
}
function combine(traffic, incidents) {
const workObj = Object.assign({ 'incidents':[] }, traffic);
for (const item of incidents)
if (workObj.streets.indexOf(item.road) > -1)
workObj.incidents.push(item);
return workObj;
}
module.exports = { reduceEstDirections, reduceIncidents, combine };
module.exports = { reduceEstDirections };

View File

@ -20,115 +20,20 @@ function reduceArticle(body = '') {
const html = [];
const content = $('div.c-article-content');
const ampAddStripper = /<\s*amp-ad(\s+.*?>|>).*?<\s*\/\s*amp-ad\s*>/ig;
$(content).find('amp-ad').remove();
$(content).find('div.widget__wrapper').remove();
$(content).find('div.widget').remove();
for (let top = 0, topLen = content.length; top < topLen; top++) {
const children = $(content[top]).children();
for (let index = 0, len = children.length; index < len; index++) {
let line = $.html($(children[index])).replace('amp-img', 'img');
const tag = children[index].name;
const symbol = /src=(['"])(http[s]?:\/\/)/.exec(line) || [];
if (tag === 'amp-twitter') {
const tweetid = $(children[index]).data('tweetid');
line = `<amp-twitter width="375"
height="472"
layout="responsive" data-tweetid="${tweetid}" > </amp-twitter>`;
}
// logger.debug(symbol);
if (symbol.length !== 0)
line = line.replace(/src=['"]http[s]?:\/\//, `src=${symbol[1]}https://image.silvrtree.co.uk/640,fit,q80/${symbol[2]}`);
html.push(line);
}
}
// stuff.children().each(function () {
stuff.each(function () {
html.push($(this).html());
});
html.push('<div class="endbumper"></div>');
// const outputHTML = html.join('').replace(htmlTidy, '');
const outputHTML = html.join('');
console.log(outputHTML);
obj.title = title;
obj.image = image;
obj.html = outputHTML;
logger.debug(JSON.stringify(obj));
return obj;
}
function reduceArticleV2(body = '') {
if (body === '') return {};
const obj = {};
const $ = cheerio.load(body);
$('amp-ad').remove();
const title = $('meta[property="og:title"]').attr('content');
const image = `https://image.silvrtree.co.uk/640,fit,q80/${ $('meta[property="og:image"]').attr('content')}`;
const stuff = $('[itemprop="articleBody"]');
const html = [];
const content = $('div.c-article-content');
const ampAddStripper = /<\s*amp-ad(\s+.*?>|>).*?<\s*\/\s*amp-ad\s*>/ig;
$(content).find('amp-ad').remove();
$(content).find('div.widget__wrapper').remove();
for (let top = 0, topLen = content.length; top < topLen; top++) {
const children = $(content[top]).children();
for (let index = 0, len = children.length; index < len; index++) {
let line = $.html($(children[index])).replace('amp-img', 'img');
const tag = children[index].name;
const symbol = /src=(['"])(http[s]?:\/\/)/.exec(line) || [];
if (tag === 'amp-twitter') {
const tweetid = $(children[index]).data('tweetid');
line = `<amp-twitter width="375"
height="472"
layout="responsive" data-tweetid="${tweetid}" > </amp-twitter>`;
}
// logger.debug(symbol);
if (symbol.length !== 0)
line = line.replace(/src=['"]http[s]?:\/\//, `src=${symbol[1]}https://image.silvrtree.co.uk/640,fit,q80/${symbol[2]}`);
html.push(line);
}
}
html.push('<div class="endbumper"></div>');
// const outputHTML = html.join('').replace(htmlTidy, '');
const outputHTML = html.join('');
console.log(outputHTML);
obj.title = title;
obj.image = image;
obj.html = outputHTML;
logger.debug(JSON.stringify(obj));
return obj;
}
module.exports = { reduceArticle, reduceArticleV2 };
module.exports = { reduceArticle };

View File

@ -1,60 +0,0 @@
const logger = require('log4js').getLogger('GeoCode 🔧');
const { get, isEmpty, has, uniq } = require('lodash');
logger.level = 'debug';
var ConfidenceInKM = {
'10': 0.25,
'9': 0.5,
'8': 1,
'7': 5,
'6': 7.5,
'5': 10,
'4': 15,
'3': 20,
'2': 25,
'1': Number.POSITIVE_INFINITY,
'0': Number.NaN
};
function formatResult (result) {
var confidence = result.confidence || 0;
return {
'latitude': result.geometry.lat,
'longitude': result.geometry.lng,
'country': result.components.country,
'city': result.components.city,
'state': result.components.state,
'zipcode': result.components.postcode,
'streetName': result.components.road,
'streetNumber': result.components.house_number,
'countryCode': result.components.country_code,
'county': result.components.county,
'suburb': result.components.suburb,
'neighbourhood' : result.components.neighbourhood,
'village' : result.components.village,
'formatted' : result.formatted,
'extra': {
'flag' : result.annotations.flag,
'confidence': confidence,
'confidenceKM': ConfidenceInKM[result.confidence] || Number.NaN,
'map' : result.annotations.OSM.url
}
};
}
function reduceOpencage(result) {
logger.debug(JSON.stringify(result));
const results = [];
if (result && result.results instanceof Array)
for (let i = 0; i < result.results.length; i++)
results.push(formatResult(result.results[i]));
return results;
}
module.exports = { reduceOpencage };

View File

@ -4,9 +4,6 @@ const { get, isEmpty } = require('lodash');
// Bearer YlF_b6D149xr_xnrrYudlSnpn1A53b67vALlIK2HnD0ymBXQocRvPW3KjGN8jZNw0KnyAqxGaOzU7CLVPr84_KbnTxutNRXFVR9axmRqGN6ccda1xahoZo58KC2GWnYx'
// google api key AIzaSyBl7O9LHIthCagcqIaDkQ4um_hghYG5reE
logger.level = 'debug';
function reduceExplore(data) {
@ -24,7 +21,6 @@ function reduceExplore(data) {
const iconSuffix = get(categories[0], 'icon.suffix', '');
obj.name = get(localObj, 'name', '');
obj.description = get(localObj, 'description', '');
obj.category = get(categories[0], 'shortName', '');
obj.icon = (iconPrefix !== '') ? `${iconPrefix}64${iconSuffix}` : '';
obj.id = get(localObj, 'id', '');
@ -35,7 +31,7 @@ function reduceExplore(data) {
obj.postcode = get(location, 'postalCode', '');
obj.twitter = get(contact, 'twitter', '');
obj.facebook = get(contact, 'facebookName', '');
obj.url = get(localObj, 'canonicalUrl', '');
obj.url = get(localObj, 'url', '');
obj.latitude = get(location, 'lat', '');
obj.longitude = get(location, 'lng', '');
@ -71,80 +67,12 @@ function reduceFullFS(data) {
const obj = {};
if (typeof data === 'undefined' || isEmpty(data)) return obj;
const localObj = Object.assign({}, data);
const photoBlob = get(localObj, 'photos.groups');
let photoItems;
for (const i of photoBlob)
if (i.type === 'venue')
photoItems = i.items;
const photosCount = (typeof(photoItems) !== 'undefined' && photoItems !== null) ? photoItems.length : 0;
const photosCount = get(localObj, 'photos.count', 0);
const tipsCount = get(localObj, 'tips.count', 0);
if (photosCount > 0)
obj.images = photoItems.map(item => {
const prefix = get(item, 'prefix', '');
const suffix = get(item, 'suffix', '');
const width = get(item, 'width', 640);
const height = get(item, 'height', 480);
const ratio = width / 640;
let ratioHeight = ~~(height / ratio);
if (ratioHeight <= 0) ratioHeight = 640;
const fsImgPath = `${prefix}${width}x${height}${suffix}`;
console.log(`https://image.silvrtree.co.uk/${640}x${ratioHeight},fit,q80/${fsImgPath}`);
// return `${prefix}${640}x${ratioHeight}${suffix}`;
return `https://image.silvrtree.co.uk/${640}x${ratioHeight},fit,q80/${fsImgPath}`;
});
if (tipsCount > 0) {
const tipItems = get(localObj, 'tips.groups[0].items');
obj.tips = tipItems.map(item => {
return get(item, 'text', '');
});
}
obj.menuUrl = get(localObj, 'menu.mobileUrl');
return obj;
}
function reduceTwitter(data) {
const urlReg = /(http|ftp|https):\/\/([\w+?\.\w+])+([a-zA-Z0-9\~\!\@\#\$\%\^\&\*\(\)_\-\=\+\\\/\?\.\:\;\'\,]*)?/;
let obj = [];
if (data.length > 0)
obj = data.map(item => {
let text = get(item, 'text');
const urlTest = urlReg.exec(text);
if (urlTest !== null) {
const newUrl = `<a hef='${urlTest[0]}'>${urlTest[0]}</a>`;
text = text.replace(urlTest[0], newUrl);
}
return text;
});
return obj;
}
function reducePhotos(data) {
const obj = {};
if (typeof data === 'undefined' || isEmpty(data)) return obj;
const localObj = Object.assign({}, data);
const photoBlob = get(localObj, 'response.photos');
let photoItems;
photoItems = photoBlob.items;
const photosCount = (typeof(photoItems) !== 'undefined' && photoItems !== null) ? photoItems.length : 0;
if (photosCount > 0)
if (photosCount > 0) {
const photoItems = get(localObj, 'photos.groups[0].items');
obj.images = photoItems.map(item => {
const prefix = get(item, 'prefix', '');
const suffix = get(item, 'suffix', '');
@ -158,8 +86,26 @@ function reducePhotos(data) {
return `${prefix}${640}x${ratioHeight}${suffix}`;
});
}
if (tipsCount > 0) {
const tipItems = get(localObj, 'tips.groups[0].items');
obj.tips = tipItems.map(item => {
return get(item, 'text', '');
});
}
return obj;
}
module.exports = { reduceExplore, reduceYelp, reduceFullFS, reduceTwitter, reducePhotos };
function reduceTwitter(data) {
let obj = [];
if (data.length > 0)
obj = data.map(item => {
return get(item, 'text');
});
return obj;
}
module.exports = { reduceExplore, reduceYelp, reduceFullFS, reduceTwitter };

View File

@ -68,24 +68,23 @@ function toCompass(degrees) {
function moonCalc(moonPhase) {
let output = '';
if (moonPhase === 0.0)
output = '🌕 New moon';
output = 'New moon';
else if (moonPhase >= 0.1 && moonPhase < 0.25)
output = '🌔 waxing crescent';
output = 'waxing crescent';
else if (moonPhase === 0.25)
output = '🌓 First Quarter';
output = 'First Quarter';
else if (moonPhase > 0.25 && moonPhase < 0.5)
output = '🌒 waxing gibbous';
output = 'waxing gibbous';
else if (moonPhase === 0.5)
output = '🌑 Full moon';
output = 'Full moon';
else if (moonPhase > 0.5 && moonPhase < 0.75)
output = '🌘 Waning gibbous';
output = 'Waning gibbous';
else if (moonPhase === 0.5)
output = '🌗 Third quarter';
output = 'Third quarter';
else if (moonPhase > 0.75)
output = '🌖 Waning crescent';
output = 'Waning crescent';
return output;
// ['🌑', '🌘', '🌗', '🌖', '🌕', '🌔', '🌓', '🌒']
// a value of 0 corresponds to a new moon, 0.25 to a first quarter moon, 0.5 to a full moon, and 0.75 to a last quarter moon. (The ranges
// in between these represent waxing crescent, waxing gibbous, waning gibbous, and waning crescent moons, respectively.)
}
@ -147,8 +146,6 @@ module.exports = { reduceWeather };
//
/*
moonPhase optional, only on daily
The fractional part of the lunation number during the given day: a value of 0 corresponds to a new moon, 0.25 to a first quarter
moon, 0.5 to a full moon, and 0.75 to a last quarter moon. (The ranges in between these represent waxing crescent, waxing gibbous,
waning gibbous, and waning crescent moons, respectively.)
The fractional part of the lunation number during the given day: a value of 0 corresponds to a new moon, 0.25 to a first quarter moon, 0.5 to a full moon, and 0.75 to a last quarter moon. (The ranges in between these represent waxing crescent, waxing gibbous, waning gibbous, and waning crescent moons, respectively.)
*/

View File

@ -1,38 +0,0 @@
/**
* Created by WebStorm.
* User: martin
* Date: 07/07/2020
* Time: 16:40
Look here https://admiraltyapi.portal.azure-api.net/docs/services/uk-tidal-api/operations/TidalEvents_GetTidalEvents?
it's an api
reduce admiralitySites.json to something better for quick searching against lat long.
helensburgh 0403
Primary key
b49297c9dacc4c6e92026d0dbec82948
Secondary key
d51efd816c2446b29e8be0f019c06f9c
https://admiraltyapi.azure-api.net/uktidalapi/api/V1/Stations/{stationId}/TidalEvents[?duration]
HTTP request
============
GET https://admiraltyapi.azure-api.net/uktidalapi/api/V1/Stations/0403/TidalEvents?duration=3 HTTP/1.1
Host: admiraltyapi.azure-api.net
Ocp-Apim-Subscription-Key: b49297c9dacc4c6e92026d0dbec82948
*/

View File

@ -1,6 +1,7 @@
const Client = require('request-json');
const logger = require('log4js').getLogger('Weather');
const { log4js } = require('./lib/logger');
const logger = log4js.getLogger('Weather');
const weather = require('openweather-apis');
const { reduceWeather } = require('./reducers/weather');
const request = require('request');

View File

@ -1,19 +0,0 @@
const http2 = require('http2');
const fs = require('fs');
const server = http2.createSecureServer({
key: fs.readFileSync('localhost-privkey.pem'),
cert: fs.readFileSync('localhost-cert.pem')
});
server.on('error', (err) => console.error(err));
server.on('stream', (stream, headers) => {
// stream is a Duplex
stream.respond({
'content-type': 'text/html',
':status': 200
});
stream.end('<h1>Hello World</h1>');
});
server.listen(8110);

View File

@ -87,55 +87,6 @@ body {
color: rgb(236, 110, 5)
}
.temp21 {
color: #ea5a24;
}
.temp22 {
color: #e4572b;
}
.temp23 {
color: #e14a29;
}
.temp24 {
color: #e04127;
}
.temp25 {
color: #d9372b;
}
.temp26 {
color: #d63129;
}
.temp27 {
color: #d12b2b;
}
.temp28 {
color: #cd282f;
}
.temp29 {
color: #c82432;
}
.temp30 {
color: #c32334;
}
.temp31 {
color: #be2138;
}
.temp32, .temp33, .temp34, .temp35 {
color: #b9203b;
}
.day {
font-family: "Roboto Slab", "Helvetica Neue", Helvetica, Arial, sans-serif;
text-transform: uppercase;

View File

@ -284,56 +284,6 @@ li {
color: rgb(236, 110, 5)
}
.temp21 {
color: #ea5a24;
}
.temp22 {
color: #e4572b;
}
.temp23 {
color: #e14a29;
}
.temp24 {
color: #e04127;
}
.temp25 {
color: #d9372b;
}
.temp26 {
color: #d63129;
}
.temp27 {
color: #d12b2b;
}
.temp28 {
color: #cd282f;
}
.temp29 {
color: #c82432;
}
.temp30 {
color: #c32334;
}
.temp31 {
color: #be2138;
}
.temp32, .temp33, .temp34, .temp35 {
color: #b9203b;
}
.day {
font-family: "Roboto Slab", "Helvetica Neue", Helvetica, Arial, sans-serif;
text-transform: uppercase;
@ -355,8 +305,6 @@ li {
#news{
height: 200px;
margin-top:15px;
-ms-overflow-style: -ms-autohiding-scrollbar;
}
#byme, #bymeYelp {
@ -425,11 +373,6 @@ li {
max-width:100%;
}
.newsarticle h1, .newsarticle h3, .newsarticle h3, .newsarticle h4 {
font-family: "Roboto Condensed", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-weight: 700;
}
.tiny {
font-size:1rem;
}
@ -483,19 +426,4 @@ li {
margin-bottom: 3px;
}
.separate {
border-bottom: 1px solid mui-color('grey', '200');
margin-bottom: 5px;
}
.greetPanel{
text-shadow: 1px 1px 2px #212121;
color: white;
height:24vw;
background-size: cover;
background-color: goldenrod;
background-image: url(../gfx/default_daily_image.jpg);
}
@import "./src/css/weather";

View File

@ -6,10 +6,6 @@
font-weight: 200;
}
.hourly {
-ms-overflow-style: -ms-autohiding-scrollbar;
}
.weatherDay {
background-image: url(../gfx/bg_morning.jpg);
}

View File

@ -1,3 +1,9 @@
Roboto+Condensed
Roboto+Condensed:300
Roboto+Mono
Roboto+Condensed:300,400,700
Roboto:100,300,400,400i,500,700,700i,900
Roboto:100
Roboto:300
Roboto:400
Roboto:500
Roboto:700
Roboto:900

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

View File

@ -11,11 +11,10 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
const CACHE_VERSION = { 'version': '0.0.1049' };
const PRECACHE = `jubileeData-${CACHE_VERSION.version}`;
const RUNTIME = 'runtime';
const PRECACHE_URLS = [
const CACHE_VERSION = { 'version': '0.0.689' };
const dataCacheName = 'jubileeData-v1';
const cacheName = 'jubilee-final-1';
const filesToCache = [
'/',
'/index.html',
'/service-worker.js',
@ -28,7 +27,6 @@ const PRECACHE_URLS = [
'/img/favicon-32x32.png',
'/img/android-chrome-192x192.png',
'/img/android-chrome-512x512.png',
'/gfx/default_daily_image.jpg',
'/gfx/stars_00.png',
'/gfx/stars_10.png',
'/gfx/stars_15.png',
@ -57,8 +55,6 @@ const PRECACHE_URLS = [
'/fonts/fonts.css',
'/fonts/fujicons.css',
'/fonts/fujicons.ttf',
'/fonts/Roboto-italic-400.woff',
'/fonts/Roboto-italic-700.woff',
'/fonts/Roboto-normal-100.woff',
'/fonts/Roboto-normal-300.woff',
'/fonts/Roboto-normal-400.woff',
@ -66,112 +62,81 @@ const PRECACHE_URLS = [
'/fonts/Roboto-normal-700.woff',
'/fonts/Roboto-normal-900.woff',
'/fonts/Roboto_Condensed-normal-300.woff',
'/fonts/Roboto_Condensed-normal-400.woff',
'/fonts/Roboto_Condensed-normal-700.woff'
'/fonts/Roboto_Condensed-normal-400.woff'
];
const liveData = ['news', 'agenda'];
self.addEventListener('install', function(e) {
console.log('[ServiceWorker] Install');
e.waitUntil(
caches.open(cacheName).then(function(cache) {
console.log('[ServiceWorker] Caching app shell');
self.addEventListener('install', event => {
console.warn('Installing...');
event.waitUntil(
caches.open(PRECACHE)
.then(cache => cache.addAll(PRECACHE_URLS))
.then(self.skipWaiting())
return cache.addAll(filesToCache);
})
);
});
// The activate handler takes care of cleaning up old caches.
self.addEventListener('activate', event => {
console.warn('Activate...');
const currentCaches = [PRECACHE, RUNTIME];
event.waitUntil(
caches.keys().then(cacheNames => {
return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));
}).then(cachesToDelete => {
return Promise.all(cachesToDelete.map(cacheToDelete => {
return caches.delete(cacheToDelete);
self.addEventListener('activate', function(e) {
console.log('[ServiceWorker] Activate');
e.waitUntil(
caches.keys().then(function(keyList) {
return Promise.all(keyList.map(function(key) {
if (key !== cacheName && key !== dataCacheName) {
console.log('[ServiceWorker] Removing old cache', key);
return caches.delete(key);
}
}));
}).then(() => self.clients.claim())
})
);
/*
* Fixes a corner case in which the app wasn't returning the latest data.
* You can reproduce the corner case by commenting out the line below and
* then doing the following steps: 1) load app for first time so that the
* initial New York City data is shown 2) press the refresh button on the
* app 3) go offline 4) reload the app. You expect to see the newer NYC
* data, but you actually see the initial data. This happens because the
* service worker is not yet activated. The code below essentially lets
* you activate the service worker faster.
*/
return self.clients.claim();
});
// The fetch handler serves responses for same-origin resources from a cache.
// If no response is found, it populates the runtime cache with the response
// from the network before returning it to the page.
self.addEventListener('fetch', event => {
console.warn('Fetch', event.request.url);
// Skip cross-origin requests, like those for Google Analytics.
/* if (event.request.url.startsWith(self.location.origin)) {
console.log('One of our requests..');
event.respondWith(
caches.match(event.request).then(cachedResponse => {
if (cachedResponse) {
console.log('cachedResponse', cachedResponse);
return cachedResponse;
}
self.addEventListener('fetch', function(e) {
console.warn('[Service Worker] Fetch', e.request.url);
const dataUrl = '/getnexttraintimes?';
if (e.request.url.indexOf(dataUrl) > -1) {
console.log('!');
return caches.open(RUNTIME).then(cache => {
return fetch(event.request).then(response => {
// Put a copy of the response in the runtime cache.
return cache.put(event.request, response.clone()).then(() => {
console.log('fetch cache response', response);
return response;
});
});
});
})
);
}*/
if (event.request.url.startsWith(self.location.origin)) {
console.log('!!', event.request);
/* event.respondWith(
caches.open(RUNTIME).then(function(cache) {
return cache.match(event.request).then(function (response) {
console.log('£', response);
return response || fetch(event.request).then(function(response) {
cache.put(event.request, response.clone());
/*
* When the request URL contains dataUrl, the app is asking for fresh
* weather data. In this case, the service worker always goes to the
* network and then caches the response. This is called the "Cache then
* network" strategy:
* https://jakearchibald.com/2014/offline-cookbook/#cache-then-network
*/
e.respondWith(
caches.open(dataCacheName).then(function(cache) {
return fetch(e.request).then(function(response) {
cache.put(e.request.url, response.clone());
return response;
});
});
})
);*/
event.respondWith(
caches.open(RUNTIME).then(function(cache) {
return cache.match(event.request).then(function (response) {
return response || fetch(event.request).then(function(response) {
cache.put(event.request, response.clone());
return response;
});
});
})
);
}
else
if (event.request.url.startsWith('https://maps.googleapis.com')) {
const url = new URL(event.request.url);
const locCache = `loc-${url.searchParams.get('latlng')}`;
event.respondWith(
caches.match(locCache).then(cachedResponse => {
if (cachedResponse)
return cachedResponse;
return caches.open(RUNTIME).then(cache => {
return fetch(event.request).then(response => {
// Put a copy of the response in the runtime cache.
return cache.put(locCache, response.clone()).then(() => {
return response;
});
});
});
/*
* The app is asking for app shell files. In this scenario the app uses the
* "Cache, falling back to the network" offline strategy:
* https://jakearchibald.com/2014/offline-cookbook/#cache-falling-back-to-network
*/
e.respondWith(
caches.match(e.request).then(function(response) {
return response || fetch(e.request);
})
);
}
});

View File

@ -1,117 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Jubilee</title>
<link href="//cdnjs.cloudflare.com/ajax/libs/weather-icons/2.0.9/css/weather-icons.css" rel="stylesheet" type="text/css"/>
<link href="/fonts/fonts.css" rel="stylesheet" type="text/css"/>
<link href="/fonts/fujicons.css" rel="stylesheet" type="text/css"/>
<link href="/css/mui.custom.css" rel="stylesheet" type="text/css"/>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css"
integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ=="
crossorigin=""/>
<link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/img/safari-pinned-tab.svg" color="#5bbad5">
<meta name="apple-mobile-web-app-title" content="Train Times">
<meta name="application-name" content="Sidekick">
<meta name="theme-color" content="#ffff00">
<script src="//cdn.layerjs.org/libs/layerjs/layerjs-0.6.1.min.js"></script>
<link href="//cdn.layerjs.org/libs/layerjs/layerjs-0.6.1.css" type="text/css" rel="stylesheet" />
</head>
<body>
<div data-lj-type="stage">
<div data-lj-type="layer" data-lj-default-frame="main" >
<div data-lj-type="frame" >
… your HTML code …
</div>
</div>
</div>
<div class="appPanel" data-id="main">
<div class="mui-container">
<div id="greet"></div>
<div id="location" class="mui-row" style="display: none;"></div>
</div>
<div class="mui-container" id="connectionStatus" style="display:none;">
<div class="mui--text-center"><i class="large fa fa-globe mui--align-middle mui--text-center"
style="color:grey;"></i></div>
<div class="mui--text-body1 mui--text-center">No internet connection</div>
</div>
<div class="mui-container" id="viewFrame">
<div id="weatherAlertShell" class="mui-panel" style="display: none;">
<div id="weatherAlertTitle" class="mui--text-title cardTitle">Weather Alert</div>
<div id="weatherAlert"></div>
</div>
<div id="bymeShell" class="mui-panel" style="display: none;">
<div id="byMeTitle" class="mui--text-title cardTitle">By me</div>
<div id="byme"></div>
</div>
<div id="trafficShell" class="mui-panel" style="display: none;">
<div class="mui--text-title cardTitle">Traffic</div>
<div id="traffic"></div>
</div>
<div id="agendaShell" class="mui-panel" style="display: none;">
<div class="mui--text-title cardTitle">Upcoming events</div>
<div id="agenda"></div>
</div>
<div id="nearbyShell" class="mui-panel" style="display: none;">
<div class="mui--text-title cardTitle">Around me</div>
<div id="nearby"></div>
</div>
<div id="nearbyShell" class="mui-panel" style="display: none;">
<div class="mui--text-title cardTitle">Nearby places</div>
<div id="nearbyPlaces"></div>
</div>
<div id="newsShell" class="mui-panel" style="display: none;">
<div class="mui--text-title cardTitle">Latest news</div>
<div id="news" class="scrolling-wrapper-flexbox"></div>
<div id='newsMore' class="cardLink">
<i class="seemore fa fa-forward mui--align-middle " ></i> <span class="seemore mui--align-middle">More news</span>
</div>
</div>
<div id="weatherShell" class="mui-panel" style="display: none;">
<div class="mui--text-title cardTitle">Weather</div>
<div id="weather"></div>
</div>
</div>
</div>
<script src="js/vendor.js" async></script>
<script type='module' src="js/bundle.js" async></script>
<script async="" src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-element="amp-twitter" src="https://cdn.ampproject.org/v0/amp-twitter-0.1.js"></script>
<noscript>
<!-- anchor linking to external file -->
<h1>Javascript disabled</h1>
<p>This really requires javascript to work</p>
</noscript>
</body>
</html>

View File

@ -20,28 +20,13 @@
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/img/safari-pinned-tab.svg" color="#5bbad5">
<meta name="apple-mobile-web-app-title" content="Train Times">
<meta name="application-name" content="Sidekick">
<meta name="theme-color" content="#ffff00">
<meta name="application-name" content="Train Times">
<meta name="theme-color" content="#ffffff">
<!-- <script src="//cdn.layerjs.org/libs/layerjs/layerjs-0.6.1.min.js"></script>
<link href="//cdn.layerjs.org/libs/layerjs/layerjs-0.6.1.css" type="text/css" rel="stylesheet" />-->
</head>
<body>
<!--
<div data-lj-type="stage">
<div data-lj-type="layer" data-lj-default-frame="main" >
<div data-lj-type="frame" >
… your HTML code …
</div>
</div>
</div>
-->
<div class="appPanel" data-id="main">
<div class="mui-container">
<div id="greet"></div>
@ -105,9 +90,6 @@
<script src="js/vendor.js" async></script>
<script type='module' src="js/bundle.js" async></script>
<script async="" src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-element="amp-twitter" src="https://cdn.ampproject.org/v0/amp-twitter-0.1.js"></script>
<noscript>
<!-- anchor linking to external file -->
<h1>Javascript disabled</h1>

View File

@ -1,8 +1,10 @@
const $ = require('jquery');
const _ = require('underscore');
const Backbone = require('backbone');
const { toHour, hourFloor } = require('./libs/utils');
const request = require('request');
const { get } = require('lodash');
// const { reduceNearby } = require('./libs/reducers');
const { toHour } = require('./libs/utils');
const TimeFormat = require('hh-mm-ss');
const fecha = require('fecha');
@ -64,27 +66,24 @@ const AgendaModel = Backbone.Model.extend({
'getAgenda': function() {
const time = new Date().getTime() ;
console.log('>> agenda this', this);
const lastUpdate = time - (this.get('time') || 0);
console.log(`>> Agenda last fetch: ${TimeFormat.fromMs(lastUpdate, 'hh:mm')} ago`);
if (lastUpdate > 120000) {
const _url = new URL(`${window.loc}/agenda`);
if (lastUpdate > 120000)
request({
'url': `${window.loc}/agenda`,
'method': 'GET',
'qs': {
_url.search = new URLSearchParams({
'w' : hourFloor()
});
console.log(_url);
fetch(_url)
.then((res) => {
return res.json();
})
.then((agendaJSON) => {
}
}, function(err, res, body) {
if (err)
console.error(err);
else {
console.log('statusCode', res.statusCode);
const now = new Date().getTime();
const agendaJSON = JSON.parse(body);
const newAgenda = [];
// console.log('>> agendaJSON', agendaJSON);
@ -95,30 +94,23 @@ const AgendaModel = Backbone.Model.extend({
if (dend > now) {
// console.log('>> agenda', item);
item.timeStart = fecha.format(new Date(item.dtstart), 'shortTime');
const timeStart = fecha.format(new Date(item.dtstart), 'shortTime');
item.timeStart = timeStart;
newAgenda.push(item);
}
// console.log(dend);
}
this.agendaCollection.reset(newAgenda);
this.logUpdate();
}
}.bind(this));
}, 'logUpdate': function() {
console.log('>> Agenda logging:');
const time = new Date().getTime() ;
this.set('time', time);
})
.catch((e) => {
console.error(e);
});
}
}, 'logUpdate': () => {
console.log('>> Agenda logging:');
console.log('>> agend log update', this);
const time = new Date().getTime() ;
this.set('time', time, {silent: true});
}
});
@ -136,8 +128,6 @@ const AgendaView = Backbone.View.extend({
const now = new Date().getTime();
const since = now - this.model.get('time');
console.log('> t', now, this.model.get('time'));
console.log(`Agenda was last updated: ${TimeFormat.fromMs(since, 'hh:mm')} ago`);
if (since > (60 * 1000 * 60) )

View File

@ -4,9 +4,6 @@ const Backbone = require('backbone');
const request = require('request');
const { get, isEmpty } = require('lodash');
const { createPanel, addPanel } = require('./libs/panel');
const templates = require('./libs/templates');
const TimeFormat = require('hh-mm-ss');
const { hourFloor } = require('./libs/utils');
const ForecastModel = Backbone.Model.extend({
'defaults': function (obj) {
@ -30,8 +27,7 @@ const ForecastModel = Backbone.Model.extend({
'url': `${window.loc}/forecast`,
'method': 'GET',
'qs': {
'll': ll,
'w' : hourFloor()
'll': ll
}
}, function(err, res, body) {
console.log('statusCode', res.statusCode);
@ -44,27 +40,8 @@ const ForecastModel = Backbone.Model.extend({
fsJSON.last = new Date().getTime();
this.set(fsJSON);
// console.log(body);
this.logUpdate();
}
}.bind(this));
}, 'logUpdate': function() {
console.log('Forecast logging:');
const log = { 'lat' : this.get('latitude'), 'long': this.get('longitude'), 'time': new Date().getTime() };
this.set('log', log, {silent: true});
this.timerID = setTimeout(
() => this.tick(),
3.6e+6 + 1000
);
// console.log(this);
},
'tick': function() {
console.log('Set update');
this.set('update', new Date().getTime());
}
});
@ -79,9 +56,84 @@ const ForecastView = Backbone.View.extend({
this.model.bind('change:time', this.doRender, this);
this.eventBus.on('showForecast', this.showForecastPanel, this);
this.eventBus.on('focused', this.focused, this);
},
'templateCurrently': _.template(`
<div class="forecastCurrently mui-panel glassy">
<div class="mui--text-title"><i class="medium wi wi-forecast-io-<%= icon %>"></i> <%=summary%></div>
<div>
<i class="small fa fa-up mui--align-middle " ></i><%=tempMax%>°
<i class="small fa fa-down mui--align-middle " ></i><%=tempMin%>°
</div>
<div class="large temp<%=~~(temperature) %>"><%=temperature%>°</div>
</div>
`),
'templateForecast': _.template(`
<div class="forecastToday mui-panel glassy">
<h3>Forecast</h3>
<div class='scrolling-wrapper-flexbox hourly' style="height: 100px;">
<%_.forEach(today, function(i) {%>
<div class="hourlyCard">
<div class="mui--text-center"><%=i.time %></div>
<div class="mui--text-center"><i class="small wi wi-forecast-io-<%= i.icon %>"></i></div>
<div class="mui--text-center temp<%=~~(i.temp)%> normalWeight"><%=~~(i.temp)%>°</div>
</div>
<%}) %>
</div>
<div>
<div class="dailyCard">
<%_.forEach(daily, function(i) {%>
<div class="mui-row">
<div class="mui-col-xs-6 mui--text-left mui--text-title"><%=i.time %></div>
<div class="mui-col-xs-2 mui--text-center"><i class="mui--text-title wi wi-forecast-io-<%= i.icon %>"></i></div>
<div class="mui-col-xs-2 mui--text-center temp<%=~~(i.tempHigh) %> mui--text-title "><%=~~(i.tempHigh)%>°</div>
<div class="mui-col-xs-2 mui--text-center temp<%=~~(i.tempLow) %> mui--text-title"><%=~~(i.tempLow)%>°</div>
</div>
<%}) %>
</div>
</div>
</div>
`),
'templateDetails': _.template(`
<div class="forecastDetails mui-panel glassy">
<h3>Details</h3>
<div class="mui-row">
<div class="mui-col-xs-6 mui--text-left mui--text-body2">Humidity</div>
<div class="mui-col-xs-6 mui--text-right mui--text-title"><%=~~(humidity * 100) %>%</div>
</div>
<div class="mui-row">
<div class="mui-col-xs-6 mui--text-left mui--text-body2">Visibility</div>
<div class="mui-col-xs-6 mui--text-right mui--text-title"><%=visibility %><span class="mui--text-body1">km</span></div>
</div>
<div class="mui-row">
<div class="mui-col-xs-6 mui--text-left mui--text-body2">UV Index</div>
<div class="mui-col-xs-6 mui--text-right mui--text-title"><%=uvIndex %></div>
</div>
<div class="mui-row">
<div class="mui-col-xs-12 mui--text-left mui--text-body1"><%=summary%></div>
</div>
<h3>Wind & Pressure</h3>
<div class="mui-row">
<div class="mui-col-xs-6 mui-col-md-3 mui--text-left mui--text-body2">Wind</div>
<div class="mui-col-xs-6 mui-col-md-3 mui--text-right mui--text-title"><%=windSpeed %><span class="mui--text-body1">km/h</span></div>
<div class="mui-col-xs-6 mui-col-md-3 mui--text-left mui--text-body2">Barometer</div>
<div class="mui-col-xs-6 mui-col-md-3 mui--text-right mui--text-title"><%=pressure %><span class="mui--text-body1">mBar</span></div>
</div>
<h3>Sun & Moon</h3>
<div class="mui-row">
<div class="mui-col-xs-3 mui--text-left mui--text-body2">Sunrise</div>
<div class="mui-col-xs-3 mui--text-right mui--text-title"><%=sunriseTime %></div>
<div class="mui-col-xs-3 mui--text-left mui--text-body2">Sunset</div>
<div class="mui-col-xs-3 mui--text-right mui--text-title"><%=sunsetTime %></div>
</div>
</div>
`),
'showForecastPanel': function(ll) {
console.log('Showing forecast', ll);
const prevll = this.model.get('ll');
@ -134,10 +186,10 @@ const ForecastView = Backbone.View.extend({
const currently = this.model.get('currently');
const forcastToday = { 'today':this.model.get('forcastToday'), 'daily':this.model.get('dailyForecast') };
const details = this.model.get('details');
html.push('<div class="">');
html.push(templates.templateCurrently(currently));
html.push(templates.templateForecast(forcastToday));
html.push(templates.templateDetails(details));
html.push('<div class="">');
html.push(this.templateCurrently(currently));
html.push(this.templateForecast(forcastToday));
html.push(this.templateDetails(details));
html.push('</div>');
html.push('<div class="endbumper"></div>');
@ -193,21 +245,6 @@ const ForecastView = Backbone.View.extend({
}
return output;
}, 'focused': function() {
console.log('>> Forecast received focus msg');
if (!this.model.has('log')) {
console.log('No log yet');
return ;
}
const now = new Date().getTime();
const log = this.model.get('log');
const since = now - log.time;
console.log(`Forecast was last updated: ${TimeFormat.fromMs(since, 'hh:mm')} ago`);
if (since > (60 * 1000 * 60) )
this.model.set('update', now);
}
});

View File

@ -1,139 +0,0 @@
const $ = require('jquery');
const _ = require('underscore');
const Backbone = require('backbone');
const request = require('request');
const { get, has, isEmpty } = require('lodash');
const { createPanel, addPanel } = require('./libs/panel');
const templates = require('./libs/templates');
const GotoCardModel = Backbone.Model.extend({
'initialize': function() {
this.listenTo(this, 'change:detail', this.getDirections);
},
'getDirections': function() {
const { from, to } = this.get('detail');
console.log('goto from', from);
console.log('goto to', to);
const qs = {
'olat':to.lat, 'olon': to.long, 'dlat': from.lat, 'dlon': from.long
};
console.log('qs', qs);
request({
'url': `${window.loc}/traffic`,
'method': 'GET',
'qs': qs
}, function(err, res, body) {
if (err)
console.error(err);
else {
console.log('statusCode', res.statusCode);
const now = new Date().getTime();
const gotoJSON = JSON.parse(body);
console.log('>> gotoJSON', gotoJSON);
this.set('directions', gotoJSON.directions);
console.log(this.attributes);
// this.logUpdate();
}
}.bind(this));
}
});
const GotoCardView = Backbone.View.extend({
'initialize': function(options) {
this.eventBus = options.eventBus;
this.location = options.location;
this.location.bind('change', this.updateMyLocation, this);
/* this.model.on('all', function(eventName) {
console.log(`${eventName } was triggered!`);
});*/
this.model.bind('change:directions', this.doRender, this);
this.eventBus.on('showDirections', this.showDirectionsPanel, this);
},
'updateMyLocation': function(l) {
console.log('Goto:My location Changed', l);
},
'template': _.template(`
<div id='gotoDetails' class="mui-container" style="margin-bottom: 50px;">
<div><h1>Details</h1></div>
<div id="gotoDetailsText" class="mui-panel"></div>
</div>
</div>
`),
'showDirectionsPanel': function(toDest, cb = null) {
console.log('Showing directions', toDest);
const detail = { 'from':{}, 'to':{} };
this.$newPanel = createPanel({ 'title':'Directions', 'divId':'directionsP' }, cb);
this.$el = addPanel(this.$newPanel);
// this.$el.empty();
this.$newPanel.show();
const l = this.location.toJSON();
console.log('l', l);
if (l.hasOwnProperty('latitude')) {
detail.from.lat = l.latitude;
detail.from.long = l.longitude;
}
else
console.log('>> No location yet');
detail.to.lat = toDest.latitude;
detail.to.long = toDest.longitude;
console.log('detail', detail);
this.model.set('detail', detail);
// 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) {
this.model.clear({ 'silent':true });
console.log('close??');
},
'doRender': function() {
this.$el.empty();
// this.$el.html(this.template(this.model.get('article')));
this.$el.html(this.template());
const html = templates.templateDirections({ 'directions':this.model.get('directions') });
console.log(html);
const $el = this.$el;
$el.find('#gotoDetailsText').html(html);
},
'doUpdateRender': function() {
// this.$el.empty();
// this.$el.html(this.template(this.model.get('article')));
}
});
module.exports = { GotoCardModel, GotoCardView };

View File

@ -83,7 +83,7 @@ const GreetView = Backbone.View.extend({
place = place + locationName;
}
const html = `<div class="mui-panel greetPanel mui--text-center">
const html = `<div class="mui-panel mui--text-center">
<h2>${todaySegment}</h2>
<div>${icon} ${place}</div>
</div>`;

View File

@ -2,10 +2,10 @@ const _ = require('underscore');
const Backbone = require('backbone');
const geolocation = require('geolocation');
const TimeFormat = require('hh-mm-ss');
const request = require('request');
const { distance } = require('./libs/utils');
const NodeGeocoder = require('node-geocoder');
// const locationData = require('./portGlasgow-Aldi-2018-03-09.json');
const LocationModel = Backbone.Model.extend({
@ -13,7 +13,7 @@ const LocationModel = Backbone.Model.extend({
// defaults go here - "children" may be contained here
},
'tick': function () {
'tick': function() {
const p = locationData[this.pos];
const now = new Date();
@ -29,15 +29,9 @@ const LocationModel = Backbone.Model.extend({
p.time
);
},
'initialize': function () {
'initialize': function() {
// this.listenTo(this, 'change sync reset', this.onChange);
// https://opencagedata.com/dashboard
//
// API key
// 893ab539eca84b5ca7a54cb03ef23443
const geoOptions = {
'maximumAge': 5 * 60 * 1000,
'timeout': 10 * 1000
@ -45,179 +39,84 @@ const LocationModel = Backbone.Model.extend({
this.pos = 0;
this.moveTimer = 0;
this.throttler = 0;
geolocation.options = geoOptions;
geolocation.on('error', function (err) {
geolocation.on('error', function(err) {
console.warn('Geolocation error');
console.error(err);
});
const updateLocation = (position) => {
const latitude = Number.parseFloat(position.coords.latitude).toFixed(6);
const longitude = Number.parseFloat(position.coords.longitude).toFixed(6);
const location = { 'latitude': latitude, 'longitude': longitude, 'timestamp': position.timestamp };
console.log('*** Updating Loc', location);
this.processPosition(location);
};
const updateMotion = (position) => {
const latitude = Number.parseFloat(position.coords.latitude).toFixed(6);
const longitude = Number.parseFloat(position.coords.longitude).toFixed(6);
if (!this.has('motion')) {
const now = new Date();
const ts = now.getTime();
const motion = {
'cur': {
'lat': latitude,
'lon': longitude,
'speed': 0,
'ts' : ts
},
'prev': {
'lat': latitude,
'lon': longitude,
'speed': 0,
'ts' : ts
},
'speed': 0,
'distance' : 0
};
this.set('motion', motion);
}
else {
//
const motion = this.get('motion');
const now = new Date();
const ts = now.getTime();
motion.prev = Object.assign({}, motion.cur);
motion.cur.lat = latitude;
motion.cur.lon = longitude;
motion.cur.ts = ts;
const timeS = (ts - motion.prev.ts) / 1000.0;
const dist = distance(motion.prev.lat, motion.prev.lon, latitude, longitude);
const speedMps = dist / timeS;
const speedKph = (speedMps * 3600.0);
motion.cur.speed = Number.parseFloat(speedKph).toFixed(3);
motion.speed = Number.parseFloat(speedKph).toFixed(3);
motion.distance = Number.parseFloat(dist).toFixed(3);
console.log(motion);
this.set('motion', motion);
this.set('moving', (speedKph > 5.0));
}
};
const updatelocationthrottled = _.throttle(updateLocation, 120000);
const updateMotionhrottled = _.throttle(updateMotion, 15000);
geolocation.on('change', _.throttle(function (position) {
geolocation.on('change', function( position) {
console.log('Location update');
updatelocationthrottled(position);
updateMotionhrottled(position);
}.bind(this), 15000));
const location = { 'latitude': position.coords.latitude, 'longitude': position.coords.longitude, 'timestamp': position.timestamp };
this.processPosition(location);
// this.set('location', location);
}.bind(this));
this.watcher = geolocation.createWatcher();
this.listenTo(this, 'change:location', this.onChange);
// this.tick();
},
'onChange': function () {
'onChange': function() {
console.log('>> Location updated');
console.log(JSON.stringify(this.get('location')));
},
'processPosition': function (pos) {
'processPosition': function(pos) {
console.log('processPosition');
const { latitude, longitude, timestamp } = pos;
// const current = this.get('location');
const current = this.toJSON();
// console.log('># current', current);
const options = {
'provider': 'google',
const myCoords = {
'home': {
'lat': 51.490002, 'long': -0.140245
},
'work': {
'lat': 51.508471, 'long': -0.068798
}
// Optional depending on the providers
'httpAdapter': 'https', // Default
'apiKey': 'AIzaSyA7oGP6QS28tTwtT6UzA7hzh0b3MWwMYB8', // for Mapquest, OpenCage, Google Premier
'formatter': null // 'gpx', 'string', ...
};
// rawburn house 51.490002, -0.140245
// thomas more 51.5084707,-0.068798
// 55.872407, -3.549003
const homeDistance = distance(myCoords.home.lat, myCoords.home.long, latitude, longitude);
const workDistance = distance(myCoords.work.lat, myCoords.work.long, latitude, longitude);
const geocoder = NodeGeocoder(options);
//55.872407, -3.549003
const homeDistance = distance(55.942673, -4.556334, latitude, longitude);
const workDistance = distance(55.872407, -3.549003, latitude, longitude);
const atHome = (homeDistance < 0.10);
const atWork = (workDistance < 0.10);
const atHomeOrWork = (atHome || atWork);
const latlong = { 'lat': latitude, 'lon': longitude };
const latlong = { 'lat':latitude, 'lon':longitude };
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,
llShort,
moving,
latlong,
'city': '',
'cityCC': ''
};
const newLocation = { homeDistance, workDistance, latitude, longitude, atHome, atWork, atHomeOrWork, timestamp, ll, llFixed, llSix, llShort, moving, latlong, 'city' : '', 'cityCC':'' };
console.log('homeDistance', homeDistance, 'workDistance:', workDistance);
// console.log('>> NewLocation', JSON.stringify(newLocation));
// const distanceFromLast = distance(current.latitude, current.longitude, latitude, longitude);
if (!_.has(current, 'atHomeOrWork')) {
console.info('>> Location:geocoder request');
request({
'url': `${window.loc}/geocode`,
'method': 'GET',
'qs': {
'll': ll
},
'json': true
}, function(err, res, body) {
if (err)
geocoder.reverse(latlong)
.then(function(res) {
console.log(JSON.stringify(res));
newLocation.city = res[0].extra.neighborhood || res[0].city;
newLocation.cityCC = `${res[0].city},${res[0].countryCode}`;
newLocation.address = res[0].formattedAddress;
// 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);
else {
console.log('New geocode', res);
const body = res.body;
const __city = body.neighborhood || body.village || body.suburb || body.city || body.county;
newLocation.city = __city;
newLocation.cityCC = `${__city},${body.countryCode}`;
newLocation.address = body.formatted;
newLocation.lastGeocode = { 'lat': latitude, 'lng': longitude, 'timestamp': timestamp };
this.set(newLocation);
}
}.bind(this));
this.set('location', newLocation);
});
}
else {
newLocation.city = current.city;
@ -235,37 +134,34 @@ const LocationModel = Backbone.Model.extend({
// 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.80 && distanceFromLast < 2.0) && (currentSince > 120000)) || ((currentSince > 900000) && (sinceLastGeocode < 1.8e+6))) {
if (((distanceFromLast > 0.80 && distanceFromLast < 2.0) && ( currentSince > 120000)) || ((currentSince > 900000) && (sinceLastGeocode < 1.8e+6))) {
// dont bother re geocoding
console.log('Slightly moved from previous');
// this.set('location', newLocation);
// this.set('moving', moving);
this.set(newLocation);
this.set( newLocation);
}
else if (((distanceFromLastGeocode >= 2.0) && (sinceLastGeocode > 120000)) || (sinceLastGeocode >= 1.8e+6)) {
else if (((distanceFromLastGeocode >= 2.0) && (sinceLastGeocode > 120000)) || (sinceLastGeocode >= 1.8e+6) ) {
console.log('>> Moved from previous', sinceLastGeocode, (sinceLastGeocode >= 1.8e+6));
console.info('>> Location:geocoder request');
request({
'url': `${window.loc}/geocode`,
'method': 'GET',
'qs': {
'll': ll
},
'json': true
}, function(err, res, body) {
if (err)
geocoder.reverse(latlong)
.then(function(res) {
console.log('>> location res', JSON.stringify(res));
newLocation.city = res[0].extra.neighborhood || res[0].city;
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);
newLocation.lastGeocode = { 'lat':latitude, 'lng':longitude, 'timestamp':timestamp };
this.set( newLocation);
console.log(this);
}.bind(this))
.catch(function(err) {
console.error(err);
else {
console.log('New geocode', res);
const body = res.body;
const __city = body.neighborhood || body.village || body.suburb || body.city || body.county;
newLocation.city = __city;
newLocation.cityCC = `${__city},${body.countryCode}`;
newLocation.address = body.formatted;
newLocation.lastGeocode = { 'lat': latitude, 'lng': longitude, 'timestamp': timestamp };
this.set(newLocation);
}
}.bind(this));
this.set( newLocation);
});
}
}
@ -290,13 +186,13 @@ const LocationModel = Backbone.Model.extend({
});
const LocationView = Backbone.View.extend({
'initialize': function (options) {
'initialize' : function(options) {
this.model.bind('change', this.render, this);
}, 'template': _.template(`
<div class="">Moving:<%=moving%></div>
`),
'render': function () {
// this.$el.html(this.template(this.model.attributes));
'render': function() {
this.$el.html(this.template(this.model.attributes));
console.log('>> location attributes', this.model.attributes);

View File

@ -4,7 +4,7 @@ const Backbone = require('backbone');
const request = require('request');
const { get } = require('lodash');
const { reduceNearby } = require('./libs/reducers');
const { toHour, hourFloor } = require('./libs/utils');
const { toHour } = require('./libs/utils');
const TimeFormat = require('hh-mm-ss');
const { FSDetailView } = require('./Foursquare');
@ -24,7 +24,6 @@ const NearbyModel = Backbone.Model.extend({
this.tick();
this.set('totalResults', 0);
this.listenTo(this, 'change:llFixed change:atHome change:section change:update', this.onChange);
this.throttledGetNearby = _.throttle(this.getNearby, 6000);
},
'tick': function() {
const hour = parseInt((new Date()).getHours().toString(), 10);
@ -38,13 +37,12 @@ const NearbyModel = Backbone.Model.extend({
);
},
'onChange': function() {
console.log('>> Nearby:Changed: ', this);
if (this.get('atHome')) {
console.log('At home, so no fetching...');
this.logUpdate();
}
else
this.throttledGetNearby();
this.getNearby();
},
'getNearby': function() {
const llFixed = this.get('llFixed');
@ -56,25 +54,22 @@ const NearbyModel = Backbone.Model.extend({
const lastUpdate = time - (this.get('time') || 0);
console.log('>> Nearby section:', hour, section);
console.info('>> Nearby:request V2');
console.info('>> Nearby:request');
console.log(`>> Nearby last fetch: ${TimeFormat.fromMs(lastUpdate, 'hh:mm')} ago`);
if (lastUpdate > 120000) {
const url = new URL(`${window.loc}/fsexplore`);
url.searchParams.append('ll', llFixed);
url.searchParams.append('section', section);
url.searchParams.append('w', hourFloor());
fetch(url)
.then(res => {
if (lastUpdate > 120000)
request({
'url': `${window.loc}/fsexplore`,
'method': 'GET',
'qs': {
'll': llFixed,
'section': section
}
}, function(err, res, body) {
if (err)
console.error(err);
else {
console.log('statusCode', res.statusCode);
console.warn(res.status);
return res.text();
})
.then(function(body) {
const fsJSON = JSON.parse(body);
const groups = get(fsJSON, 'response.groups');
const items = groups[0].items;
@ -85,17 +80,14 @@ const NearbyModel = Backbone.Model.extend({
this.fsCollection.reset(newItems);
this.logUpdate();
}.bind(this))
.catch(function(error) {
console.error(error);
});
}
}.bind(this));
}, 'logUpdate': function() {
console.log('Nearby logging:');
const time = new Date().getTime() ;
this.set('time', time, { 'silent': true });
this.set('time', time);
}
});

View File

@ -1,6 +1,7 @@
const $ = require('jquery');
const _ = require('underscore');
const Backbone = require('backbone');
const request = require('request');
const { get } = require('lodash');
const { reduceNearby } = require('./libs/reducers');
const { createPanel, addPanel } = require('./libs/panel');
@ -19,24 +20,19 @@ const NearbyListModel = Backbone.Model.extend({
}, 'initialize': function() {
this.fsCollection = fsCollection;
this.listenTo(this, 'change:update', this.onChange);
this.listenTo(this, 'change:section change:query', this.onChangeSection);
this.listenTo(this, 'change:section', this.onChangeSection);
},
'onChange': function() {
console.log('NearbyList::onChange');
console.log(this);
this.getNearby();
},
'onChangeSection': function() {
console.log('NearbyList::onChangeSection');
console.log(this);
this.getNearby(true);
},
'getNearby': _.throttle(function(force = false) {
'getNearby': function(force = false) {
const llFixed = this.get('llFixed');
const hour = parseInt((new Date()).getHours().toString(), 10);
const section = this.get('section') || '';
const query = this.get('query') || '';
const section = this.get('section');
const limit = this.get('limit');
const time = new Date().getTime() ;
@ -44,49 +40,40 @@ const NearbyListModel = Backbone.Model.extend({
console.log('>> Nearby section:', hour, section);
console.info('>> Nearby:request');
console.log(`>> Nearby last fetch: ${lastUpdate} ago`);
console.log(`>> Nearby last fetch: ${TimeFormat.fromMs(lastUpdate, 'hh:mm')} ago`);
// this.fsCollection.reset( null, { 'silent':true });
if (lastUpdate > 120000 || force) {
const _url = new URL(`${window.loc}/fsexplore`);
_url.search = new URLSearchParams({
if (lastUpdate > 120000 || force)
request({
'url': `${window.loc}/fsexplore`,
'method': 'GET',
'qs': {
'll': llFixed,
'section': section,
'query':query,
'limit': limit
});
console.log(_url);
fetch(_url)
.then((res) => {
return res.json();
})
.then((fsJSON) => {
}
}, function(err, res, body) {
if (err)
console.error(err);
else {
console.log('statusCode', res.statusCode);
const fsJSON = JSON.parse(body);
const groups = get(fsJSON, 'response.groups');
const items = groups[0].items;
const newItems = [];
this.set('totalResults', get(fsJSON, 'response.totalResults'));
this.set('fullLocation', get(fsJSON, 'response.headerFullLocation'));
for(const item of items)
newItems.push(reduceNearby(item));
this.fsCollection.reset(newItems);
this.logUpdate();
})
.catch((e) => {
console.error(e);
});
}
}, 9000), 'logUpdate': function() {
}.bind(this));
}, 'logUpdate': function() {
console.log('NearyList logging:');
const time = new Date().getTime() ;
this.set('time', time, { 'silent': true });
this.set('time', time);
this.timerID = setTimeout(
() => this.tick(),
@ -124,7 +111,7 @@ const NearbyListView = Backbone.View.extend({
this.$el = addPanel(this.$newPanel);
// this.$el.empty();
//this.$el.empty();
this.$newPanel.show();
// console.log(this.model);
@ -139,15 +126,10 @@ const NearbyListView = Backbone.View.extend({
'click': 'doClick'
}, 'doClick': function(d) {
const self = this;
console.log('Do click', d);
const id = get(d, 'currentTarget.dataset.id', '');
console.log(id);
this.eventBus.trigger('showVenueDetail', id, () => {
console.log('News item panel closed');
self.$newPanel.show();
});
this.$newPanel.hide();
this.eventBus.trigger('showVenueDetail', id);
},
'render' : function() {
console.log('>> Do render');
@ -156,13 +138,6 @@ const NearbyListView = Backbone.View.extend({
const totalResults = this.model.get('totalResults');
console.log('>> totalResults', totalResults);
this.$el.empty();
const fullLocation = this.model.get('fullLocation');
console.log('nearby::fullLocation', fullLocation);
this.$el.append(`<div class="mui--text-subhead mui--text-accent">Near ${fullLocation}</div>`);
this.model.fsCollection.each(function(item) {
const fsView = new FSItemView({ 'model': item });
this.$el.append(fsView.el);

View File

@ -21,8 +21,7 @@ const FSItemView = Backbone.View.extend({
},
'attributes': function() {
return {
'data-section': this.model.get('section'),
'data-query': this.model.get('query')
'data-section': this.model.get('section')
};
},
@ -40,10 +39,7 @@ const NearbyPlacesView = Backbone.View.extend({
this.list = [
{ 'icon': 'https://ss3.4sqi.net/img/categories_v2/food/default_32.png', 'title':'Restaurants', 'section':'food' },
{ 'icon': 'https://ss3.4sqi.net/img/categories_v2/food/coffeeshop_32.png', 'title':'Cafes', 'section':'coffee' },
{ 'icon': 'https://ss3.4sqi.net/img/categories_v2/nightlife/default_32.png', 'title':'Bars', 'section':'drinks' },
{ 'icon': 'https://ss3.4sqi.net/img/categories_v2/food/diner_32.png', 'title':'Diner', 'query':'Diner' },
{ 'icon': 'https://ss3.4sqi.net/img/categories_v2/food/mexican_32.png', 'title':'Mexican Restaurant', 'query':'Mexican' },
{ 'icon': 'https://ss3.4sqi.net/img/categories_v2/food/deli_32.png', 'title':'Subways', 'query':'subway' }
{ 'icon': 'https://ss3.4sqi.net/img/categories_v2/nightlife/default_32.png', 'title':'Bars', 'section':'drinks' }
];
this.eventBus = options.eventBus;
this.location = options.location;
@ -92,12 +88,8 @@ const NearbyPlacesView = Backbone.View.extend({
console.log('Do click', d);
const section = get(d, 'currentTarget.dataset.section', '');
console.log(section);
const query = get(d, 'currentTarget.dataset.query', '');
console.log(section);
const llFixed = this.location.get('llFixed');
const data = { llFixed, section, query, 'limit':30 };
console.log('>> outgoing', data);
const data = { llFixed, section, 'limit':20 };
this.eventBus.trigger('showNearbyList', data);
}, 'atHome': function() {

View File

@ -5,7 +5,6 @@ const request = require('request');
const { get } = require('lodash');
const { reduceEuronews } = require('./libs/reducers');
const TimeFormat = require('hh-mm-ss');
const { hourFloor } = require('./libs/utils');
const NewsItem = Backbone.Model.extend({
@ -52,21 +51,18 @@ const NewsModel = Backbone.Model.extend({
}, 'initialize': function() {
this.newsCollection = newsCollection;
this.listenTo(this, 'change:update', this.onChange);
this.getNews = _.throttle(this.getNewsReal, 6000);
this.getNews();
},
'onChange': function() {
this.getNews();
},
'getNewsReal': function() {
'getNews': function() {
// const ll = this.get('llShort');
console.info('>> News:getNewsReal');
console.info('>> News:request');
request({
'url': `${window.loc}/news`,
'method': 'GET', 'qs': {
'limit': 10,
'w' : hourFloor()
'limit': 10
}
}, function(err, res, body) {
if (err)
@ -90,7 +86,7 @@ const NewsModel = Backbone.Model.extend({
const time = new Date().getTime() ;
this.set('time', time, {silent: true});
this.set('time', time);
this.timerID = setTimeout(
() => this.tick(),
@ -155,7 +151,7 @@ const NewsView = Backbone.View.extend({
'click .scrollCard': 'doClick'
}, 'doClick': function(d) {
// console.log('Do click', d);
console.log('Do click', d);
const id = get(d, 'currentTarget.dataset.guid', '');
console.log(id);
this.eventBus.trigger('showNews', id);
@ -170,7 +166,7 @@ const NewsView = Backbone.View.extend({
this.model.set('update', now);
},
'doMoreNews': function() {
// console.log('doMoreNews', this);
console.log('doMoreNews', this);
this.eventBus.trigger('showNewsList');
}

View File

@ -5,7 +5,6 @@ const request = require('request');
const { get } = require('lodash');
const { reduceEuronews } = require('./libs/reducers');
const { createPanel, addPanel } = require('./libs/panel');
const { hourFloor } = require('./libs/utils');
const NewsItem = Backbone.Model.extend({
@ -57,12 +56,11 @@ const NewsListModel = Backbone.Model.extend({
this.getNews();
},
'getNews': function() {
console.info('>> NewsList:getNews');
console.info('>> News:request');
request({
'url': `${window.loc}/news`,
'method': 'GET', 'qs': {
'w' : hourFloor()
}
}, function(err, res, body) {
if (err)
@ -86,7 +84,7 @@ const NewsListModel = Backbone.Model.extend({
const time = new Date().getTime() ;
this.set('time', time, {silent: true});
this.set('time', time);
this.timerID = setTimeout(
() => this.tick(),
@ -123,15 +121,10 @@ const NewsListView = Backbone.View.extend({
'click': 'doClick'
}, 'doClick': function(d) {
// console.log('Do click', d);
const self = this;
console.log('Do click', d);
const id = get(d, 'currentTarget.dataset.guid', '');
console.log(id);
this.eventBus.trigger('showNews', id, () => {
console.log('News item panel closed');
this.$newPanel.show();
});
this.$newPanel.hide();
this.eventBus.trigger('showNews', id);
},
'render' : function() {
console.log('>> Do render');

View File

@ -4,7 +4,6 @@ const Backbone = require('backbone');
const request = require('request');
const { get, isEmpty } = require('lodash');
const { createPanel, addPanel } = require('./libs/panel');
const { hourFloor } = require('./libs/utils');
const NewsCardModel = Backbone.Model.extend({
'initialize': function() {
@ -20,8 +19,7 @@ const NewsCardModel = Backbone.Model.extend({
'url': `${window.loc}/article`,
'method': 'GET',
'qs': {
'guid': guid,
'w' : hourFloor()
'guid': guid
}
}, function(err, res, body) {
console.log('statusCode', res.statusCode);
@ -54,20 +52,20 @@ const NewsCardView = Backbone.View.extend({
'template': _.template(`
<div class="newsarticle">
<div style="text-align: center;"><img src="<%= image %>"></div>
<div><img src="<%= image %>"></div>
<div class="mui-container" style="margin-bottom: 50px;">
<div><h1><%= title %></h1></div>
<div><%= html %></div>
</div>
</div>
`),
'showNewsPanel': function(guid, cb = null) {
'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' }, cb);
this.$newPanel = createPanel({ 'title':'News', 'divId':'newsP' });
this.$el = addPanel(this.$newPanel);

View File

@ -3,7 +3,7 @@ const _ = require('underscore');
const Backbone = require('backbone');
const request = require('request');
const { get, isEmpty } = require('lodash');
const { maybePluralize, hourFloor } = require('./libs/utils');
const { maybePluralize } = require('./libs/utils');
const templates = require('./libs/templates');
const ByMeModel = Backbone.Model.extend({

View File

@ -24,25 +24,24 @@ const TrafficModel = Backbone.Model.extend({
'tick': function() {
const hour = (new Date()).getHours();
const day = new Date().getDay();
console.log('>> day', day);
let doRequest = false;
if (day !== 0 && day !== 6)
doRequest = (((hour >= 7) && (hour <= 9)) || ((hour >= 17) && (hour <= 19)));
// doRequest = true;
const delay = doRequest ? 600000 : toHour();
if (this.has('latlong') && doRequest) {
// ( ((hour >= 7) && (hour <= 9)) || ((hour >= 17) && (hour <= 19)) )
//
console.log('this.has(\'latlong\')', this.has('latlong'));
if (this.has('latlong')) {
this.updateID = 1;
this.getTraffic();
}
else
this.set('mode', 0);
console.log('doRequest', doRequest);
const day = new Date().getDay();
console.log('tick', this.attributes);
console.log('((hour >= 7) && (hour <= 9))', ((hour >= 7) && (hour <= 9)));
console.log('((hour >= 17) && (hour <= 19))', ((hour >= 17) && (hour <= 19)));
let delay;
if (day === 0 || day === 6)
delay = toHour();
else
delay = ( ((hour >= 7) && (hour <= 9)) || ((hour >= 17) && (hour <= 19)) ) ? 600000 : toHour();
console.log('Delay', delay);
this.timerID = setTimeout(
() => this.tick(),
@ -53,9 +52,8 @@ const TrafficModel = Backbone.Model.extend({
this.getTraffic();
},
'getTraffic': function() {
console.log('Get Traffic');
console.log('Get Raffic');
// olat, olon, dlat, dlon
const override = false;
const time = new Date().getTime() ;
const hour = (new Date()).getHours();
const latlong = this.get('latlong');
@ -65,13 +63,6 @@ const TrafficModel = Backbone.Model.extend({
if (!this.has('latlong'))
return;
const myCoords = { 'home': {
'lat':51.490002, 'long':-0.140245
},
'work':{
'lat':51.5084707, 'long':-0.068798
} };
// 55.872407, -3.549003
// const latlong = { 'lat':latitude, 'lon':longitude };
@ -79,14 +70,14 @@ const TrafficModel = Backbone.Model.extend({
this.set('dest', 'Work');
mode = 1;
qs = {
'olat': latlong.lat, 'olon': latlong.lon, 'dlat': myCoords.work.lat, 'dlon': myCoords.work.long
'olat': latlong.lat, 'olon': latlong.lon, 'dlat': 55.872407, 'dlon': -3.549003
};
}
else if (((hour >= 17) && (hour <= 19)) || override) {
else if ((hour >= 17) && (hour <= 19)) {
mode = 1;
this.set('dest', 'Home');
qs = {
'olat': latlong.lat, 'olon': latlong.lon, 'dlat': myCoords.home.lat, 'dlon': myCoords.home.long
'olat': latlong.lat, 'olon': latlong.lon, 'dlat': 55.942673, 'dlon': -4.556334
};
}
const lastUpdate = time - (this.get('time') || 0);
@ -118,7 +109,7 @@ const TrafficModel = Backbone.Model.extend({
const time = new Date().getTime() ;
this.set('time', time, {silent: true});
this.set('time', time);
}
});
@ -150,8 +141,8 @@ const TrafficView = Backbone.View.extend({
},
'template': _.template(`
<div class="">
<div class="itemRow mui--align-middle"><i class=" fa <%= "fa-" + dest.toLowerCase() %> fa-2x mui--align-middle <%= className %>"></i> <%=readable%> to <%= dest.toLowerCase() %> <span class="<%= className %>"><%=traffic %></span></div>
<div><i class="small fa <%= "fa-" + dest.toLowerCase() %> mui--align-middle "></i> <%=readable%> to <%= dest.toLowerCase() %></div>
<div class="<%= className %>"><%=traffic %></div>
</div>
`),
@ -189,14 +180,15 @@ const parts = new Map(
['9', 'left_turn'],
['13', 'right_turn'],
['11', 'continue'],
['23', 'right_fork'],
['17', 'left_exit'],
['23','right_fork'],
['17','left_exit'],
['19', 'left_ramp'],
['29', 'turn'],
['', '']
['','']
]
);
module.exports = { TrafficModel, TrafficView };

View File

@ -47,16 +47,16 @@ const VenueDetailView = Backbone.View.extend({
this.location = options.location;
this.model.bind('change:details', this.doRender, this);
this.eventBus.on('showVenueDetail', this.showVenuePanel, this);
this.eventBus.on('showVenueDetail', this.showNewsPanel, this);
},
'showVenuePanel': function(id, cb = null) {
'showNewsPanel': function(id) {
console.log('Showing venue details', id);
const prevId = this.model.get('id');
this.model.set('id', id);
this.$newPanel = createPanel({ 'title':'Venue details', 'divId':'VenueDetail' }, cb);
this.$newPanel = createPanel({ 'title':'Venue details', 'divId':'VenueDetail' });
this.$el = addPanel(this.$newPanel);
@ -67,10 +67,7 @@ const VenueDetailView = Backbone.View.extend({
this.doRender();
},
'events': {
'click .closebutton': 'doClick',
'click #getDirections': (d) => {
console.log('Clicked', d);
}
'click .closebutton': 'doClick'
},
'doClick': function(d) {
console.log('Do click', d);
@ -78,17 +75,6 @@ const VenueDetailView = Backbone.View.extend({
console.log(id);
// this.eventBus.trigger('showNews', id);
},
'doNavigate': function(d) {
// console.log('Do click', d);
console.log('>> this.model', this);
const details = this.model.get('details');
console.log(details);
this.eventBus.trigger('showDirections', details, () => {
console.log('Navigate panel closed');
this.$newPanel.show();
});
this.$newPanel.hide();
},
'doClose': function(d) {
console.log('close??');
},
@ -102,12 +88,11 @@ const VenueDetailView = Backbone.View.extend({
const $map = $('#map');
if (!isEmpty(m.images))
contents.push(templates.imagesTemplate(m));
contents.push(templates.map());
contents.push(templates.venueDirections(m));
contents.push(templates.venueDescription(m));
if (!isEmpty(m.yelp))
contents.push(templates.yelpTemplate(m));
@ -117,9 +102,6 @@ const VenueDetailView = Backbone.View.extend({
if (!isEmpty(m.tweets))
contents.push(templates.tweetsTemplate(m));
if (!isEmpty(m.images))
contents.push(templates.imagesTemplate(m));
contents.push(templates.openInFS(m));
this.$el.empty();
this.$el.html(contents.join(''));
@ -130,43 +112,21 @@ const VenueDetailView = Backbone.View.extend({
'zoom': 15
});
// L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
'attribution': 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>',
'maxZoom': 18,
'id': 'mapbox.streets',
'accessToken': 'pk.eyJ1IjoibWFydGluZDIwMDAiLCJhIjoiY2pmNnlnc3F1MGpoYzJ5bXpscGFwaTlueiJ9.sx1ToptfsUf5HF3-0VVC-Q'
}).addTo(this.map);
const mePoints = this.location.get('ll').split(',');
const dest = new L.LatLng(m.latitude, m.longitude);
const me = new L.LatLng(mePoints[0], mePoints[1]);
const pointList = [dest, me];
const firstpolyline = new L.Polyline(pointList, {
'color': 'red',
'weight': 3,
'opacity': 0.5,
'smoothFactor': 1
});
firstpolyline.addTo(this.map);
L.marker(dest).addTo(this.map);
/* var circle =*/
L.circle(me, {
/* const marker =*/ L.marker([m.latitude, m.longitude]).addTo(this.map);
/* var circle =*/ L.circle(this.location.get('ll').split(','), {
'color': 'blue',
'fillColor': '#00a6ff',
'fillOpacity': 0.5,
'opacity': 0.5,
'radius': 30
'radius': 10
}).addTo(this.map);
this.$el.find('#getDirections').on('click', () => {
this.doNavigate();
});
// console.log(this.location.attributes);
}

View File

@ -4,7 +4,7 @@ const Backbone = require('backbone');
const request = require('request');
const { get } = require('lodash');
const { reduceOpenWeather } = require('./libs/reducers');
const { distance, hourFloor } = require('./libs/utils');
const { distance } = require('./libs/utils');
const TimeFormat = require('hh-mm-ss');
const weatherItem = Backbone.Model.extend({
@ -82,7 +82,7 @@ const WeatherModel = Backbone.Model.extend({
else {
const log = this.get('log');
const timeDiff = new Date().getTime() - log.time;
// console.log('this', this);
console.log('this', this);
const dist = distance(log.lat, log.long, this.get('latitude'), this.get('longitude'));
console.log('Weather distance:', dist);
@ -102,8 +102,7 @@ const WeatherModel = Backbone.Model.extend({
'url': `${window.loc}/weather`,
'method': 'GET',
'qs': {
'll': llFixed,
'w' : hourFloor()
'll': llFixed
}
}, function(err, res, body) {
console.log('statusCode', res.statusCode);
@ -124,12 +123,12 @@ const WeatherModel = Backbone.Model.extend({
}
}.bind(this));
},
'logUpdate': function () {
'logUpdate': function() {
console.log('Weather logging:');
const log = { 'lat': this.get('latitude'), 'long': this.get('longitude'), 'time': new Date().getTime() };
const log = { 'lat' : this.get('latitude'), 'long': this.get('longitude'), 'time': new Date().getTime() };
this.set('log', log, { 'silent': true });
this.set('log', log);
this.timerID = setTimeout(
() => this.tick(),

View File

@ -6,7 +6,7 @@ const fecha = require('fecha');
const TimeFormat = require('hh-mm-ss');
const { get } = require('lodash');
const { reduceOpenWeather } = require('./libs/reducers');
const { distance, toHour, hourFloor } = require('./libs/utils');
const { distance, toHour } = require('./libs/utils');
const WeatherAlertModel = Backbone.Model.extend({
'defaults': function (obj) {
@ -62,8 +62,7 @@ const WeatherAlertModel = Backbone.Model.extend({
'url': `${window.loc}/weatheralert`,
'method': 'GET',
'qs': {
'll': llFixed,
'w' : hourFloor()
'll': llFixed
}
}, function (err, res, body) {
console.log('statusCode', res.statusCode);
@ -97,7 +96,7 @@ const WeatherAlertModel = Backbone.Model.extend({
toHour(1000)
);
console.log('>>WeatherAlert log', log);
this.set('log', log, { 'silent': true });
this.set('log', log);
// console.log(this);
},
'tick': function () {
@ -119,7 +118,7 @@ const WeatherAlertView = Backbone.View.extend({
this.$title = $('#weatherAlertTitle');
// this.model.bind('change', this.render, this);
this.location.bind('change:llFixed', this.updateLocation, this);
this.location.bind('change:llShort', this.updateLocation, this);
this.model.bind('change:alert', this.render, this);
this.eventBus.on('focused', this.focused, this);
},
@ -144,8 +143,8 @@ const WeatherAlertView = Backbone.View.extend({
console.log('changedAttributes:', this.location.changedAttributes());
if (l.has('atHome')) {
const llFixed = l.get('llFixed');
this.model.set('ll', llFixed);
const llShort = l.get('llShort');
this.model.set('ll', llShort);
}
else
console.log('>> Weather No location yet');

View File

@ -19,56 +19,25 @@ const { AgendaModel, AgendaView } = require('./Agenda');
const { TrafficModel, TrafficView } = require('./Traffic');
const { NearbyListModel, NearbyListView } = require('./NearbyList');
const { NearbyPlacesView } = require('./NearbyPlaces');
const { GotoCardModel, GotoCardView } = require('./Goto');
var app = app || {};
const live = true;
const live = false;
if (live) {
const url = new URL(window.location.origin);
console.log('url', url);
window.loc = url.origin;
if ('serviceWorker' in navigator) {
//
navigator.serviceWorker.ready.then(function(reg) {
console.warn('Ready??', reg);
main();
});
window.addEventListener('load', function() {
window.loc = 'https://jubilee.silvrtree.co.uk';
if ('serviceWorker' in navigator)
navigator.serviceWorker
.register('./service-worker.js')
.then(function(r) {
console.warn('Service Worker Registered', r.scope);
})
.catch(function(error) {
// registration failed
console.error(`Registration failed with ${ error}`);
.then(function() {
console.log('Service Worker Registered');
});
});
//
}
}
else {
console.log('window.location', window.location.origin);
else
window.loc = 'http://localhost:8110';
const url = new URL(window.location.origin);
console.log('url', url);
window.loc = url.origin;
main();
}
function main() {
(function () {
const offline = false;
console.log('>>> START!!! <<<');
/* var myRouter = Backbone.Router.extend({
//
@ -104,23 +73,23 @@ function main() {
app.traffic = new TrafficView({ 'model': new TrafficModel(), 'eventBus': app.eventBus, 'location': app.locationModel, 'el':'#traffic' });
app.venueCard = new VenueDetailView({ 'model': new VenueDetailModel(), 'eventBus': app.eventBus, 'location': app.locationModel });
app.newsCard = new VenueDetailView({ 'model': new VenueDetailModel(), 'eventBus': app.eventBus, 'location': app.locationModel });
app.nearbyList = new NearbyListView({ 'model': new NearbyListModel(), 'eventBus' : app.eventBus });
app.nearbyPlacesView = new NearbyPlacesView({ 'eventBus': app.eventBus, 'location': app.locationModel, 'el':'#nearbyPlaces' });
app.gotoCard = new GotoCardView({ 'model': new GotoCardModel(), 'eventBus': app.eventBus, 'location': app.locationModel });
app.updateOnlineStatus = function(event) {
if (navigator.onLine) {
if (navigator.onLine)
// handle online status
{
console.log('online');
$('#connectionStatus').hide(500);
}
else {
else
// handle offline status
{
console.log('offline');
$('#connectionStatus').show(500);
}
@ -133,4 +102,4 @@ function main() {
window.addEventListener('online', app.updateOnlineStatus);
window.addEventListener('offline', app.updateOnlineStatus);
}
})();

View File

@ -1,16 +0,0 @@
const EventEmitter = require('events');
const jsonfile = require('jsonfile');
class DummyLocation extends EventEmitter {
constructor(options = {}) {
this.options = Object.assign({}, options);
console.log('options', this.options);
if (typeof this.options.file !== 'undefined' && this.options.file !== null)
this.file = jsonfile.reaFileSync(this.options.file);
}
}
module.exports = DummyLocation;

View File

@ -15,7 +15,7 @@ const FSItemView = Backbone.View.extend({
'tagName': 'div',
'className': 'itemRow mui--align-middle',
'template': _.template(`
<img class='mui--align-middle' src="<%= icon %>" width="32px" height="32px" style="-webkit-filter: invert(100%);"/><span class="mui--text-dark mui--text-subhead"><%= name %></span> <span class="mui--text-caption mui--text-dark-secondary">(<%= distance %>km)</span> <span class="mui--text-caption mui--text-dark-secondary"><%= category %></span> `),
<img class='mui--align-middle' src="<%= icon %>" width="32px" height="32px" style="-webkit-filter: invert(100%);"/><span class="mui--text-dark mui--text-subhead"><%= name %></span> <span class="mui--text-caption mui--text-dark-secondary"><%= category %></span> `),
'initialize': function() {
this.render();
},

View File

@ -1,7 +1,7 @@
const $ = require('jquery');
let panelCount = 0;
function createPanel(params, cb = null) {
function createPanel(params) {
const { title, divId } = params;
const newPanel = `
<div class="appPanel" data-id="${divId}">
@ -52,25 +52,18 @@ function createPanel(params, cb = null) {
$newPanel.hide().remove();
console.log('panelCount', panelCount);
panelCount--;
if (panelCount === 0) {
if (panelCount === 0)
console.log('Removing panel stuff');
$body.removeClass('stop-scrolling').unbind('touchmove');
}
if (cb !== null) {
console.log('trying close cb');
cb();
}
}
return $newPanel;
}
function addPanel($newPanel) {
const $body = $('body');
const $content = $newPanel.find('.content');
// $body.append($newPanel);
$body.prepend($newPanel);
$body.append($newPanel);
if (panelCount === 0) {
$body.addClass('stop-scrolling');
$body.bind('touchmove', function(e) {
@ -79,6 +72,7 @@ function addPanel($newPanel) {
}
panelCount++;
return $content;
}

View File

@ -90,8 +90,6 @@ const reduceNearby = function(item) {
obj.category = get(categories[0], 'name', '');
obj.icon = `${get(categories[0], 'icon.prefix', '')}32${get(categories[0], 'icon.suffix', '')}`;
obj.distance = (get(item, 'venue.location.distance', 0) / 1000).toFixed(2);
return obj;
};
@ -102,14 +100,9 @@ const reduceEuronews = function(item) {
obj.pubdate = fecha.format(pubdateSrc, 'dddd MMMM Do, YYYY HH:mm');
obj.description = item.description.replace(/(<script(\s|\S)*?<\/script>)|(<style(\s|\S)*?<\/style>)|(<!--(\s|\S)*?-->)|(<\/?(\s|\S)*?>)/g, '');
if (obj.description === '1')
obj.description = '';
obj.guid = encodeURI(item.guid.text);
obj.title = item.title;
console.log(obj);
return obj;
};

View File

@ -11,7 +11,7 @@ const templates = {
<%= yelp.reviewCount %> review
</div>
<div class="mui-col-md-4 mui-col-xs-4 mui--text-right">
<a href="<%=yelp.viewIntent %>"><img src="gfx/yssdk_yelp_logo.png"></a>
<img src="gfx/yssdk_yelp_logo.png">
</div>
</div>
`),
@ -19,11 +19,11 @@ const templates = {
<div id='bymeTips'>
<div class="mui-row">
<div class="mui-col-xs-10 mui--text-body2">Tips</div>
<div class="mui-col-xs-1" style="font-family:fujicons;"><a href="<%=url %>"></a></div>
<div class="mui-col-xs-1" style="font-family:fujicons;"></div>
</div>
<div class='scrolling-wrapper-flexbox' style="height: 200px;">
<div class='scrolling-wrapper-flexbox' style="height: 100px;">
<%_.forEach(tips, function(i) {%>
<div class="scrollCard mui--text-body1">
<div class="scrollCardHalf mui--text-body1">
<%=i %>
</div>
<%}) %>
@ -47,120 +47,22 @@ const templates = {
<div class="mui-col-xs-10 mui--text-body2">Tweets</div>
<div class="mui-col-xs-1" style="font-family:fujicons;"></div>
</div>
<div class='scrolling-wrapper-flexbox' style="height: 200px;">
<div class='scrolling-wrapper-flexbox' style="height: 100px;">
<%_.forEach(tweets, function(i) {%>
<div class="scrollCard mui--text-body1">
<div class="scrollCardHalf mui--text-body1">
<%=i %>
</div>
<%}) %>
</div>
</div>
`),
'venueTitle': _.template(`
'venueTitle' : _.template(`
<div class="mui--text-display1 mui--text-center" style="font-weight: 900;"><%=name %></div>
`),
'venueDescription': _.template(`
<div class="mui--text-body1" ><%=description %></div>
'openInFS' : _.template(`
<div class=""><a href="https://m.foursquare.com/v/<%=id%>">Open in Foursquare</a></div>
`),
'venueDirections': _.template(`
<div class="mui--text-subhead mui--text-center separate" style="" id="getDirections"><p><i class="fa fa-sm fa-map-marker mui--align-middle " ></i><%=address%></p><p>Directions</p></div>
`),
'openInFS': _.template(`
<div style="margin-bottom:50px"><a href="<%=url%>">Open in Foursquare</a></div>
`),
'map': _.template('<div id="map"></div>'),
'templateCurrently': _.template(`
<div class="forecastCurrently mui-panel glassy">
<div class="mui--text-title"><i class="medium wi wi-forecast-io-<%= icon %>"></i> <%=summary%></div>
<div>
<i class="small fa fa-up mui--align-middle " ></i><%=tempMax%>°
<i class="small fa fa-down mui--align-middle " ></i><%=tempMin%>°
</div>
<div class="large temp<%=~~(temperature) %>"><%=temperature%>°</div>
</div>
`),
'templateForecast': _.template(`
<div class="forecastToday mui-panel glassy">
<h3>Forecast</h3>
<div class='scrolling-wrapper-flexbox hourly' style="height: 100px;">
<%_.forEach(today, function(i) {%>
<div class="hourlyCard">
<div class="mui--text-center"><%=i.time %></div>
<div class="mui--text-center"><i class="small wi wi-forecast-io-<%= i.icon %>"></i></div>
<div class="mui--text-center temp<%=~~(i.temp)%> normalWeight"><%=~~(i.temp)%>°</div>
</div>
<%}) %>
</div>
<div>
<div class="dailyCard">
<%_.forEach(daily, function(i) {%>
<div class="mui-row">
<div class="mui-col-xs-6 mui--text-left mui--text-title"><%=i.time %></div>
<div class="mui-col-xs-2 mui--text-center"><i class="mui--text-title wi wi-forecast-io-<%= i.icon %>"></i></div>
<div class="mui-col-xs-2 mui--text-center temp<%=~~(i.tempHigh) %> mui--text-title "><%=~~(i.tempHigh)%>°</div>
<div class="mui-col-xs-2 mui--text-center temp<%=~~(i.tempLow) %> mui--text-title"><%=~~(i.tempLow)%>°</div>
</div>
<%}) %>
</div>
</div>
</div>
`),
'templateDetails': _.template(`
<div class="forecastDetails mui-panel glassy">
<h3>Details</h3>
<div class="mui-row">
<div class="mui-col-xs-6 mui--text-left mui--text-body2">Humidity</div>
<div class="mui-col-xs-6 mui--text-right mui--text-title"><%=~~(humidity * 100) %>%</div>
</div>
<div class="mui-row">
<div class="mui-col-xs-6 mui--text-left mui--text-body2">Visibility</div>
<div class="mui-col-xs-6 mui--text-right mui--text-title"><%=visibility %><span class="mui--text-body1">km</span></div>
</div>
<div class="mui-row">
<div class="mui-col-xs-6 mui--text-left mui--text-body2">UV Index</div>
<div class="mui-col-xs-6 mui--text-right mui--text-title"><%=uvIndex %></div>
</div>
<div class="mui-row">
<div class="mui-col-xs-12 mui--text-left mui--text-body1"><%=summary%></div>
</div>
<h3>Wind & Pressure</h3>
<div class="mui-row">
<div class="mui-col-xs-6 mui-col-md-3 mui--text-left mui--text-body2">Wind</div>
<div class="mui-col-xs-6 mui-col-md-3 mui--text-right mui--text-title"><%=windSpeed %><span class="mui--text-body1">km/h</span></div>
<div class="mui-col-xs-6 mui-col-md-3 mui--text-left mui--text-body2">Barometer</div>
<div class="mui-col-xs-6 mui-col-md-3 mui--text-right mui--text-title"><%=pressure %><span class="mui--text-body1">mBar</span></div>
</div>
<h3>Sun & Moon</h3>
<div class="mui-row">
<div class="mui-col-xs-3 mui--text-left mui--text-body2">Sunrise</div>
<div class="mui-col-xs-3 mui--text-right mui--text-title"><%=sunriseTime %></div>
<div class="mui-col-xs-3 mui--text-left mui--text-body2">Sunset</div>
<div class="mui-col-xs-3 mui--text-right mui--text-title"><%=sunsetTime %></div>
</div>
<div class="mui-row">
<div class="mui-col-xs-12 mui--text-right mui--text-title"><%=moonphase %></div>
</div>
</div>
`),
'templateDirections': _.template(`
<%_.forEach(directions, function(i) {%>
<div class="itemRow mui--align-middle">
<span class="mui--text-dark mui--text-subhead"><%=i %></span>
</div>
<%}) %>
`)
'map': _.template('<div id="map"></div>')
};
module.exports = templates;
/*
<div data-id="4b926c3af964a52068f833e3" class="itemRow mui--align-middle">
<img class="mui--align-middle" src="https://ss3.4sqi.net/img/categories_v2/nightlife/pub_32.png" width="32px" height="32px" style="-webkit-filter: invert(100%);">
<span class="mui--text-dark mui--text-subhead">The Mayflower</span> <span class="mui--text-caption mui--text-dark-secondary">Pub</span> </div>
*/

View File

@ -48,12 +48,6 @@ function toHour(extra = 0) {
return (3600000 - (now.getTime() % 3600000)) + extra;
}
function hourFloor() {
const now = new Date();
return parseInt(~~(now.getTime() / 3600000) * 3600000, 10).toString(32);
}
function distance(lat1, lon1, lat2, lon2) {
const p = 0.017453292519943295; // Math.PI / 180
const c = Math.cos;
@ -71,5 +65,5 @@ function splitURL(url) {
const maybePluralize = (count, noun, suffix = 's') =>
`${count} ${noun}${count !== 1 ? suffix : ''}`;
module.exports = { partOfDay, toHour, hourFloor, distance, maybePluralize };
module.exports = { partOfDay, toHour, distance, maybePluralize };

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More