Index: sitescripts/extensions/bin/updateDownloadLinks.py |
=================================================================== |
--- a/sitescripts/extensions/bin/updateDownloadLinks.py |
+++ b/sitescripts/extensions/bin/updateDownloadLinks.py |
@@ -29,6 +29,8 @@ |
from StringIO import StringIO |
from sitescripts.utils import get_config, get_template |
from sitescripts.extensions.utils import compareVersions, Configuration, getSafariCertificateID |
+from sitescripts.extensions.android import get_min_sdk_version |
+from sitescripts.extensions.pad import PadFile |
from buildtools.packagerGecko import KNOWN_APPS |
def urlencode(value): |
@@ -66,84 +68,78 @@ |
""" |
gets download link for a Chrome add-on from the Chrome Gallery site |
""" |
- param = 'id=%s&uc' % urlencode(galleryID) |
- url = 'https://clients2.google.com/service/update2/crx?x=%s' % urlencode(param) |
- contents = urlopen(url).read() |
- document = dom.parseString(contents) |
+ galleryID = urlencode(galleryID) |
+ |
+ url = 'https://clients2.google.com/service/update2/crx?x=' |
+ url += urlencode('id=%s&uc' % galleryID) |
+ document = dom.parse(urlopen(url)) |
updateTags = document.getElementsByTagName('updatecheck') |
- updateTag = updateTags[0] if len(updateTags) > 0 else None |
- if updateTag and updateTag.hasAttribute('codebase') and updateTag.hasAttribute('version'): |
- return (updateTag.getAttribute('codebase'), updateTag.getAttribute('version')) |
- else: |
+ 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 |
""" |
- class HeadRequest(urllib2.Request): |
- def get_method(self): |
- return "HEAD" |
+ galleryID = urlencode(galleryID) |
- url = 'https://addons.opera.com/extensions/download/%s/' % urlencode(galleryID) |
- response = urllib2.urlopen(HeadRequest(url)) |
- content_disposition = response.info().dict.get('content-disposition', None) |
- if content_disposition != None: |
- match = re.search(r'filename=\S+-([\d.]+)-\d+\.oex$', content_disposition) |
- else: |
- match = None; |
- if match: |
- return (url, match.group(1)) |
- else: |
- return (None, None) |
+ 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 |
""" |
- url = repo.downloadsURL |
- |
highestURL = None |
highestVersion = None |
- if repo.type in ('gecko', 'chrome', 'opera', 'safari'): |
- prefix = readRawMetadata(repo).get('general', 'basename') |
- else: |
- prefix = os.path.basename(repo.repository) |
- prefix += '-' |
- suffix = repo.packageSuffix |
+ for filename, version in repo.getDownloads(): |
+ if not highestVersion or compareVersions(version, highestVersion) > 0: |
+ highestURL = urlparse.urljoin(repo.downloadsURL, filename) |
+ highestVersion = version |
- # go through the downloads repository looking for downloads matching this extension |
- command = ['hg', 'locate', '-R', repo.downloadsRepo, '-r', 'default'] |
- result = subprocess.check_output(command) |
- for fileName in result.splitlines(): |
- if fileName.startswith(prefix) and fileName.endswith(suffix): |
- version = fileName[len(prefix):len(fileName) - len(suffix)] |
- if highestVersion == None or compareVersions(version, highestVersion) > 0: |
- highestURL = urlparse.urljoin(url, fileName) |
- highestVersion = version |
return (highestURL, highestVersion) |
def getDownloadLink(repo): |
""" |
gets the download link to the most current version of an extension |
""" |
- galleryURL = None |
- galleryVersion = None |
- if repo.type == "gecko" and repo.galleryID: |
+ # 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) |
- elif repo.type == "chrome" and repo.galleryID: |
- (galleryURL, galleryVersion) = getGoogleDownloadLink(repo.galleryID) |
- elif repo.type == "opera" and repo.galleryID: |
- (galleryURL, galleryVersion) = getOperaDownloadLink(repo.galleryID) |
+ if not localVersion or (galleryVersion and |
+ compareVersions(galleryVersion, localVersion) >= 0): |
+ return (galleryURL, galleryVersion) |
- (downloadsURL, downloadsVersion) = getLocalLink(repo) |
- if galleryVersion == None or (downloadsVersion != None and |
- compareVersions(galleryVersion, downloadsVersion) < 0): |
- return (downloadsURL, downloadsVersion) |
- else: |
- return (galleryURL, galleryVersion) |
+ return (localURL, localVersion) |
def getQRCode(text): |
try: |
@@ -175,23 +171,6 @@ |
if qrcode != None: |
result.set(repo.repositoryName, "qrcode", qrcode) |
-def readRawMetadata(repo, version='tip'): |
- files = subprocess.check_output(['hg', '-R', repo.repository, 'locate', '-r', version]).splitlines() |
- genericFilename = 'metadata' |
- filename = '%s.%s' % (genericFilename, repo.type) |
- |
- # Fall back to platform-independent metadata file |
- if filename not in files: |
- filename = genericFilename |
- |
- command = ['hg', '-R', repo.repository, 'cat', '-r', version, os.path.join(repo.repository, filename)] |
- result = subprocess.check_output(command) |
- |
- parser = SafeConfigParser() |
- parser.readfp(StringIO(result)) |
- |
- return parser |
- |
def readMetadata(repo, version): |
""" |
reads extension ID and compatibility information from metadata file in the |
@@ -202,17 +181,12 @@ |
result = subprocess.check_output(command) |
revision = re.sub(r'\D', '', result) |
- command = ['hg', '-R', repo.repository, 'cat', '-r', version, os.path.join(repo.repository, 'AndroidManifest.xml')] |
- result = subprocess.check_output(command) |
- manifest = dom.parseString(result) |
- usesSdk = manifest.getElementsByTagName('uses-sdk')[0] |
- |
return { |
'revision': revision, |
- 'minSdkVersion': usesSdk.attributes["android:minSdkVersion"].value, |
+ 'minSdkVersion': get_min_sdk_version(repo, version), |
} |
elif repo.type == 'safari': |
- metadata = readRawMetadata(repo, version) |
+ metadata = repo.readMetadata(version) |
return { |
'certificateID': getSafariCertificateID(repo.keyFile), |
'version': version, |
@@ -220,7 +194,7 @@ |
'basename': metadata.get('general', 'basename'), |
} |
elif repo.type == 'gecko': |
- metadata = readRawMetadata(repo, version) |
+ metadata = repo.readMetadata(version) |
result = { |
'extensionID': metadata.get('general', 'id'), |
'version': version, |
@@ -257,6 +231,12 @@ |
template = get_template(get_config().get('extensions', '%sUpdateManifest' % repoType)) |
template.stream({'extensions': extensions[repoType]}).dump(manifestPath) |
+def writePadFile(links): |
+ for repo in Configuration.getRepositoryConfigurations(): |
+ if repo.padTemplate and links.has_section(repo.repositoryName): |
+ PadFile.forRepository(repo, links.get(repo.repositoryName, 'version'), |
+ links.get(repo.repositoryName, 'downloadURL')).write() |
+ |
def updateLinks(): |
""" |
writes the current extension download links to a file |
@@ -270,6 +250,7 @@ |
file.close() |
writeUpdateManifest(result) |
+ writePadFile(result) |
if __name__ == "__main__": |
updateLinks() |