From 5aa8230c0dd0a09ca80136773f521489f75039c6 Mon Sep 17 00:00:00 2001 From: Scott Lederer Date: Mon, 14 Aug 2017 11:04:29 -0400 Subject: [PATCH 01/10] Show toggle arrows on to/within button. Resolves #862 --- .../styles/components/_directions-form.scss | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/app/styles/components/_directions-form.scss b/src/app/styles/components/_directions-form.scss index 611265890..44299bbcb 100644 --- a/src/app/styles/components/_directions-form.scss +++ b/src/app/styles/components/_directions-form.scss @@ -260,16 +260,23 @@ &.directions-tab-button label { position: relative; + padding-right: 2rem; background-color: $gophillygo-blue-dark; cursor: pointer; - } - - &.directions-to label { - padding-right: .5rem; - } - &.isochrone-control label { - padding-right: 1rem; + &:after { + position: absolute; + right: 4px; + width: 20px; + margin: 0; + padding: 0; + color: inherit; + font-family: gpg; + font-size: .7em; + line-height: 30px; + text-align: right; + content: '\e813'; + } } } From fdaf8c96be8f6964b127ccbf28de95ca1292b94e Mon Sep 17 00:00:00 2001 From: Scott Lederer Date: Mon, 14 Aug 2017 11:51:23 -0400 Subject: [PATCH 02/10] Normalize case of infowindow action links --- src/app/scripts/cac/map/cac-map-templates.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/scripts/cac/map/cac-map-templates.js b/src/app/scripts/cac/map/cac-map-templates.js index 6f73832c7..e03ee6c90 100644 --- a/src/app/scripts/cac/map/cac-map-templates.js +++ b/src/app/scripts/cac/map/cac-map-templates.js @@ -184,7 +184,7 @@ CAC.Map.Templates = (function (Handlebars, moment, Utils) { // .back and .getdirections are used to select these elements for the click event '', '', + 'Get directions', '', '', '' From a9ddd5fd0fc093e8b63b3ce03dc48ff3e94008f1 Mon Sep 17 00:00:00 2001 From: Kathryn Killebrew Date: Fri, 18 Aug 2017 15:41:10 +0200 Subject: [PATCH 03/10] Change breakpoint for to/within toggle Closes #874. Use narrower breakpoint for detecting mobile for the to/within and current location display. --- src/app/scripts/cac/pages/cac-pages-home.js | 6 +++--- src/app/styles/utils/_breakpoints.scss | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/scripts/cac/pages/cac-pages-home.js b/src/app/scripts/cac/pages/cac-pages-home.js index 59b9b5e8e..10d171ee6 100644 --- a/src/app/scripts/cac/pages/cac-pages-home.js +++ b/src/app/scripts/cac/pages/cac-pages-home.js @@ -3,7 +3,7 @@ CAC.Pages.Home = (function ($, ModeOptions, MapControl, TripOptions, SearchPara 'use strict'; // this needs to match the value in styles/utils/_breakpoints.scss - var MD_UP_BREAKPOINT = 992; + var XXS_BREAKPOINT = 480; var defaults = { selectors: { @@ -60,7 +60,7 @@ CAC.Pages.Home = (function ($, ModeOptions, MapControl, TripOptions, SearchPara mapControl = new MapControl({ tabControl: tabControl, - isMobile: $(window).width() < MD_UP_BREAKPOINT + isMobile: $(window).width() < XXS_BREAKPOINT }); modeOptionsControl = new ModeOptions(); @@ -168,7 +168,7 @@ CAC.Pages.Home = (function ($, ModeOptions, MapControl, TripOptions, SearchPara // only allow explore mode on desktop and only respond to label in map view if (tabControl.isTabShowing(tabControl.TABS.HOME) || - $(window).width() < MD_UP_BREAKPOINT) { + $(window).width() < XXS_BREAKPOINT) { return; } diff --git a/src/app/styles/utils/_breakpoints.scss b/src/app/styles/utils/_breakpoints.scss index fb8bd216f..e612fb0a9 100644 --- a/src/app/styles/utils/_breakpoints.scss +++ b/src/app/styles/utils/_breakpoints.scss @@ -3,6 +3,7 @@ $breakpoints: ( // 'xxs' must match defaults.slick.responsive.breakpoint in cac-control-itinerary-list.js 'xxs': (max-width: 480px), + // NB: if xxs breakpoint changes, must also update cac-pages-home.js XXS_BREAKPOINT 'xxs-up': (min-width: 481px), 'xs': (max-width: 767px), @@ -12,7 +13,6 @@ $breakpoints: ( 'sm-down': (max-width: 991px), 'md': "(min-width: 992px) and (max-width: 1200px)", - // NB: if md-up breakpoint changes, must also update cac-pages-home.js MD_UP_BREAKPOINT 'md-up': (min-width: 992px), 'md-down': (max-width: 1200px), From e02cfcaceda10a81248f8fd8f345b6b413599a89 Mon Sep 17 00:00:00 2001 From: Kathryn Killebrew Date: Wed, 6 Sep 2017 13:27:56 +0200 Subject: [PATCH 04/10] Update python dependencies Note Django version must stay at 1.8 for wpadmin. --- .../cac-tripplanner.app/defaults/main.yml | 20 +++++++++---------- .../tasks/dev-test-dependencies.yml | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/deployment/ansible/roles/cac-tripplanner.app/defaults/main.yml b/deployment/ansible/roles/cac-tripplanner.app/defaults/main.yml index 2d5fd7556..fd71bf799 100644 --- a/deployment/ansible/roles/cac-tripplanner.app/defaults/main.yml +++ b/deployment/ansible/roles/cac-tripplanner.app/defaults/main.yml @@ -20,16 +20,16 @@ root_media_dir: "/media/cac" app_cron_event_feed: "cd {{ root_app_dir }} && python manage.py load_events >> {{ app_cron_event_feed_log }} 2>&1" cac_python_dependencies: - - { name: 'base58', version: '0.2.4' } - - { name: 'boto', version: '2.45.0' } - - { name: 'django', version: '1.8.17' } - - { name: 'django-ckeditor', version: '5.1.1' } - - { name: 'django-extensions', version: '1.7.5' } - - { name: 'django-storages-redux', version: '1.3.2' } - - { name: 'gunicorn', version: '19.6.0' } - - { name: 'pillow', version: '3.4.2' } - - { name: 'psycopg2', version: '2.6.2' } - - { name: 'pytz', version: '2016.10' } + - { name: 'base58', version: '0.2.5' } + - { name: 'boto', version: '2.48.0' } + - { name: 'django', version: '1.8.18' } + - { name: 'django-ckeditor', version: '5.3.0' } + - { name: 'django-extensions', version: '1.9.0' } + - { name: 'django-storages-redux', version: '1.3.3' } + - { name: 'gunicorn', version: '19.7.1' } + - { name: 'pillow', version: '4.2.1' } + - { name: 'psycopg2', version: '2.7.3' } + - { name: 'pytz', version: '2017.2' } - { name: 'pyyaml', version: '3.12' } - { name: 'troposphere', version: '0.7.2'} # Note: django-wpadmin is installed manually to work around the fact that ansible-pip diff --git a/deployment/ansible/roles/cac-tripplanner.app/tasks/dev-test-dependencies.yml b/deployment/ansible/roles/cac-tripplanner.app/tasks/dev-test-dependencies.yml index 0eaa5c67c..eb012b463 100644 --- a/deployment/ansible/roles/cac-tripplanner.app/tasks/dev-test-dependencies.yml +++ b/deployment/ansible/roles/cac-tripplanner.app/tasks/dev-test-dependencies.yml @@ -2,4 +2,4 @@ - name: Install dev/test python packages pip: name={{ item.name }} version={{ item.version }} with_items: - - { name: 'flake8', version: '2.3.0' } + - { name: 'flake8', version: '3.4.1' } From 3b389800c7e9eb4109f214760917e8e9f6d8a55e Mon Sep 17 00:00:00 2001 From: Kathryn Killebrew Date: Wed, 6 Sep 2017 13:28:50 +0200 Subject: [PATCH 05/10] Add file logging Log Django app debug messages to file. Existing gunicorn logs only record page requests. --- .../cac_tripplanner/settings.py | 44 ++++++++++++++++--- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/python/cac_tripplanner/cac_tripplanner/settings.py b/python/cac_tripplanner/cac_tripplanner/settings.py index 6566b27a2..1e7d811d2 100644 --- a/python/cac_tripplanner/cac_tripplanner/settings.py +++ b/python/cac_tripplanner/cac_tripplanner/settings.py @@ -166,8 +166,7 @@ MEDIA_URL = '/media/' # LOGGING CONFIGURATION -LOGGING_CONFIG = None -logging.config.dictConfig({ +LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { @@ -180,16 +179,49 @@ 'handlers': { 'console': { 'class': 'logging.StreamHandler', + 'level': 'DEBUG', 'formatter': 'verbose', }, + 'logfile': { + 'level': 'DEBUG', + 'class': 'logging.FileHandler', + 'formatter': 'verbose', + 'filename': os.path.join(BASE_DIR, 'cac-tripplanner-app.log'), + }, }, 'loggers': { 'django': { - 'handlers': ['console'], - 'level': 'INFO', - } + 'handlers': ['console', 'logfile'], + 'level': 'DEBUG', + 'propagate': True, + }, + 'ckeditor': { + 'handlers': ['console', 'logfile'], + 'level': 'DEBUG', + 'propagate': True, + }, + 'wpadmin': { + 'handlers': ['console', 'logfile'], + 'level': 'DEBUG', + 'propagate': True, + }, + 'destinations': { + 'handlers': ['console', 'logfile'], + 'level': 'DEBUG', + 'propagate': True, + }, + 'cms': { + 'handlers': ['console', 'logfile'], + 'level': 'DEBUG', + 'propagate': True, + }, + 'shortlinks': { + 'handlers': ['console', 'logfile'], + 'level': 'DEBUG', + 'propagate': True, + }, } -}) +} # TEMPLATE CONFIGURATION # See https://docs.djangoproject.com/en/1.8/ref/settings/#templates From c976cbd01cb48903d947b368bd16ed54a4081014 Mon Sep 17 00:00:00 2001 From: Kathryn Killebrew Date: Wed, 6 Sep 2017 17:12:06 +0200 Subject: [PATCH 06/10] Reduce log level Log INFO and above only by default and for Django core. --- python/cac_tripplanner/cac_tripplanner/settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/cac_tripplanner/cac_tripplanner/settings.py b/python/cac_tripplanner/cac_tripplanner/settings.py index 1e7d811d2..2f054fbec 100644 --- a/python/cac_tripplanner/cac_tripplanner/settings.py +++ b/python/cac_tripplanner/cac_tripplanner/settings.py @@ -179,7 +179,7 @@ 'handlers': { 'console': { 'class': 'logging.StreamHandler', - 'level': 'DEBUG', + 'level': 'INFO', 'formatter': 'verbose', }, 'logfile': { @@ -192,7 +192,7 @@ 'loggers': { 'django': { 'handlers': ['console', 'logfile'], - 'level': 'DEBUG', + 'level': 'INFO', 'propagate': True, }, 'ckeditor': { From 074c4e8b05584a3d17c4667c46ce87c9eb6d91b0 Mon Sep 17 00:00:00 2001 From: Kathryn Killebrew Date: Wed, 6 Sep 2017 13:08:03 +0200 Subject: [PATCH 07/10] Do not use service worker to cache admin pages Service worker requests will not include credentials unless specifically requested in the fetch. See `credentials` parameter discussion here: https://developers.google.com/web/fundamentals/getting-started/primers/service-workers However, including credentials for all fetch requests will cause some requests to fail, such as for third-party fonts. Instead exclude `admin` page requests (to the Django CMS app) from the cache, which require the CSRF token for form posts. Fixes #887. --- python/cac_tripplanner/templates/service-worker.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/cac_tripplanner/templates/service-worker.js b/python/cac_tripplanner/templates/service-worker.js index 09dc620e2..06a3d102b 100644 --- a/python/cac_tripplanner/templates/service-worker.js +++ b/python/cac_tripplanner/templates/service-worker.js @@ -1,7 +1,7 @@ // Service Worker to support functioning as a PWA // https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers -var CACHE_NAME = 'cac_tripplanner_v1'; +var CACHE_NAME = 'cac_tripplanner_v2'; var cacheFiles = {{ cache_files | safe }}; @@ -28,7 +28,7 @@ self.addEventListener('fetch', function(event) { } else { return fetch(event.request).then(function (response) { // cache fetched request if it is on this domain - if (request.url.startsWith(location.href)) { + if (!location.href.includes('/admin') && request.url.startsWith(location.href)) { var responseClone = response.clone(); caches.open(CACHE_NAME).then(function (cache) { cache.put(event.request, responseClone); From bc3a0295ba8f48bcd9709ef2fa7ec834ca5414e7 Mon Sep 17 00:00:00 2001 From: Kathryn Killebrew Date: Fri, 8 Sep 2017 17:52:41 +0200 Subject: [PATCH 08/10] Fix service worker URL references --- python/cac_tripplanner/templates/service-worker.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/python/cac_tripplanner/templates/service-worker.js b/python/cac_tripplanner/templates/service-worker.js index 06a3d102b..9c10be910 100644 --- a/python/cac_tripplanner/templates/service-worker.js +++ b/python/cac_tripplanner/templates/service-worker.js @@ -27,15 +27,17 @@ self.addEventListener('fetch', function(event) { return response; } else { return fetch(event.request).then(function (response) { - // cache fetched request if it is on this domain - if (!location.href.includes('/admin') && request.url.startsWith(location.href)) { + // cache fetched request if it is on this domain and does not require authentication + if (!event.request.url.includes('/admin') && + event.request.url.startsWith(location.origin)) { var responseClone = response.clone(); caches.open(CACHE_NAME).then(function (cache) { cache.put(event.request, responseClone); }); } return response; - }).catch(function () { + }).catch(function (error) { + console.error(error); return fetch(event.request); }); } From 0f4049d18b8f7f6a8d9a128e57b8aea9c4622e8a Mon Sep 17 00:00:00 2001 From: Kathryn Killebrew Date: Fri, 8 Sep 2017 18:25:14 +0200 Subject: [PATCH 09/10] Exclude POST requests and URLs with origin parameter from cache Only cache GET requests. Fixes service worker related console errors on sharing trip to social media. Still explicitly exclude add admin pages as well (including GET), as they contain the CSRF token. Exclude page request with the origin parameter set, as these may quickly fill cache space. They are relatively low value to cache compared to static assets, as they change often. Note that OTP requests, being to a separate domain, are never cached. --- python/cac_tripplanner/templates/service-worker.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/python/cac_tripplanner/templates/service-worker.js b/python/cac_tripplanner/templates/service-worker.js index 9c10be910..0f8790ea8 100644 --- a/python/cac_tripplanner/templates/service-worker.js +++ b/python/cac_tripplanner/templates/service-worker.js @@ -27,9 +27,15 @@ self.addEventListener('fetch', function(event) { return response; } else { return fetch(event.request).then(function (response) { - // cache fetched request if it is on this domain and does not require authentication - if (!event.request.url.includes('/admin') && - event.request.url.startsWith(location.origin)) { + // Cache fetched request if it is on this domain, + // does not involve a routing request (has an origin), + // and does not require authentication credentials (cookies are not passed). + var url = event.request.url; + if (url.startsWith(location.origin) && + !url.includes('origin=') && + !url.includes('/admin') && + event.request.method === 'GET') { + var responseClone = response.clone(); caches.open(CACHE_NAME).then(function (cache) { cache.put(event.request, responseClone); @@ -38,6 +44,7 @@ self.addEventListener('fetch', function(event) { return response; }).catch(function (error) { console.error(error); + console.error(event); return fetch(event.request); }); } From 1749b30a0053606c03f31ad486ad726dcf56ece6 Mon Sep 17 00:00:00 2001 From: Kathryn Killebrew Date: Fri, 8 Sep 2017 18:39:55 +0200 Subject: [PATCH 10/10] Only cace local static and media files They are all we actually want, apart from the top-level index.html, which is already explicitly cached. Simplifies the service worker and avoids potential issues with requests requiring credentials. --- python/cac_tripplanner/templates/service-worker.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/python/cac_tripplanner/templates/service-worker.js b/python/cac_tripplanner/templates/service-worker.js index 0f8790ea8..9b2337496 100644 --- a/python/cac_tripplanner/templates/service-worker.js +++ b/python/cac_tripplanner/templates/service-worker.js @@ -27,14 +27,10 @@ self.addEventListener('fetch', function(event) { return response; } else { return fetch(event.request).then(function (response) { - // Cache fetched request if it is on this domain, - // does not involve a routing request (has an origin), - // and does not require authentication credentials (cookies are not passed). + // Only cache static and media assets on this domain var url = event.request.url; if (url.startsWith(location.origin) && - !url.includes('origin=') && - !url.includes('/admin') && - event.request.method === 'GET') { + (url.includes('/static') || url.includes('/media'))) { var responseClone = response.clone(); caches.open(CACHE_NAME).then(function (cache) {