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

Unified 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.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sitescripts/extensions/bin/updateUpdateManifests.py ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sitescripts/extensions/utils.py
===================================================================
--- a/sitescripts/extensions/utils.py
+++ b/sitescripts/extensions/utils.py
@@ -15,9 +15,14 @@
# You should have received a copy of the GNU General Public License
# along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
+import os
import re
-import os
import subprocess
+import time
+import urlparse
+import urllib
+import urllib2
+import xml.dom.minidom as dom
from ConfigParser import SafeConfigParser, NoOptionError
from StringIO import StringIO
from sitescripts.utils import get_config
@@ -256,3 +261,139 @@
return m.group(1)
finally:
bio.close()
+
+def _urlencode(value):
+ return urllib.quote(value.encode('utf-8'), '')
+
+def _urlopen(url, attempts=3):
+ """
+ Tries to open a particular URL, retries on failure.
+ """
+ for i in range(attempts):
+ try:
+ return urllib.urlopen(url)
+ except IOError, e:
+ error = e
+ time.sleep(5)
+ raise error
+
+def _getMozillaDownloadLink(galleryID):
+ """
+ gets download link for a Gecko add-on from the Mozilla Addons site
+ """
+ url = 'https://services.addons.mozilla.org/en-US/firefox/api/1/addon/%s' % _urlencode(galleryID)
+ document = dom.parse(_urlopen(url))
+ linkTags = document.getElementsByTagName('install')
+ linkTag = linkTags[0] if len(linkTags) > 0 else None
+ versionTags = document.getElementsByTagName('version')
+ versionTag = versionTags[0] if len(versionTags) > 0 else None
+ if linkTag and versionTag and linkTag.firstChild and versionTag.firstChild:
+ return (linkTag.firstChild.data, versionTag.firstChild.data)
+ else:
+ return (None, None)
+
+def _getGoogleDownloadLink(galleryID):
+ """
+ gets download link for a Chrome add-on from the Chrome Gallery site
+ """
+ galleryID = _urlencode(galleryID)
+
+ url = 'https://clients2.google.com/service/update2/crx?x=%s' % _urlencode('id=%s&uc' % galleryID)
+ document = dom.parse(_urlopen(url))
+ updateTags = document.getElementsByTagName('updatecheck')
+ version = updateTags and updateTags[0].getAttribute('version')
+
+ if not version:
+ return (None, None)
+
+ request = urllib2.Request('https://chrome.google.com/webstore/detail/_/' + galleryID)
+ request.get_method = lambda : 'HEAD'
+ url = urllib2.urlopen(request).geturl()
+
+ return (url, version)
+
+def _getOperaDownloadLink(galleryID):
+ """
+ gets download link for an Opera add-on from the Opera Addons site
+ """
+ galleryID = _urlencode(galleryID)
+
+ request = urllib2.Request('https://addons.opera.com/extensions/download/%s/' % galleryID)
+ request.get_method = lambda : 'HEAD'
+ response = urllib2.urlopen(request)
+
+ content_disposition = response.info().getheader('Content-Disposition')
+ if content_disposition:
+ match = re.search(r'filename=\S+-([\d.]+)-\d+\.crx$', content_disposition)
+ if match:
+ return ('https://addons.opera.com/extensions/details/%s/' % galleryID , match.group(1))
+
+ return (None, None)
+
+def _getLocalLink(repo):
+ """
+ gets the link for the newest download of an add-on in the local downloads
+ repository
+ """
+ highestURL = None
+ highestVersion = None
+
+ for filename, version in repo.getDownloads():
+ if not highestVersion or compareVersions(version, highestVersion) > 0:
+ highestURL = urlparse.urljoin(repo.downloadsURL, filename)
+ highestVersion = version
+
+ return (highestURL, highestVersion)
+
+def _getDownloadLink(repo):
+ """
+ gets the download link to the most current version of an extension
+ """
+ # you can't easily install extensions from third-party sources on Chrome
+ # and Opera. So always get the link for the version on the Web Store.
+ if repo.galleryID:
+ if repo.type == "chrome":
+ return _getGoogleDownloadLink(repo.galleryID)
+ if repo.type == "opera":
+ return _getOperaDownloadLink(repo.galleryID)
+
+ (localURL, localVersion) = _getLocalLink(repo)
+
+ # get a link to Firefox Add-Ons, if the latest version has been published there
+ if repo.type == 'gecko' and repo.galleryID:
+ (galleryURL, galleryVersion) = _getMozillaDownloadLink(repo.galleryID)
+ if not localVersion or (galleryVersion and
+ compareVersions(galleryVersion, localVersion) >= 0):
+ return (galleryURL, galleryVersion)
+
+ return (localURL, localVersion)
+
+def _getQRCode(text):
+ try:
+ import qrcode
+ import base64
+ import Image # required by qrcode but not formally a dependency
+ except:
+ return None
+
+ data = StringIO()
+ qrcode.make(text, box_size=5).save(data, 'png')
+ return 'data:image/png;base64,' + base64.b64encode(data.getvalue())
+
+def getDownloadLinks(result):
+ """
+ gets the download links for all extensions and puts them into the config
+ object
+ """
+ for repo in Configuration.getRepositoryConfigurations():
+ (downloadURL, version) = _getDownloadLink(repo)
+ if downloadURL == None:
+ continue
+ if not result.has_section(repo.repositoryName):
+ result.add_section(repo.repositoryName)
+ result.set(repo.repositoryName, "downloadURL", downloadURL)
+ result.set(repo.repositoryName, "version", version)
+
+ qrcode = _getQRCode(downloadURL)
+ if qrcode != None:
+ result.set(repo.repositoryName, "qrcode", qrcode)
« 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