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

Side by Side Diff: sitescripts/extensions/utils.py

Issue 6291923287408640: Issue 1093 - Separate update manifest generation (Closed)
Patch Set: Fix issue Created July 23, 2014, 4:50 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/extensions/bin/updateUpdateManifests.py ('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-2014 Eyeo GmbH 4 # Copyright (C) 2006-2014 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 os
18 import re 19 import re
19 import os
20 import subprocess 20 import subprocess
21 import time
22 import urlparse
23 import urllib
24 import urllib2
25 import xml.dom.minidom as dom
21 from ConfigParser import SafeConfigParser, NoOptionError 26 from ConfigParser import SafeConfigParser, NoOptionError
22 from StringIO import StringIO 27 from StringIO import StringIO
23 from sitescripts.utils import get_config 28 from sitescripts.utils import get_config
24 29
25 def compareVersionParts(part1, part2): 30 def compareVersionParts(part1, part2):
26 def convertInt(value, default): 31 def convertInt(value, default):
27 try: 32 try:
28 return int(value) 33 return int(value)
29 except ValueError: 34 except ValueError:
30 return default 35 return default
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 except M2Crypto.X509.X509Error: 254 except M2Crypto.X509.X509Error:
250 raise Exception('No safari developer certificate found in chain') 255 raise Exception('No safari developer certificate found in chain')
251 256
252 subject = cert.get_subject() 257 subject = cert.get_subject()
253 for entry in subject.get_entries_by_nid(subject.nid['CN']): 258 for entry in subject.get_entries_by_nid(subject.nid['CN']):
254 m = re.match(r'Safari Developer: \((.*?)\)', entry.get_data().as_text()) 259 m = re.match(r'Safari Developer: \((.*?)\)', entry.get_data().as_text())
255 if m: 260 if m:
256 return m.group(1) 261 return m.group(1)
257 finally: 262 finally:
258 bio.close() 263 bio.close()
264
265 def _urlencode(value):
266 return urllib.quote(value.encode('utf-8'), '')
267
268 def _urlopen(url, attempts=3):
269 """
270 Tries to open a particular URL, retries on failure.
271 """
272 for i in range(attempts):
273 try:
274 return urllib.urlopen(url)
275 except IOError, e:
276 error = e
277 time.sleep(5)
278 raise error
279
280 def _getMozillaDownloadLink(galleryID):
281 """
282 gets download link for a Gecko add-on from the Mozilla Addons site
283 """
284 url = 'https://services.addons.mozilla.org/en-US/firefox/api/1/addon/%s' % _ur lencode(galleryID)
285 document = dom.parse(_urlopen(url))
286 linkTags = document.getElementsByTagName('install')
287 linkTag = linkTags[0] if len(linkTags) > 0 else None
288 versionTags = document.getElementsByTagName('version')
289 versionTag = versionTags[0] if len(versionTags) > 0 else None
290 if linkTag and versionTag and linkTag.firstChild and versionTag.firstChild:
291 return (linkTag.firstChild.data, versionTag.firstChild.data)
292 else:
293 return (None, None)
294
295 def _getGoogleDownloadLink(galleryID):
296 """
297 gets download link for a Chrome add-on from the Chrome Gallery site
298 """
299 galleryID = _urlencode(galleryID)
300
301 url = 'https://clients2.google.com/service/update2/crx?x=%s' % _urlencode('id= %s&uc' % galleryID)
302 document = dom.parse(_urlopen(url))
303 updateTags = document.getElementsByTagName('updatecheck')
304 version = updateTags and updateTags[0].getAttribute('version')
305
306 if not version:
307 return (None, None)
308
309 request = urllib2.Request('https://chrome.google.com/webstore/detail/_/' + gal leryID)
310 request.get_method = lambda : 'HEAD'
311 url = urllib2.urlopen(request).geturl()
312
313 return (url, version)
314
315 def _getOperaDownloadLink(galleryID):
316 """
317 gets download link for an Opera add-on from the Opera Addons site
318 """
319 galleryID = _urlencode(galleryID)
320
321 request = urllib2.Request('https://addons.opera.com/extensions/download/%s/' % galleryID)
322 request.get_method = lambda : 'HEAD'
323 response = urllib2.urlopen(request)
324
325 content_disposition = response.info().getheader('Content-Disposition')
326 if content_disposition:
327 match = re.search(r'filename=\S+-([\d.]+)-\d+\.crx$', content_disposition)
328 if match:
329 return ('https://addons.opera.com/extensions/details/%s/' % galleryID , ma tch.group(1))
330
331 return (None, None)
332
333 def _getLocalLink(repo):
334 """
335 gets the link for the newest download of an add-on in the local downloads
336 repository
337 """
338 highestURL = None
339 highestVersion = None
340
341 for filename, version in repo.getDownloads():
342 if not highestVersion or compareVersions(version, highestVersion) > 0:
343 highestURL = urlparse.urljoin(repo.downloadsURL, filename)
344 highestVersion = version
345
346 return (highestURL, highestVersion)
347
348 def _getDownloadLink(repo):
349 """
350 gets the download link to the most current version of an extension
351 """
352 # you can't easily install extensions from third-party sources on Chrome
353 # and Opera. So always get the link for the version on the Web Store.
354 if repo.galleryID:
355 if repo.type == "chrome":
356 return _getGoogleDownloadLink(repo.galleryID)
357 if repo.type == "opera":
358 return _getOperaDownloadLink(repo.galleryID)
359
360 (localURL, localVersion) = _getLocalLink(repo)
361
362 # get a link to Firefox Add-Ons, if the latest version has been published ther e
363 if repo.type == 'gecko' and repo.galleryID:
364 (galleryURL, galleryVersion) = _getMozillaDownloadLink(repo.galleryID)
365 if not localVersion or (galleryVersion and
366 compareVersions(galleryVersion, localVersion) >= 0):
367 return (galleryURL, galleryVersion)
368
369 return (localURL, localVersion)
370
371 def _getQRCode(text):
372 try:
373 import qrcode
374 import base64
375 import Image # required by qrcode but not formally a dependency
376 except:
377 return None
378
379 data = StringIO()
380 qrcode.make(text, box_size=5).save(data, 'png')
381 return 'data:image/png;base64,' + base64.b64encode(data.getvalue())
382
383 def getDownloadLinks(result):
384 """
385 gets the download links for all extensions and puts them into the config
386 object
387 """
388 for repo in Configuration.getRepositoryConfigurations():
389 (downloadURL, version) = _getDownloadLink(repo)
390 if downloadURL == None:
391 continue
392 if not result.has_section(repo.repositoryName):
393 result.add_section(repo.repositoryName)
394 result.set(repo.repositoryName, "downloadURL", downloadURL)
395 result.set(repo.repositoryName, "version", version)
396
397 qrcode = _getQRCode(downloadURL)
398 if qrcode != None:
399 result.set(repo.repositoryName, "qrcode", qrcode)
OLDNEW
« no previous file with comments | « sitescripts/extensions/bin/updateUpdateManifests.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld