# -*- 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'})