Skip to content

Commit a64e094

Browse files
Lance LinderLance Linder
Lance Linder
authored and
Lance Linder
committed
Fixed version discovery and download logic
This resolves issue #1
1 parent 6b2ab86 commit a64e094

File tree

6 files changed

+110
-100
lines changed

6 files changed

+110
-100
lines changed

.gitignore

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
*.pyo
33
*.swp
44
env
5-
/TODO
6-
/build/
7-
/dist/
8-
/*.egg-info/
5+
TODO
6+
build/
7+
dist/
8+
*.egg-info/

gaeenv/sdk.py

+35-25
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import shutil
44
import requests
55
import re
6+
import xml.etree.ElementTree as ET
67

78
from tempfile import gettempdir
89
from utils import logger, writefile
@@ -48,47 +49,56 @@ def download(version=None):
4849
Download App Engine SDK
4950
"""
5051
if not version:
51-
lvt = get_latest_version()
52-
version = '{0}.{1}.{2}'.format(*lvt)
52+
version = get_latest_version()
5353

54-
gae_url = 'http://googleappengine.googlecode.com/files/google_appengine_{0}.zip'.format(version)
54+
response = requests.get('https://storage.googleapis.com/appengine-sdks')
55+
response.raise_for_status()
56+
tree = ET.fromstring(response.text)
57+
58+
path = None
59+
for key in tree.iter('{http://doc.s3.amazonaws.com/2006-03-01}Key'):
60+
match = re.match('^.*google_appengine_{0}.{1}.{2}\.zip$'.format(*version), key.text)
61+
if match:
62+
path = key.text
63+
break
5564

56-
logger.debug(' * Starting SDK download for version %s' % version)
57-
response = requests.get(gae_url)
65+
url = 'https://storage.googleapis.com/appengine-sdks/{path}'.format(**locals())
66+
67+
logger.debug(' * Starting SDK download for version {0}.{1}.{2}'.format(*version))
68+
response = requests.get(url)
5869
response.raise_for_status()
5970

60-
temp_dir = gettempdir()
61-
temp_zip = os.path.join(temp_dir, 'google_appengine_%s.zip' % version)
71+
temp_zip = os.path.join(gettempdir(), 'google_appengine_{0}.{1}.{2}.zip'.format(*version))
6272
writefile(temp_zip, response.content, encode=None)
6373
return temp_zip
6474

6575
def get_versions():
6676
"""
6777
Retrieves all available App Engine SDK get_versions
6878
"""
69-
response = requests.get('https://code.google.com/p/googleappengine/downloads/list?can=1&q=&colspec=Filename&num=2000')
79+
versions = []
80+
response = requests.get('https://storage.googleapis.com/appengine-sdks')
7081
response.raise_for_status()
7182

72-
versions = []
73-
for match in re.finditer(r'google_appengine_([0-9]+)\.([0-9]+)\.([0-9]+)\.zip', response.text):
74-
versions.append((match.group(1),match.group(2),match.group(3)))
83+
tree = ET.fromstring(response.text)
84+
85+
for key in tree.iter('{http://doc.s3.amazonaws.com/2006-03-01}Key'):
86+
match = re.match(r'^.*google_appengine_([0-9]+)\.([0-9]+)\.([0-9]+)\.zip$', key.text)
87+
if match:
88+
versions.append((
89+
int(match.group(1)),
90+
int(match.group(2)),
91+
int(match.group(3))
92+
))
7593

76-
return sorted(set(versions), key=lambda tup: str(tup), reverse=True)
94+
def compare(x, y):
95+
return sum(y) - sum(x)
96+
97+
return sorted(versions, cmp=compare)
7798

78-
__latest_version = None
7999
def get_latest_version():
80100
"""
81101
Retrieves the latest App Engine SDK version
82102
"""
83-
global __latest_version
84-
if not __latest_version:
85-
response = requests.get('https://code.google.com/p/googleappengine/downloads/list?can=2&q=&colspec=Filename')
86-
response.raise_for_status()
87-
88-
match = re.search(r'google_appengine_([0-9]+)\.([0-9]+)\.([0-9]+)\.zip', response.text)
89-
if match:
90-
__latest_version = (match.group(1),match.group(2),match.group(3))
91-
else:
92-
raise Exception('App Engine SDK version not found')
93-
94-
return __latest_version
103+
versions = get_versions()
104+
return versions[0]

gaeenv/utils.py

+18-20
Original file line numberDiff line numberDiff line change
@@ -20,38 +20,36 @@ def writefile(dest, content, overwrite=True, append=False, encode="utf-8"):
2020
"""
2121
if not os.path.exists(dest):
2222
logger.debug(' * Writing %s ... ', dest)
23-
f = open(dest, 'wb')
24-
if encode:
25-
f.write(content.encode(encode))
26-
else:
27-
f.write(content)
28-
f.close()
23+
with open(dest, 'wb') as f:
24+
if encode:
25+
f.write(content.encode(encode))
26+
else:
27+
f.write(content)
2928
logger.debug('done.')
3029
return
3130
else:
32-
f = open(dest, 'rb')
33-
c = f.read()
34-
f.close()
31+
c = None
32+
with open(dest, 'rb') as f:
33+
c = f.read()
34+
3535
if c != content:
3636
if not overwrite:
3737
logger.info(' * File %s exists with different content; '
3838
' not overwriting', dest)
3939
return
4040
if append:
4141
logger.info(' * Appending nodeenv settings to %s', dest)
42-
f = open(dest, 'a')
43-
f.write(DISABLE_POMPT.encode('utf-8'))
44-
f.write(content.encode('utf-8'))
45-
f.write(ENABLE_PROMPT.encode('utf-8'))
46-
f.close()
42+
with open(dest, 'a') as f:
43+
f.write(DISABLE_POMPT.encode('utf-8'))
44+
f.write(content.encode('utf-8'))
45+
f.write(ENABLE_PROMPT.encode('utf-8'))
4746
return
4847
logger.info(' * Overwriting %s with new content', dest)
49-
f = open(dest, 'wb')
50-
if encode:
51-
f.write(content.encode(encode))
52-
else:
53-
f.write(content)
54-
f.close()
48+
with open(dest, 'wb') as f:
49+
if encode:
50+
f.write(content.encode(encode))
51+
else:
52+
f.write(content)
5553
else:
5654
logger.debug(' * Content %s already in place', dest)
5755

gaeenv/virtualenv.py

+45-44
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import sys
33
import re
4+
import textwrap
45

56
from utils import logger
67

@@ -14,55 +15,55 @@ def add_gae_pth(env_dir):
1415
logger.error('Python site packages directory doesn\'t exist. Please ensure Virtualenv is activated.')
1516
else:
1617
with open(os.path.join(site_packages_dir, 'gae.pth'), 'wb') as file:
17-
file.write((
18-
'../../google_appengine\n'
19-
'import dev_appserver; dev_appserver.fix_sys_path()'))
18+
file.write(textwrap.dedent("""\
19+
../../google_appengine
20+
import dev_appserver; dev_appserver.fix_sys_path()"""))
2021

2122
logger.info(' * App Engine SDK path added to Python site packages')
2223

2324

2425
def add_gae_activation(env_dir):
25-
activate = (
26-
'# === GAEENV START ===\n'
27-
'\n'
28-
'deactivate_gae () {\n'
29-
' # reset old environment variables\n'
30-
' if [ -n "$_OLD_GAE_VIRTUAL_PATH" ] ; then\n'
31-
' PATH="$_OLD_GAE_VIRTUAL_PATH"\n'
32-
' export PATH\n'
33-
' unset _OLD_GAE_VIRTUAL_PATH\n'
34-
' fi\n'
35-
' if [ -n "$_OLD_GAE_SDK_ROOT" ] ; then\n'
36-
' GAE_SDK_ROOT="$_OLD_GAE_SDK_ROOT"\n'
37-
' export GAE_SDK_ROOT\n'
38-
' unset _OLD_GAE_SDK_ROOT\n'
39-
' fi\n'
40-
' \n'
41-
' # This should detect bash and zsh, which have a hash command that must\n'
42-
' # be called to get it to forget past commands. Without forgetting\n'
43-
' # past commands the $PATH changes we made may not be respected\n'
44-
' if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then\n'
45-
' hash -r\n'
46-
' fi\n'
47-
' \n'
48-
' if [ ! "$1" = "nondestructive" ] ; then\n'
49-
' # Self destruct!\n'
50-
' unset -f deactivate_gae\n'
51-
' fi\n'
52-
'}\n'
53-
'\n'
54-
'# unset irrelevant variables\n'
55-
'deactivate_gae nondestructive\n'
56-
'\n'
57-
'_OLD_GAE_SDK_ROOT="$GAE_SDK_ROOT"\n'
58-
'GAE_SDK_ROOT="$VIRTUAL_ENV/lib/google_appengine"\n'
59-
'export GAE_SDK_ROOT\n'
60-
'\n'
61-
'_OLD_GAE_VIRTUAL_PATH="$PATH"\n'
62-
'PATH=$GAE_SDK_ROOT:$PATH\n'
63-
'export PATH\n'
64-
'\n'
65-
'# === GAEENV END ===\n')
26+
activate = textwrap.dedent("""\
27+
# === GAEENV START ===
28+
29+
deactivate_gae () {
30+
# reset old environment variables
31+
if [ -n "$_OLD_GAE_VIRTUAL_PATH" ] ; then
32+
PATH="$_OLD_GAE_VIRTUAL_PATH"
33+
export PATH
34+
unset _OLD_GAE_VIRTUAL_PATH
35+
fi
36+
if [ -n "$_OLD_GAE_SDK_ROOT" ] ; then
37+
GAE_SDK_ROOT="$_OLD_GAE_SDK_ROOT"
38+
export GAE_SDK_ROOT
39+
unset _OLD_GAE_SDK_ROOT
40+
fi
41+
42+
# This should detect bash and zsh, which have a hash command that must
43+
# be called to get it to forget past commands. Without forgetting
44+
# past commands the $PATH changes we made may not be respected
45+
if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
46+
hash -r
47+
fi
48+
49+
if [ ! "$1" = "nondestructive" ] ; then
50+
# Self destruct!
51+
unset -f deactivate_gae
52+
fi
53+
}
54+
55+
# unset irrelevant variables
56+
deactivate_gae nondestructive
57+
58+
_OLD_GAE_SDK_ROOT="$GAE_SDK_ROOT"
59+
GAE_SDK_ROOT="$VIRTUAL_ENV/lib/google_appengine"
60+
export GAE_SDK_ROOT
61+
62+
_OLD_GAE_VIRTUAL_PATH="$PATH"
63+
PATH=$GAE_SDK_ROOT:$PATH
64+
export PATH
65+
66+
# === GAEENV END ===""")
6667

6768
activate_script = os.path.join(env_dir, 'bin', 'activate')
6869
if not os.path.exists(activate_script):

requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
requests>=2.2.0

setup.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
import os
88
from setuptools import setup, find_packages
99
from gaeenv.main import gaeenv_version
10+
from pip.req import parse_requirements
1011

1112
def read_file(file_name):
12-
return open(
13-
os.path.join(
14-
os.path.dirname(os.path.abspath(__file__)),
15-
file_name
16-
)
17-
).read()
13+
path = os.path.join(os.path.dirname(os.path.abspath(__file__)), file_name)
14+
with open(path) as f:
15+
return f.read()
16+
17+
required = read_file('requirements.txt').splitlines()
1818

1919
ldesc = read_file('README')
2020
ldesc += "\n\n" + read_file('CHANGES')
@@ -29,7 +29,7 @@ def read_file(file_name):
2929
description="Goole App Engine Virtualenv tools",
3030
long_description=ldesc,
3131
packages = find_packages(exclude="test"),
32-
install_requires = ['requests>=2.2.0'],
32+
install_requires = required,
3333
entry_points={
3434
'console_scripts': ['gaeenv = gaeenv.main:main']
3535
},

0 commit comments

Comments
 (0)