100 lines
3.5 KiB
Python
100 lines
3.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
import base64
|
|
import os
|
|
import re
|
|
import gzip
|
|
import tarfile
|
|
from gluon.contrib.simplejsonrpc import ServerProxy
|
|
from gluon._compat import StringIO, ProtocolError, urlencode, urllib2
|
|
|
|
def deploy():
|
|
response.title = T('Deploy to pythonanywhere')
|
|
return {}
|
|
|
|
|
|
def create_account():
|
|
""" Create a PythonAnywhere account """
|
|
if not request.vars:
|
|
raise HTTP(400)
|
|
|
|
if request.vars.username and request.vars.web2py_admin_password:
|
|
# Check if web2py is already there otherwise we get an error 500 too.
|
|
client = ServerProxy('https://%(username)s:%(web2py_admin_password)s@%(username)s.pythonanywhere.com/admin/webservices/call/jsonrpc' % request.vars)
|
|
try:
|
|
if client.login() is True:
|
|
return response.json({'status': 'ok'})
|
|
except ProtocolError as error:
|
|
pass
|
|
|
|
url = 'https://www.pythonanywhere.com/api/web2py/create_account'
|
|
data = urlencode(request.vars)
|
|
req = urllib2.Request(url, data)
|
|
|
|
try:
|
|
reply = urllib2.urlopen(req)
|
|
except urllib2.HTTPError as error:
|
|
if error.code == 400:
|
|
reply = error
|
|
elif error.code == 500:
|
|
return response.json({'status':'error', 'errors':{'username': ['An App other than web2py is installed in the domain %(username)s.pythonanywhere.com' % request.vars]}})
|
|
else:
|
|
raise
|
|
response.headers['Content-Type'] = 'application/json'
|
|
return reply.read()
|
|
|
|
|
|
def list_apps():
|
|
""" Get a list of apps both remote and local """
|
|
if not request.vars.username or not request.vars.password:
|
|
raise HTTP(400)
|
|
client = ServerProxy('https://%(username)s:%(password)s@%(username)s.pythonanywhere.com/admin/webservices/call/jsonrpc' % request.vars)
|
|
regex = re.compile('^\w+$')
|
|
local = [f for f in os.listdir(apath(r=request)) if regex.match(f)]
|
|
try:
|
|
pythonanywhere = client.list_apps()
|
|
except ProtocolError as error:
|
|
raise HTTP(error.errcode)
|
|
return response.json({'local': local, 'pythonanywhere': pythonanywhere})
|
|
|
|
|
|
def bulk_install():
|
|
""" Install a list of apps """
|
|
|
|
def b64pack(app):
|
|
"""
|
|
Given an app's name, return the base64 representation of its packed version.
|
|
"""
|
|
folder = apath(app, r=request)
|
|
tmpfile = StringIO()
|
|
tar = tarfile.TarFile(fileobj=tmpfile, mode='w')
|
|
try:
|
|
filenames = listdir(folder, '^[\w\.\-]+$', add_dirs=True,
|
|
exclude_content_from=['cache', 'sessions', 'errors'])
|
|
for fname in filenames:
|
|
tar.add(os.path.join(folder, fname), fname, False)
|
|
finally:
|
|
tar.close()
|
|
tmpfile.seek(0)
|
|
gzfile = StringIO()
|
|
w2pfp = gzip.GzipFile(fileobj=gzfile, mode='wb')
|
|
w2pfp.write(tmpfile.read())
|
|
w2pfp.close()
|
|
gzfile.seek(0)
|
|
return base64.b64encode(gzfile.read())
|
|
|
|
request.vars.apps = request.vars['apps[]']
|
|
if not request.vars.apps or not request.vars.username or not request.vars.password:
|
|
raise HTTP(400)
|
|
if not isinstance(request.vars.apps, list):
|
|
request.vars.apps = [request.vars.apps] # Only one app selected
|
|
|
|
client = ServerProxy('https://%(username)s:%(password)s@%(username)s.pythonanywhere.com/admin/webservices/call/jsonrpc' % request.vars)
|
|
|
|
for app in request.vars.apps:
|
|
try:
|
|
client.install(app, app+'.w2p', b64pack(app))
|
|
except ProtocolError as error:
|
|
raise HTTP(error.errcode)
|
|
|
|
return response.json({'status': 'ok'})
|