Exemple #1
0
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)})
Exemple #2
0
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)})
Exemple #3
0
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',
    })
Exemple #4
0
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',
    })
Exemple #5
0
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',
    })
Exemple #6
0
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),
    })
Exemple #7
0
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',
    })
Exemple #8
0
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),
        })
Exemple #9
0
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))
Exemple #10
0
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))
Exemple #11
0
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})
Exemple #12
0
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})
Exemple #13
0
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})