VulpesOS/gaia/tools/cache_sync.py
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

116 lines
2.8 KiB
Python
Executable file

# Synchronizes the offline cache of an external app into a local directory
# structure. Run from the base directory of an app in gaia/external-apps.
# Builds a directory for each known origin in the offline cache.
import json
import os
import requests
def read_manifest():
file = open('manifest.webapp', 'r').read()
content = json.loads(file)
return content
def read_origin():
# Extract the origin from the origin file
return open('origin', 'r').readline().rstrip()
def parse_offline_manifest(s, origin):
lines = s.split('\n')
# Bail if this is an invalid appcache manifest.
if lines[0] != 'CACHE MANIFEST':
return None
sections = ['CACHE:', 'NETWORK:', 'FALLBACK:']
current_section = 'CACHE'
cache = []
for line in lines[1:]:
# ignore comments, empty lines, and wildcards
if line.startswith('#') or line.startswith('*') or not line.rstrip():
continue
if line in sections:
current_section = line[:len(line)-1]
continue
# Don't cache NETWORK entries.
if current_section == 'NETWORK':
continue
# if we're in FALLBACK, extract the fallback path.
if current_section == 'FALLBACK':
line = line.split(' ')[1]
# Ensure that all paths start with an origin.
if not line.startswith('http'):
if line.startswith('/'):
line = line[1:]
line = origin + line
cache.append(line)
return cache
def fetch_with_path(url):
# are we dealing with something URL-esque?
if not url.find('//') + 1:
return None
print 'fetching %s' % url
file = requests.get(url, verify=False)
if file.status_code != 200:
return None
# base our paths in the 'cache' directory.
path = 'cache/' + url.split('//')[1]
directory, fn = path.rsplit('/', 1)
# make the directory structure
if not os.path.exists(directory):
os.makedirs(directory)
# write our file
out_file = open(path, 'w')
out_file.write(file.content)
return file.content;
def main():
# Learn about the external app.
app_manifest = read_manifest()
origin = read_origin()
if 'appcache_path' not in app_manifest:
print 'no appcache found'
return
# Construct the appcache url and drop the first slash from appcache_path.
appcache_url = origin + app_manifest.get('appcache_path')[1:]
print 'fetching appcache at %s' % appcache_url
cache_manifest = fetch_with_path(appcache_url)
if not cache_manifest:
print 'failed to fetch appcache'
return
cache = parse_offline_manifest(cache_manifest, origin)
if not cache:
print 'bad offline cache'
return
# fetch each file, and store it in the right place
for entry in cache:
fetch_with_path(entry);
main()