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

Side by Side Diff: packagerChrome.py

Issue 9199007: Unified in-memory file processing between Gecko and Chrome (Closed)
Patch Set: Created Jan. 14, 2013, 11:14 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 | « packager.py ('k') | packagerGecko.py » ('j') | 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 build tools, 3 # This file is part of the Adblock Plus build tools,
4 # Copyright (C) 2006-2012 Eyeo GmbH 4 # Copyright (C) 2006-2012 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 sys, os, re, json, struct 18 import sys, os, re, json, struct
19 from StringIO import StringIO 19 from StringIO import StringIO
20 from zipfile import ZipFile, ZIP_DEFLATED
21 20
22 from packager import getDefaultFileName, readMetadata, getBuildVersion, getTempl ate 21 from packager import getDefaultFileName, readMetadata, getBuildVersion, getTempl ate, Files
23 22
24 defaultLocale = 'en_US' 23 defaultLocale = 'en_US'
25 24
26 def getIgnoredFiles(params): 25 def getIgnoredFiles(params):
27 return ['store.description'] 26 return set(('store.description',))
28 27
29 def getPackageFiles(params): 28 def getPackageFiles(params):
29 result = set(('_locales', 'icons', 'jquery-ui', 'lib', 'skin', 'ui',))
30
31 if params['devenv']:
32 result.add('qunit')
33
30 baseDir = params['baseDir'] 34 baseDir = params['baseDir']
31 for file in ('_locales', 'icons', 'jquery-ui', 'lib', 'skin', 'ui'):
32 yield os.path.join(baseDir, file)
33 if params['devenv']:
34 yield os.path.join(baseDir, 'qunit')
35 for file in os.listdir(baseDir): 35 for file in os.listdir(baseDir):
36 if file.endswith('.js') or file.endswith('.html') or file.endswith('.xml'): 36 if file.endswith('.js') or file.endswith('.html') or file.endswith('.xml'):
37 yield os.path.join(baseDir, file) 37 result.add(file)
38 return result
38 39
39 def createManifest(params): 40 def createManifest(params):
40 template = getTemplate('manifest.json.tmpl') 41 template = getTemplate('manifest.json.tmpl')
41 templateData = dict(params) 42 templateData = dict(params)
42 43
43 baseDir = templateData['baseDir'] 44 baseDir = templateData['baseDir']
44 metadata = templateData['metadata'] 45 metadata = templateData['metadata']
45 46
46 if metadata.has_option('general', 'pageAction'): 47 if metadata.has_option('general', 'pageAction'):
47 icon, popup = re.split(r'\s+', metadata.get('general', 'pageAction'), 1) 48 icon, popup = re.split(r'\s+', metadata.get('general', 'pageAction'), 1)
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 if '_dummy' in data: 96 if '_dummy' in data:
96 del data['_dummy'] 97 del data['_dummy']
97 manifest = json.dumps(data, sort_keys=True, indent=2) 98 manifest = json.dumps(data, sort_keys=True, indent=2)
98 99
99 return manifest.encode('utf-8') 100 return manifest.encode('utf-8')
100 101
101 def createPoller(params): 102 def createPoller(params):
102 template = getTemplate('chromeDevenvPoller__.js.tmpl') 103 template = getTemplate('chromeDevenvPoller__.js.tmpl')
103 return template.render(params).encode('utf-8'); 104 return template.render(params).encode('utf-8');
104 105
105 def readFile(params, files, path):
106 ignoredFiles = getIgnoredFiles(params)
107 if os.path.isdir(path):
108 for file in os.listdir(path):
109 if file in ignoredFiles:
110 continue
111 readFile(params, files, os.path.join(path, file))
112 else:
113 file = open(path, 'rb')
114 data = file.read()
115 file.close()
116
117 name = os.path.relpath(path, params['baseDir']).replace('\\', '/')
118 files[name] = data
119
120 def convertJS(params, files): 106 def convertJS(params, files):
121 from jshydra.abp_rewrite import doRewrite 107 from jshydra.abp_rewrite import doRewrite
122 baseDir = params['baseDir'] 108 baseDir = params['baseDir']
123 109
124 for file, sources in params['metadata'].items('convert_js'): 110 for file, sources in params['metadata'].items('convert_js'):
125 dirsep = file.find('/') 111 # Make sure the file is inside an included directory
126 if dirsep >= 0: 112 if '/' in file and not files.isIncluded(file):
127 # Not a top-level file, make sure it is inside an included directory 113 continue
128 dirname = file[0:dirsep]
129 if os.path.join(baseDir, dirname) not in getPackageFiles(params):
130 continue
131 114
132 sourceFiles = re.split(r'\s+', sources) 115 sourceFiles = re.split(r'\s+', sources)
133 args = [] 116 args = []
134 try: 117 try:
135 argsStart = sourceFiles.index('--arg') 118 argsStart = sourceFiles.index('--arg')
136 args = sourceFiles[argsStart + 1:] 119 args = sourceFiles[argsStart + 1:]
137 sourceFiles = sourceFiles[0:argsStart] 120 sourceFiles = sourceFiles[0:argsStart]
138 except ValueError: 121 except ValueError:
139 pass 122 pass
140 123
141 sourceFiles = map(lambda f: os.path.abspath(os.path.join(baseDir, f)), sourc eFiles) 124 sourceFiles = map(lambda f: os.path.abspath(os.path.join(baseDir, f)), sourc eFiles)
142 files[file] = doRewrite(sourceFiles, args) 125 files[file] = doRewrite(sourceFiles, args)
143 126
144 def packFiles(files):
145 buffer = StringIO()
146 zip = ZipFile(buffer, 'w', ZIP_DEFLATED)
147 for file, data in files.iteritems():
148 zip.writestr(file, data)
149 zip.close()
150 return buffer.getvalue()
151
152 def signBinary(zipdata, keyFile): 127 def signBinary(zipdata, keyFile):
153 import M2Crypto 128 import M2Crypto
154 if not os.path.exists(keyFile): 129 if not os.path.exists(keyFile):
155 M2Crypto.RSA.gen_key(1024, 65537, callback=lambda x: None).save_key(keyFile, cipher=None) 130 M2Crypto.RSA.gen_key(1024, 65537, callback=lambda x: None).save_key(keyFile, cipher=None)
156 key = M2Crypto.EVP.load_key(keyFile) 131 key = M2Crypto.EVP.load_key(keyFile)
157 key.sign_init() 132 key.sign_init()
158 key.sign_update(zipdata) 133 key.sign_update(zipdata)
159 return key.final() 134 return key.final()
160 135
161 def getPublicKey(keyFile): 136 def getPublicKey(keyFile):
(...skipping 20 matching lines...) Expand all
182 157
183 params = { 158 params = {
184 'baseDir': baseDir, 159 'baseDir': baseDir,
185 'releaseBuild': releaseBuild, 160 'releaseBuild': releaseBuild,
186 'version': version, 161 'version': version,
187 'experimentalAPI': experimentalAPI, 162 'experimentalAPI': experimentalAPI,
188 'devenv': devenv, 163 'devenv': devenv,
189 'metadata': metadata, 164 'metadata': metadata,
190 } 165 }
191 166
192 files = {} 167 files = Files(getPackageFiles(params), getIgnoredFiles(params))
193 files['manifest.json'] = createManifest(params) 168 files['manifest.json'] = createManifest(params)
194 for path in getPackageFiles(params): 169 files.read(baseDir)
195 if os.path.exists(path):
196 readFile(params, files, path)
197 170
198 if metadata.has_section('convert_js'): 171 if metadata.has_section('convert_js'):
199 convertJS(params, files) 172 convertJS(params, files)
200 173
201 if devenv: 174 if devenv:
202 files['devenvPoller__.js'] = createPoller(params) 175 files['devenvPoller__.js'] = createPoller(params)
203 176
204 zipdata = packFiles(files) 177 zipdata = files.zipToString()
205 signature = None 178 signature = None
206 pubkey = None 179 pubkey = None
207 if keyFile != None: 180 if keyFile != None:
208 signature = signBinary(zipdata, keyFile) 181 signature = signBinary(zipdata, keyFile)
209 pubkey = getPublicKey(keyFile) 182 pubkey = getPublicKey(keyFile)
210 writePackage(outFile, pubkey, signature, zipdata) 183 writePackage(outFile, pubkey, signature, zipdata)
211 184
212 def createDevEnv(baseDir): 185 def createDevEnv(baseDir):
213 fileBuffer = StringIO() 186 fileBuffer = StringIO()
214 createBuild(baseDir, outFile=fileBuffer, devenv=True, releaseBuild=True) 187 createBuild(baseDir, outFile=fileBuffer, devenv=True, releaseBuild=True)
188
189 from zipfile import ZipFile
215 zip = ZipFile(StringIO(fileBuffer.getvalue()), 'r') 190 zip = ZipFile(StringIO(fileBuffer.getvalue()), 'r')
216 zip.extractall(os.path.join(baseDir, 'devenv')) 191 zip.extractall(os.path.join(baseDir, 'devenv'))
217 zip.close() 192 zip.close()
218 193
219 print 'Development environment created, waiting for connections from active ex tensions...' 194 print 'Development environment created, waiting for connections from active ex tensions...'
220 metadata = readMetadata(baseDir) 195 metadata = readMetadata(baseDir)
221 connections = [0] 196 connections = [0]
222 197
223 import SocketServer, time, thread 198 import SocketServer, time, thread
224 199
225 class ConnectionHandler(SocketServer.BaseRequestHandler): 200 class ConnectionHandler(SocketServer.BaseRequestHandler):
226 def handle(self): 201 def handle(self):
227 connections[0] += 1 202 connections[0] += 1
228 self.request.sendall('HTTP/1.0 OK\nConnection: close\n\n%s' % metadata.get ('general', 'basename')) 203 self.request.sendall('HTTP/1.0 OK\nConnection: close\n\n%s' % metadata.get ('general', 'basename'))
229 204
230 server = SocketServer.TCPServer(('localhost', 43816), ConnectionHandler) 205 server = SocketServer.TCPServer(('localhost', 43816), ConnectionHandler)
231 206
232 def shutdown_server(server): 207 def shutdown_server(server):
233 time.sleep(10) 208 time.sleep(10)
234 server.shutdown() 209 server.shutdown()
235 thread.start_new_thread(shutdown_server, (server,)) 210 thread.start_new_thread(shutdown_server, (server,))
236 server.serve_forever() 211 server.serve_forever()
237 212
238 if connections[0] == 0: 213 if connections[0] == 0:
239 print 'Warning: No incoming connections, extension probably not active in th e browser yet' 214 print 'Warning: No incoming connections, extension probably not active in th e browser yet'
240 else: 215 else:
241 print 'Handled %i connection(s)' % connections[0] 216 print 'Handled %i connection(s)' % connections[0]
OLDNEW
« no previous file with comments | « packager.py ('k') | packagerGecko.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld