def create_or_update_dev_mode(app_id, user_id, url, toolbar): UPDATE_SQL = """ UPDATE dashboard_developmentmode SET url = %s, toolbar = %s, date_updated = %s WHERE app_id = %s AND user_id = %s """ INSERT_SQL = """ INSERT INTO dashboard_developmentmode (app_id, user_id, url, toolbar, date_updated, date_created) VALUES (%s, %s, %s, %s, %s, %s) """ now = utils.get_now() try: db.execute(INSERT_SQL, [app_id, user_id, url, toolbar, now, now]) except psycopg2.IntegrityError: db.execute(UPDATE_SQL, [url, toolbar, now, app_id, user_id])
def _get_conf(app, app_version, device): dev = None if device: now = utils.get_now() date_updated = now - datetime.timedelta(minutes=6) dev = db.get_dev_mode(app['id'], device['user_id'], date_updated) user_conf = _get_user_conf(app, app_version) timestamps = [] for key, value in user_conf.items(): if isinstance(value, datetime.datetime): user_conf[key] = utils.datetime_to_timestamp(value) timestamps.append(key) return dict(user_conf, **{ '_version': app_version, '_url': dev.get('url') if dev else 'http://127.0.0.1:41675/', '_dev': bool(dev), '_toolbar': dev.get('toolbar') if dev else False, '_timestamps': timestamps, })
def _get_conf(app, app_version, device): dev = None if device: now = utils.get_now() date_updated = now - datetime.timedelta(minutes=6) dev = db.get_dev_mode(app['id'], device['user_id'], date_updated) user_conf = _get_user_conf(app, app_version) timestamps = [] for key, value in user_conf.items(): if isinstance(value, datetime.datetime): user_conf[key] = utils.datetime_to_timestamp(value) timestamps.append(key) return dict( user_conf, **{ '_version': app_version, '_url': dev.get('url') if dev else 'http://127.0.0.1:41675/', '_dev': bool(dev), '_toolbar': dev.get('toolbar') if dev else False, '_timestamps': timestamps, })
def add_bulk_ab_logs(udid, api_version, app_version, bundle_version, app_key, platform, logs): """ Adds bulk ab testing logs to the database. """ LOG_INSERT_SQL = """ INSERT INTO ab_log ( timestamp, action, data, udid, api_version, app_version, bundle_version, app_key, uuid, platform ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s) """ UNIQUE_INSERT_SQL = """ INSERT INTO ab_uniquemonth (uuid, app_id, udid, month, date_created) VALUES (%s, %s, %s, %s, %s) """ EXP_INSERT_SQL = """ INSERT INTO ab_experiment (app_id, name, slug, has_data, num_choices, enabled, date_created) VALUES (%s, %s, %s, %s, %s, %s, %s) """ EXP_UPDATE_SQL = """ UPDATE ab_experiment SET num_choices = %s WHERE id = %s """ VARIATION_INSERT_SQL = """ INSERT INTO ab_variation (experiment_id, weight, num, name, data, date_created) VALUES (%s, %s, %s, %s, %s, %s) """ TRIAL_INSERT_SQL = """ INSERT INTO ab_trial (uuid, udid, app_id, experiment_id, date_created, date_started, date_completed, choice, goal_reached) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s) """ TRIAL_UPDATE_SQL = """ UPDATE ab_trial SET date_completed = %s, goal_reached = %s WHERE udid = %s AND experiment_id = %s """ app = get_app_from_key(app_key) if not app: return app_id = app['id'] now = utils.get_now() def insert_ab_log(log): try: data = log['data'] except KeyError: # TODO: Log error somewhere? return try: db.execute(LOG_INSERT_SQL, [ log['ts'], data['action'], simplejson.dumps(log['data']), udid, api_version, app_version, bundle_version, app_key, log['uuid'], platform, ]) except psycopg2.IntegrityError: return ts = datetime.datetime.utcfromtimestamp(log['ts']).replace( tzinfo=pytz.utc) month = ts.replace(day=1, hour=0, minute=0, second=0, microsecond=0) try: db.execute(UNIQUE_INSERT_SQL, [str(uuid.uuid1()), app_id, udid, month, now]) except psycopg2.IntegrityError: pass # Don't care about disappearing in aggregate yet if data['action'] == 'failure': return experiment = get_experiment(app_id, data['name']) if experiment is None: if 'has_data' not in data: return db.execute(EXP_INSERT_SQL, [ app_id, 'Experiment for ' + data['name'], data['name'], data['has_data'], 0, True, now, ]) experiment = get_experiment(app_id, data['name']) if 'num_choices' in data: if data['num_choices'] != experiment['num_choices']: # First update the experiment object db.execute(EXP_UPDATE_SQL, [data['num_choices'], experiment['id']]) # Now create any un-created variation objects for i in xrange(data['num_choices']): try: name = 'Test ' + ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'[i]) db.execute(VARIATION_INSERT_SQL, [ experiment['id'], 0.5 / data['num_choices'], i + 1, name, '{\n}' if experiment['has_data'] else '', now, ]) except psycopg2.IntegrityError: pass # If it's one of the 'num-choices' actions, we've done that # already so we can continue on. if data['action'] == 'num-choices': return if data['action'] == 'test': try: dt = datetime.datetime.utcfromtimestamp(log['ts']).replace( tzinfo=pytz.utc) db.execute(TRIAL_INSERT_SQL, [ str(uuid.uuid1()), udid, app_id, experiment['id'], now, dt, None, data['choice'], False, ]) except psycopg2.IntegrityError: # What is the expected behavior here? If a trial is # already started for this user, then do we discard the old # one, or do we start a new one with a new timestamp and # choice? Do we update the started timestamp on the # current one? Not sure. For now we just continue and do # nothing. pass return if data['action'] == 'goal': dt = datetime.datetime.utcfromtimestamp(log['ts']).replace( tzinfo=pytz.utc) db.execute(TRIAL_UPDATE_SQL, [ dt, True, udid, experiment['id'], ]) for log in logs: insert_ab_log(log)
def add_bulk_ab_logs(udid, api_version, app_version, bundle_version, app_key, platform, logs): """ Adds bulk ab testing logs to the database. """ LOG_INSERT_SQL = """ INSERT INTO ab_log ( timestamp, action, data, udid, api_version, app_version, bundle_version, app_key, uuid, platform ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s) """ UNIQUE_INSERT_SQL = """ INSERT INTO ab_uniquemonth (uuid, app_id, udid, month, date_created) VALUES (%s, %s, %s, %s, %s) """ EXP_INSERT_SQL = """ INSERT INTO ab_experiment (app_id, name, slug, has_data, num_choices, enabled, date_created) VALUES (%s, %s, %s, %s, %s, %s, %s) """ EXP_UPDATE_SQL = """ UPDATE ab_experiment SET num_choices = %s WHERE id = %s """ VARIATION_INSERT_SQL = """ INSERT INTO ab_variation (experiment_id, weight, num, name, data, date_created) VALUES (%s, %s, %s, %s, %s, %s) """ TRIAL_INSERT_SQL = """ INSERT INTO ab_trial (uuid, udid, app_id, experiment_id, date_created, date_started, date_completed, choice, goal_reached) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s) """ TRIAL_UPDATE_SQL = """ UPDATE ab_trial SET date_completed = %s, goal_reached = %s WHERE udid = %s AND experiment_id = %s """ app = get_app_from_key(app_key) if not app: return app_id = app['id'] now = utils.get_now() def insert_ab_log(log): try: data = log['data'] except KeyError: # TODO: Log error somewhere? return try: db.execute(LOG_INSERT_SQL, [ log['ts'], data['action'], simplejson.dumps(log['data']), udid, api_version, app_version, bundle_version, app_key, log['uuid'], platform, ]) except psycopg2.IntegrityError: return ts = datetime.datetime.utcfromtimestamp( log['ts']).replace(tzinfo=pytz.utc) month = ts.replace(day=1, hour=0, minute=0, second=0, microsecond=0) try: db.execute(UNIQUE_INSERT_SQL, [str(uuid.uuid1()), app_id, udid, month, now]) except psycopg2.IntegrityError: pass # Don't care about disappearing in aggregate yet if data['action'] == 'failure': return experiment = get_experiment(app_id, data['name']) if experiment is None: if 'has_data' not in data: return db.execute(EXP_INSERT_SQL, [ app_id, 'Experiment for ' + data['name'], data['name'], data['has_data'], 0, True, now, ]) experiment = get_experiment(app_id, data['name']) if 'num_choices' in data: if data['num_choices'] != experiment['num_choices']: # First update the experiment object db.execute(EXP_UPDATE_SQL, [data['num_choices'], experiment['id']]) # Now create any un-created variation objects for i in xrange(data['num_choices']): try: name = 'Test ' + ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'[i], ) db.execute(VARIATION_INSERT_SQL, [ experiment['id'], 0.5 / data['num_choices'], i + 1, name, '{\n}' if experiment['has_data'] else '', now, ]) except psycopg2.IntegrityError: pass # If it's one of the 'num-choices' actions, we've done that # already so we can continue on. if data['action'] == 'num-choices': return if data['action'] == 'test': try: dt = datetime.datetime.utcfromtimestamp( log['ts']).replace(tzinfo=pytz.utc) db.execute(TRIAL_INSERT_SQL, [ str(uuid.uuid1()), udid, app_id, experiment['id'], now, dt, None, data['choice'], False, ]) except psycopg2.IntegrityError: # What is the expected behavior here? If a trial is # already started for this user, then do we discard the old # one, or do we start a new one with a new timestamp and # choice? Do we update the started timestamp on the # current one? Not sure. For now we just continue and do # nothing. pass return if data['action'] == 'goal': dt = datetime.datetime.utcfromtimestamp( log['ts']).replace(tzinfo=pytz.utc) db.execute(TRIAL_UPDATE_SQL, [ dt, True, udid, experiment['id'], ]) for log in logs: insert_ab_log(log)