def handle_rpc(env, start_response): try: content_length = int(env.get('CONTENT_LENGTH', 0)) except (ValueError, TypeError): content_length = 0 if content_length: raw_data = env['wsgi.input'].read(content_length) else: raw_data = env['wsgi.input'].read() request_json = simplejson.loads(raw_data) request_json.update({ '_app_key': env.get('HTTP_X_APP_KEY'), '_udid': env.get('HTTP_X_UDID'), '_api_version': env.get('HTTP_X_API_VERSION'), '_app_version': env.get('HTTP_X_APP_VERSION'), '_bundle_version': env.get('HTTP_X_BUNDLE_VERSION'), '_clutch_username': env.get('HTTP_X_CLUTCH_USERNAME'), '_clutch_password': env.get('HTTP_X_CLUTCH_PASSWORD'), '_platform': env.get('HTTP_X_PLATFORM', 'iOS'), }) method = request_json.get('method') if not method: return utils.jsonrpc_error(request_json, 1, {'method': method}) func = METHODS.get(method) if func is None: return utils.jsonrpc_error(request_json, 12, {'method': method}) print method, raw_data[:100] try: return func(request_json, **(request_json.get('params') or {})) except Exception, e: utils.exception_printer(None) return utils.jsonrpc_error(request_json, 3, {'detail': str(e)})
def stop_dev(request_json, app_slug=None): user = db.get_user_from_creds(request_json.get('_clutch_username'), request_json.get('_clutch_password')) if not user: return utils.jsonrpc_error(request_json, 10) app = db.get_app_from_user_and_slug(user['id'], app_slug) if not app: return utils.jsonrpc_error({}, 9, {'app_slug': app_slug}) db.delete_dev_modes_for_user_and_app(user['id'], app['id']) return utils.jsonrpc_response(request_json, { 'development': 'inactive', })
def stop_dev(request_json, app_slug=None): user = db.get_user_from_creds( request_json.get('_clutch_username'), request_json.get('_clutch_password') ) if not user: return utils.jsonrpc_error(request_json, 10) app = db.get_app_from_user_and_slug(user['id'], app_slug) if not app: return utils.jsonrpc_error({}, 9, {'app_slug': app_slug}) db.delete_dev_modes_for_user_and_app(user['id'], app['id']) return utils.jsonrpc_response(request_json, { 'development': 'inactive', })
def start_dev(request_json, app_slug=None, url=None, toolbar=None): user = db.get_user_from_creds(request_json.get('_clutch_username'), request_json.get('_clutch_password')) if not user: return utils.jsonrpc_error(request_json, 10) app = db.get_app_from_user_and_slug(user['id'], app_slug) if not app: return utils.jsonrpc_error({}, 9, {'app_slug': app_slug}) if toolbar is None: toolbar = True db.create_or_update_dev_mode(app['id'], user['id'], url, toolbar) return utils.jsonrpc_response(request_json, { 'development': 'active', })
def sync(request_json): app = db.get_app_from_key(request_json['_app_key']) if not app: data = {'app_key': request_json['_app_key']} return utils.jsonrpc_error(request_json, 8, data) app_version = db.get_app_version_for_bundle_version(app['id'], request_json['_bundle_version']) # If the app is over the limit and they're not a first-time customer, then # we return an error instead of the updated file list. if request_json['_app_version'] != '-1' and not app['enabled']: return utils.jsonrpc_error(request_json, 15, {}) device = db.get_device_for_udid_and_app(request_json['_udid'], app['id']) return utils.jsonrpc_response(request_json, { 'files': _get_file_list(app, app_version), 'conf': _get_conf(app, app_version, device), })
def start_dev(request_json, app_slug=None, url=None, toolbar=None): user = db.get_user_from_creds( request_json.get('_clutch_username'), request_json.get('_clutch_password') ) if not user: return utils.jsonrpc_error(request_json, 10) app = db.get_app_from_user_and_slug(user['id'], app_slug) if not app: return utils.jsonrpc_error({}, 9, {'app_slug': app_slug}) if toolbar is None: toolbar = True db.create_or_update_dev_mode(app['id'], user['id'], url, toolbar) return utils.jsonrpc_response(request_json, { 'development': 'active', })
def sync(request_json): app = db.get_app_from_key(request_json['_app_key']) if not app: data = {'app_key': request_json['_app_key']} return utils.jsonrpc_error(request_json, 8, data) app_version = db.get_app_version_for_bundle_version( app['id'], request_json['_bundle_version']) # If the app is over the limit and they're not a first-time customer, then # we return an error instead of the updated file list. if request_json['_app_version'] != '-1' and not app['enabled']: return utils.jsonrpc_error(request_json, 15, {}) device = db.get_device_for_udid_and_app(request_json['_udid'], app['id']) return utils.jsonrpc_response( request_json, { 'files': _get_file_list(app, app_version), 'conf': _get_conf(app, app_version, device), })
def get_file(request_json, filename=None): app = db.get_app_from_key(request_json['_app_key']) if not app: data = {'app_key': request_json['_app_key']} return utils.jsonrpc_error(request_json, 8, data) conn = S3Connection(settings.AWS_ACCESS_KEY, settings.AWS_ACCESS_SECRET) bucket = conn.get_bucket(settings.AWS_BUCKET_NAME, validate=False) key = Key(bucket, '%s/%s/files/%s' % ( app['slug'], request_json['_app_version'], filename, )) if key is None: return utils.jsonrpc_error(request_json, 4, {'filename': filename}, code=404) if request_json['_platform'] == 'Android': return utils.jsonrpc_response(request_json, {'url': key.generate_url(120)}) else: return utils.redirect(key.generate_url(120))
def get_file(request_json, filename=None): app = db.get_app_from_key(request_json['_app_key']) if not app: data = {'app_key': request_json['_app_key']} return utils.jsonrpc_error(request_json, 8, data) conn = S3Connection(settings.AWS_ACCESS_KEY, settings.AWS_ACCESS_SECRET) bucket = conn.get_bucket(settings.AWS_BUCKET_NAME, validate=False) key = Key( bucket, '%s/%s/files/%s' % ( app['slug'], request_json['_app_version'], filename, )) if key is None: return utils.jsonrpc_error(request_json, 4, {'filename': filename}, code=404) if request_json['_platform'] == 'Android': return utils.jsonrpc_response(request_json, {'url': key.generate_url(120)}) else: return utils.redirect(key.generate_url(120))
def get_ab_metadata(request_json, guid): app = db.get_app_from_key(request_json['_app_key']) if app is None: data = {'app_key': request_json['_app_key']} return utils.jsonrpc_error(request_json, 8, data) experiments = dict(((e['id'], e) for e in db.get_experiments_for_app(app['id']))) variations = db.get_variations_for_app(app['id']) metadata = {} for variation in variations: experiment = experiments[variation['experiment_id']] metadata.setdefault(experiment['slug'], {}) metadata[experiment['slug']].setdefault('weights', []) metadata[experiment['slug']]['weights'].append(variation['weight']) if experiment['has_data']: metadata[experiment['slug']].setdefault('data', []) metadata[experiment['slug']]['data'].append( simplejson.loads(variation['data'])) return utils.jsonrpc_response(request_json, {'metadata': metadata})
def handle_upload(env, start_response): form = cgi.FieldStorage(fp=env['wsgi.input'], environ=env) if 'archive' not in form: return utils.jsonrpc_error({}, 4) app_slug = env.get('HTTP_X_APP_SLUG') if not app_slug: return utils.jsonrpc_error({}, 7) user = db.get_user_from_creds( env.get('HTTP_X_CLUTCH_USERNAME'), env.get('HTTP_X_CLUTCH_PASSWORD'), ) if not user: return utils.jsonrpc_error({}, 10) app = db.get_app_from_user_and_slug(user['id'], app_slug) if not app: return utils.jsonrpc_error({}, 9, {'app_slug': app_slug}) app_version = db.get_latest_app_version(app['id']) if app_version is None: app_version = 1 else: app_version += 1 tmp = StringIO(form['archive'].file.read()) extracted = tempfile.mkdtemp() zip_context = contextlib.closing( zipfile.ZipFile(tmp, 'r', zipfile.ZIP_DEFLATED)) with zip_context as z: namelist = z.namelist() for name in namelist: if name.startswith('..'): return utils.jsonrpc_error({}, 6, {'name': name}) if name.startswith('/'): return utils.jsonrpc_error({}, 6, {'name': name}) z.extractall(extracted) # Get rid of the StringIO for memory savings del tmp # Now we upload that to S3 conn = S3Connection(settings.AWS_ACCESS_KEY, settings.AWS_ACCESS_SECRET) bucket = conn.get_bucket(settings.AWS_BUCKET_NAME) for name in namelist: upload_fn = '%s/%s/files/%s' % (app_slug, app_version, name) key = bucket.new_key(upload_fn) key.set_contents_from_filename(os.path.join(extracted, name)) # Generate an md5 hash of each file in the upload hashes = {} for name in namelist: with open(os.path.join(extracted, name), 'r') as f: hashes[name] = hashlib.md5(f.read()).hexdigest() # JSON-encode the md5 hashes and upload them to s3 manifest = simplejson.dumps(hashes) manifest_key = '%s/%s/meta/manifest.json' % (app_slug, app_version) key = bucket.new_key(manifest_key) key.set_contents_from_string(manifest) # Delete the temporary directory shutil.rmtree(extracted) db.create_app_version(app['id'], app_version) return utils.jsonrpc_response({}, {'version': app_version})