Getting a PWA set up based on web2py

231 views
Skip to first unread message

Valdeck Rowe

unread,
Oct 10, 2018, 5:25:25 AM10/10/18
to web2py-users

I decided to use upup.js by Tal Ater, website here: https://www.talater.com/upup/getting-started-with-offline-first.html, mainly because I had a project deadline and needed something with a short learning curve.

The main thing about PWAs appears to be that the service worker javascript files need to be accessible from the domain root.

Warning - this is all very hackish - I wasn't sure how to get a file to appear as if it was on the actual domain root.

I tried setting it up using a controller to serve as the base for the JS and manifest files in order to mimic the root.

This is the controller setup:
def manifest():
    item
= db(db.item.id > 0).select().first()
   
return locals()


def upup():
   
return locals()


def upup_sw():
   
return locals()

    

manifest.json
{
 
"name": "{{=item.name}}",
 
"short_name": "{{=item.slugname}}",
 
"theme_color": "#2196f3",
 
"background_color": "rgba(243,216,33,0.62)",
 
"display": "standalone",
 
"Scope": "/app2/items/",
 
"start_url": "/app2/items/",
 
"icons": [
   
{
     
"src": "{{=URL('static', 'images/icons/icon-72x72.png', scheme='https', host=True)}}",
     
"sizes": "72x72",
     
"type": "image/png"
   
},
   
{
     
"src": "{{=URL('static', 'images/icons/icon-96x96.png', scheme='https', host=True)}}",
     
"sizes": "96x96",
     
"type": "image/png"
   
},
   
{
     
"src": "{{=URL('static', 'images/icons/icon-128x128.png', scheme='https', host=True)}}",
     
"sizes": "128x128",
     
"type": "image/png"
   
},
   
{
     
"src": "{{=URL('static', 'images/icons/icon-144x144.png', scheme='https', host=True)}}",
     
"sizes": "144x144",
     
"type": "image/png"
   
},
   
{
     
"src": "{{=URL('static', 'images/icons/icon-152x152.png', scheme='https', host=True)}}",
     
"sizes": "152x152",
     
"type": "image/png"
   
},
   
{
     
"src": "{{=URL('static', 'images/icons/icon-192x192.png', scheme='https', host=True)}}",
     
"sizes": "192x192",
     
"type": "image/png"
   
},
   
{
     
"src": "{{=URL('static', 'images/icons/icon-384x384.png', scheme='https', host=True)}}",
     
"sizes": "384x384",
     
"type": "image/png"
   
},
   
{
     
"src": "{{=URL('static', 'images/icons/icon-512x512.png', scheme='https', host=True)}}",
     
"sizes": "512x512",
     
"type": "image/png"
   
}
 
],
 
"splash_pages": null
}



upup.js # I simply copied the contents
//! UpUp
//! version : 1.0.0
//! author  : Tal Ater @TalAter
//! license : MIT
//! https://github.com/TalAter/UpUp
(function(e){"use strict";var t=navigator.serviceWorker;if(!t)return this.UpUp=null,e;var n={"service-worker-url":"{{=URL('items', 'upup_sw.js', scheme=True, )}}"},r=!1,s="font-weight: bold; color: #00f;";this.UpUp={start:function(e){this.addSettings(e),t.register(n["service-worker-url"],{scope:"./app2/items/"}).then(function(e){r&&console.log("Service worker registration successful with scope: %c"+e.scope,s);(e.installing||t.controller||e.active).postMessage({action:"set-settings",settings:n})}).catch(function(e){r&&console.log("Service worker registration failed: %c"+e,s)})},addSettings:function(t){"string"==typeof(t=t||{})&&(t={content:t}),["content","content-url","assets","service-worker-url","cache-version"].forEach(function(r){t[r]!==e&&(n[r]=t[r])})},debug:function(e){r=!(arguments.length>0)||!!e}}}).call(this);
//# sourceMappingURL=upup.js.map



upup_sw.js
//! UpUp Service Worker
//! version : 1.0.0                  
//! license : MIT
//! https://github.com/TalAter/UpUp
var _CACHE_NAME_PREFIX="upup-cache",_calculateHash=function(e){var t,n=0,s=(e=e.toString()).length;if(0===s)return n;for(t=0;t<s;t++)n=(n<<5)-n+e.charCodeAt(t),n|=0;return n};self.addEventListener("message",function(e){"set-settings"===e.data.action&&_parseSettingsAndCache(e.data.settings)}),self.addEventListener("fetch",function(e){e.respondWith(fetch(e.request).catch(function(){return caches.match(e.request).then(function(t){return t||("navigate"===e.request.mode||"GET"===e.request.method&&e.request.headers.get("accept").includes("text/html")?caches.match("sw-offline-content"):void 0)})}))});var _parseSettingsAndCache=function(e){var t=_CACHE_NAME_PREFIX+"-"+(e["cache-version"]?e["cache-version"]+"-":"")+_calculateHash(e.content+e["content-url"]+e.assets);return caches.open(t).then(function(t){return e.assets&&t.addAll(e.assets.map(function(e){return new Request(e,{mode:"no-cors"})})),e["content-url"]?fetch(e["content-url"],{mode:"no-cors"}).then(function(e){return t.put("sw-offline-content",e)}):e.content?t.put("sw-offline-content",_buildResponse(e.content)):t.put("sw-offline-content",_buildResponse("You are offline"))}).then(function(){return caches.keys().then(function(e){return Promise.all(e.map(function(e){if(e.startsWith(_CACHE_NAME_PREFIX)&&t!==e)return caches.delete(e)}))})})},_buildResponse=function(e){return new Response(e,{headers:{"Content-Type":"text/html"}})};
//# sourceMappingURL=upup_sw.js.map



The main issue I'm having so far is getting a 404 error when trying to load the service worker file (upup_sw.js) which I think is a path issue (inside upup.js).

Any ideas?

Jose C

unread,
Oct 10, 2018, 6:34:00 AM10/10/18
to web2py-users

The main thing about PWAs appears to be that the service worker javascript files need to be accessible from the domain root.
...
The main issue I'm having so far is getting a 404 error when trying to load the service worker file (upup_sw.js) which I think is a path issue (inside upup.js).

Any ideas?

To serve files from root you'll need to set it up in your routes.py file  (e.g. mine looks like this...)

routers = dict(
   
# base router
    BASE
= dict(
        default_application
= 'your app here',
        applications
= ['your app here'],
        default_function
= 'index',
        root_static
= [
           
'favicon.ico',
           
'robots.txt',
           
'manifest.json',
           
'sw.min.js',
           
],
   
),

Then I have the above files I want serving from root located in my app_name/static directory.

and if you view the comments in the default routes.py file it should also help (specifically the root_static var)

HTH,




mostwanted

unread,
Oct 11, 2019, 2:06:26 AM10/11/19
to web2py-users
Hi @Valdeck Rowe,  i wan to know if this approach worked for you in your PWA  development. Were there any developments or changes to this approach? I am asking because i was hoping to use your approach in my desperate attempt at making one of my apps a PWA.

Regards;

Mostwanted

dirman

unread,
Nov 28, 2019, 8:28:24 AM11/28/19
to web2py-users
You can also use this approach https://groups.google.com/d/msg/web2py/W4cbtIDNoSA/Lb0bTJilAgAJ. It works fine for me.
Reply all
Reply to author
Forward
0 new messages