Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: sitescripts/extensions/web/adblockbrowserUpdates.py

Issue 29330140: Issue 3312 - Serve release update manifests for Adblock Browser (Closed)
Patch Set: Use os.path.splitext, remove devbuild flag Created Nov. 14, 2015, 12:40 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « .sitescripts.example ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # coding: utf-8 1 # coding: utf-8
2 2
3 # This file is part of the Adblock Plus web scripts, 3 # This file is part of the Adblock Plus web scripts,
4 # Copyright (C) 2006-2015 Eyeo GmbH 4 # Copyright (C) 2006-2015 Eyeo GmbH
5 # 5 #
6 # Adblock Plus is free software: you can redistribute it and/or modify 6 # Adblock Plus is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License version 3 as 7 # it under the terms of the GNU General Public License version 3 as
8 # published by the Free Software Foundation. 8 # published by the Free Software Foundation.
9 # 9 #
10 # Adblock Plus is distributed in the hope that it will be useful, 10 # Adblock Plus is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details. 13 # GNU General Public License for more details.
14 # 14 #
15 # You should have received a copy of the GNU General Public License 15 # You should have received a copy of the GNU General Public License
16 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 16 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
17 17
18 import glob
18 import hashlib 19 import hashlib
20 import json
19 import os 21 import os
20 import re 22 import re
21 from urlparse import parse_qs 23 from urlparse import parse_qs
22 24
23 from jinja2 import Template 25 from jinja2 import Template
24 26
25 from sitescripts.utils import get_config 27 from sitescripts.utils import get_config
26 from sitescripts.web import url_handler 28 from sitescripts.web import url_handler
27 29
28 _MANIFEST_TEMPLATE = Template("""<?xml version="1.0"?> 30 _MANIFEST_TEMPLATE = Template("""<?xml version="1.0"?>
29 <updates> 31 <updates>
30 {% if build %} 32 {% if build %}
31 <update buildID="{{ build.build_id }}"> 33 <update buildID="{{ build.build_id }}">
32 <patch 34 <patch
33 URL="{{ build.url }}" 35 URL="{{ build.url }}"
34 hashFunction="{{ build.hash_function }}" 36 hashFunction="{{ build.hash_function }}"
35 hashValue="{{ build.hash_value }}" 37 hashValue="{{ build.hash_value }}"
36 size="{{ build.size }}"/> 38 size="{{ build.size }}"/>
37 </update> 39 </update>
38 {% endif %} 40 {% endif %}
39 </updates> 41 </updates>
40 42
41 """, autoescape=True) 43 """, autoescape=True)
42 44
43 def _get_latest_build(builds_dir): 45 def _get_latest_build(builds_dir):
44 latest_build = {"id": 0} 46 latest_build = {"id": 0}
45 for file in os.listdir(builds_dir): 47 for json_path in glob.glob(os.path.join(builds_dir, "adblockbrowser-*.json")):
46 match = re.search(r"^adblockbrowser-.*?(\d+)-\w+\.apk$", file) 48 with open(json_path) as json_file:
47 if match: 49 build_id = int(json.loads(json_file.read())["buildid"])
48 build_id = int(match.group(1)) 50 if build_id > latest_build["id"]:
49 if build_id > latest_build["id"]: 51 latest_build["id"] = build_id
50 latest_build["id"] = build_id 52 apk_path = os.path.splitext(json_path)[0] + ".apk"
51 latest_build["path"] = os.path.join(builds_dir, file) 53 latest_build["path"] = os.path.join(builds_dir, apk_path)
52 if latest_build["id"] == 0: 54 if latest_build["id"] == 0:
53 return {} 55 return {}
54 return latest_build 56 return latest_build
55 57
56 def _render_manifest(build=None): 58 def _render_manifest(build=None, builds_url=None):
57 if not build: 59 if not build:
58 return _MANIFEST_TEMPLATE.render() 60 return _MANIFEST_TEMPLATE.render()
59 61
60 nightlies_url = get_config().get("extensions", "nightliesURL") 62 build_url = "%s/%s?update" % (builds_url, os.path.basename(build["path"]))
61 build_url = "%s/adblockbrowser/%s?update" % (nightlies_url.rstrip("/"),
62 os.path.basename(build["path"]))
63 with open(build["path"], "rb") as build_file: 63 with open(build["path"], "rb") as build_file:
64 build_content = build_file.read() 64 build_content = build_file.read()
65 return _MANIFEST_TEMPLATE.render({ 65 return _MANIFEST_TEMPLATE.render({
66 "build": { 66 "build": {
67 "build_id": build["id"], 67 "build_id": build["id"],
68 "url": build_url, 68 "url": build_url,
69 "hash_function": "SHA512", 69 "hash_function": "SHA512",
70 "hash_value": hashlib.sha512(build_content).hexdigest(), 70 "hash_value": hashlib.sha512(build_content).hexdigest(),
71 "size": len(build_content) 71 "size": len(build_content)
72 } 72 }
73 }) 73 })
74 74
75 def _get_update_manifest(current_build_id): 75 def _get_update_manifest(current_build_id, builds_dir, builds_url):
76 nightlies_dir = get_config().get("extensions", "nightliesDirectory")
77 builds_dir = os.path.join(nightlies_dir, "adblockbrowser")
78 if not os.path.isdir(builds_dir): 76 if not os.path.isdir(builds_dir):
79 return _render_manifest() 77 return _render_manifest()
80 78
81 latest_build = _get_latest_build(builds_dir) 79 latest_build = _get_latest_build(builds_dir)
82 if not latest_build or current_build_id >= latest_build["id"]: 80 if not latest_build or current_build_id >= latest_build["id"]:
83 return _render_manifest() 81 return _render_manifest()
84 return _render_manifest(latest_build) 82 return _render_manifest(latest_build, builds_url)
85 83
86 @url_handler("/devbuilds/adblockbrowser/updates.xml") 84 def _handle_request(environ, start_response, builds_dir, builds_url):
87 def adblockbrowser_updates(environ, start_response):
88 params = parse_qs(environ.get("QUERY_STRING", "")) 85 params = parse_qs(environ.get("QUERY_STRING", ""))
89 try: 86 try:
90 version = params.get("addonVersion", [""])[0] 87 version = params.get("addonVersion", [""])[0]
91 build_id = int(re.search(r"(\d+)$", version).group(1)) 88 build_id = int(re.search(r"(\d+)$", version).group(1))
92 except: 89 except:
93 start_response("400 Processing Error", [("Content-Type", "text/plain")]) 90 start_response("400 Processing Error", [("Content-Type", "text/plain")])
94 return ["Failed to parse addonVersion."] 91 return ["Failed to parse addonVersion."]
95 manifest = _get_update_manifest(build_id) 92 manifest = _get_update_manifest(build_id, builds_dir, builds_url)
96 response = manifest.encode("utf-8") 93 response = manifest.encode("utf-8")
97 start_response("200 OK", [("Content-Type", "application/xml; charset=utf-8")]) 94 start_response("200 OK", [("Content-Type", "application/xml; charset=utf-8")])
98 return [response] 95 return [response]
96
97 @url_handler("/adblockbrowser/updates.xml")
98 def adblockbrowser_updates(environ, start_response):
99 builds_dir = get_config().get("extensions", "downloadsDirectory")
100 builds_url = get_config().get("extensions", "downloadsURL").rstrip("/")
Sebastian Noack 2015/11/14 21:09:23 How about caching the config object instead callin
Felix Dahlke 2015/11/19 09:37:34 Done.
101 return _handle_request(environ, start_response, builds_dir, builds_url)
102
103 @url_handler("/devbuilds/adblockbrowser/updates.xml")
104 def adblockbrowser_devbuild_updates(environ, start_response):
105 nightlies_dir = get_config().get("extensions", "nightliesDirectory")
106 builds_dir = os.path.join(nightlies_dir, "adblockbrowser")
107
108 nightlies_url = get_config().get("extensions", "nightliesURL").rstrip("/")
109 builds_url = "%s/adblockbrowser" % nightlies_url
110
111 return _handle_request(environ, start_response, builds_dir, builds_url)
OLDNEW
« no previous file with comments | « .sitescripts.example ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld