def item_add(): payload = request.get_json(force=True) token = Token.verify(payload['token']) token.record_script_version(payload.get('script_version')) print('Item {} submitted by {}'.format(payload['name'], token.character.name)) item = autovivify( Item, { 'token': token, 'name': payload['name'], 'slug': payload.get('slug'), 'mass_kg': float(payload['mass_kg']), 'tier': payload['tier'], 'rarity': autovivify(ItemRarity, dict(name=payload['rarity'])), 'item_type': autovivify(ItemType, dict(name=payload['type'])), 'description': payload.get('description'), }, update=True) item_aspect_armor(item, payload) item_aspect_medical(item, payload) item_aspect_food(item, payload) item_aspect_weapon(item, payload) db.session.commit() response = { 'id': item.id, 'recorded': True, 'message': '<a href="https://tracker.tauguide.de/item/detail/{}">this item on the tracker</a>' .format(item.id), } return jsonify(response)
def ship_add(): payload = request.get_json(force=True) token = Token.verify(payload['token']) token.record_script_version(payload.get('script_version')) station = get_station(payload['system'], payload['station']) count = 0 for ship_sighting in payload['ships']: ship_class = autovivify(ShipClass, {'name': ship_sighting['class']}) ship = autovivify( Ship, { 'registration': ship_sighting['registration'], 'ship_class': ship_class, 'name': ship_sighting['name'], 'captain': ship_sighting['captain'], }) if not ship.captain and ship_sighting['captain']: ship.captain = ship_sighting['captain'] db.session.add(ship) db.session.add(ShipSighting( ship=ship, station=station, token=token, )) count += 1 db.session.commit() print('Recorded {} ship positions on {} by {}'.format( count, station.name, token.character.name)) return jsonify({'success': True, 'num_recorded': count})
def add_item_comment(): payload = request.get_json(force=True) try: token = Token.verify(payload['token']) except InvalidTokenException: return jsonify({"success": False, "message": "invalid token."}) item = Item.query.filter_by(id=payload['item']).one() db.session.add( ItemComment(token=token, comment=payload['comment'], item=item)) db.session.commit() return jsonify({'success': True})
def insert(name): character = Character(name=name) db.session.add(character) try: token_str = sys.argv[2] except IndexError: token_str = random_token() token = Token(character=character, token=token_str) db.session.add(token) db.session.commit() print('{} - {}'.format(name, token_str))
def fuel_add(): payload = request.get_json(force=True) mandatory = set(('token', 'station', 'system', 'fuel_g', 'price')) missing_attrs = [a for a in mandatory if not payload.get(a)] if missing_attrs: message = 'Missing attributes: ' + ', '.join(missing_attrs) return jsonify({ 'recorded': False, 'missing': missing_attrs, message: message }) token_str = payload['token'] station_name = payload['station'] try: token = Token.verify(payload['token']) token.record_script_version(payload.get('script_version')) except InvalidTokenException: return jsonify({'recorded': False, 'message': 'Invalid token'}) station = get_station(payload['system'], station_name) price_per_g = payload['price'] / payload['fuel_g'] reading = FuelPriceReading( token=token, station=station, fuel_g=payload['fuel_g'], price=payload['price'], price_per_g=price_per_g, when=now(), ) db.session.add(reading) response = { 'recorded': True, 'systems': { station.system.name: { station.name: price_per_g } }, 'message': render_fuel_add_response(station, token_str), } print('Recorded fuel price {} for station {} by {}, {}'.format( price_per_g, station.name, token.character.name, datetime.now())) db.session.commit() return jsonify(response)
def fuel_estimation_add(): payload = request.get_json(force=True) token = Token.verify(payload['token']) stations = payload['stations'] date = today() print('Recording fuel price estimations for {} from {}, token {}'.format( date, token.character.name, token.id)) FuelPriceEstimation.query.filter_by(day=date).delete() for station_name, price in stations.items(): try: station = Station.query.filter_by(name=station_name).one() est = FuelPriceEstimation( station=station, day=date, price_per_g=price, ) db.session.add(est) except NoResultFound: print(' Found no station {}'.format(station_name)) db.session.commit() return jsonify({'recorded': True})
def export_fuel_estimation(): token = Token.verify(request.args.get('token')) date_string = request.args.get('date') if date_string is None: from datetime import date day = date.today() else: day = datetime.strptime(date_string, '%Y-%m-%d').date() rs = FuelPriceEstimation.query.filter_by(day=day).order_by( FuelPriceEstimation.station_id) result = { 'date': str(day), 'stations': { e.station.short: { 'name': e.station.name, 'estimated_fuel_price_per_g': e.price_per_g, } for e in rs } } return jsonify(result)
def add_vendory_inventory(): payload = request.get_json(force=True) token = Token.verify(payload['token']) token.record_script_version(payload.get('script_version')) messages = [] station = get_station(payload['system'], payload['station']) vendor_name = payload['vendor'] print('Vendor {} at {} submitted by {}'.format(vendor_name, station.short or station.id, token.character.name)) vendor = Vendor.query.filter_by(station_id=station.id, name=vendor_name).first() if not vendor: messages.append('Vendor created.') vendor = Vendor( station=station, name=vendor_name, ) db.session.add(vendor) slugs = {iv['slug'] for iv in payload['inventory']} - vendor_blacklist items = { item.slug: item for item in Item.query.filter(Item.slug.in_(sorted(slugs))) } missing = [slug for slug in slugs if not slug in items] if missing: return jsonify({ 'recorded': False, 'message': 'The Tracker does not know about the following item(s): ' + ', '.join([linkify(slug) for slug in missing]) }) new_timestamp = datetime.utcnow() day = today() # make sure the inventory is up-to-date latest_inventory = VendorInventory.query.filter_by(vendor_id=vendor.id, is_current=True) \ .order_by(VendorInventory.last_seen.desc()).first() has_current_inventory = False if latest_inventory: if latest_inventory.item_slugs == slugs: has_current_inventory = True # inventory still up to date latest_inventory.last_seen = new_timestamp messages.append('Updated inventory timestamp.') else: latest_inventory.is_current = False if not has_current_inventory: latest_inventory = VendorInventory( token=token, vendor=vendor, first_seen=new_timestamp, last_seen=new_timestamp, ) db.session.add(latest_inventory) for item in items.values(): db.session.add( VendorInventoryItem( vendor_inventory=latest_inventory, item=item, )) # check/update item prices def price_tuple(d): v = d['price'] return (float(v), None) if d['currency'] == 'credits' else (None, int(v)) existing_prices = { vipr.item.slug: vipr for vipr in VendorItemPriceReading.query.filter_by( vendor_inventory_id=latest_inventory.id, day=day) } prices_updated = False for d in payload['inventory']: slug = d['slug'] if slug in vendor_blacklist: continue credits, bonds = price_tuple(d) if slug in existing_prices: record = existing_prices[slug] if record.price_credits != credits or record.price_bonds != bonds: prices_updated = True record.price_credits = credits record.price_bonds = bonds record.token = token else: vipr = VendorItemPriceReading( token=token, vendor=vendor, vendor_inventory=latest_inventory, item=Item.query.filter_by(slug=slug).one(), day=day, price_credits=credits, price_bonds=bonds, ) db.session.add(vipr) prices_updated = True if prices_updated: messages.append('Price information recorded/updated.') db.session.commit() return jsonify({'recorded': True, 'message': ' '.join(messages)})
def career_task_add(): payload = request.get_json(force=True) mandatory = set(('token', 'station', 'system', 'career', 'rank', 'tasks')) missing_attrs = [a for a in mandatory if not payload.get(a)] if missing_attrs: message = 'Missing attributes: ' + ', '.join(missing_attrs) return jsonify({ 'recorded': False, 'missing': missing_attrs, message: message }) station_name = payload['station'] try: token = Token.verify(payload['token']) token.record_script_version(payload.get('script_version')) except InvalidTokenException: return jsonify({'recorded': False, 'message': 'Invalid token'}) if token is None: return jsonify({'recorded': False, 'message': 'Invalid token'}) if 'Confined to the' in station_name or 'Doing activity' in station_name: return jsonify({ 'recorded': False, 'message': '{} does not look like a valid station name'.format(station_name) }) station = get_station(payload['system'], station_name) batch = CareerBatchSubmission( token=token, character=token.character, station=station, career=payload['career'], rank=payload['rank'], ) db.session.add(batch) response = {'character': token.character.name} factors = [] for task, bonus in payload['tasks'].items(): bonus = float(bonus) career_task = CareerTask.query.filter_by(name=task).first() if career_task is None: career_task = CareerTask( name=task, career=payload['career'], bonus_baseline=bonus, ) db.session.add(career_task) elif career_task.bonus_baseline is None or career_task.bonus_baseline > bonus: career_task.bonus_baseline = bonus tr = CareerTaskReading( batch_submission=batch, career_task=career_task, bonus=bonus, ) db.session.add(tr) f = tr.factor factors.append(f) if f > 2.1: print( 'SUSPICIOUS READING of factor {}, station {}, task {}, token {}' .format( f, station_name, task, token.id, )) factor = max(factors) batch.factor = factor if factor: print('Recorded factor {} for station {}, {}'.format( factor, station.name, datetime.now())) response['recorded'] = True response['factor'] = factor # find factors for other stations in the system date_limit = today_datetime() stations = Station.query.filter_by(system_id=station.system_id) system_factors = {} cbs = CareerBatchSubmission for st in stations.all(): if st.name == station_name: continue qry = cbs.query.filter(cbs.when > date_limit).filter_by( station_id=st.id).order_by(cbs.when.desc()) bs = qry.first() if bs: factor = max(o.factor for o in bs.readings) system_factors[st.name] = factor if system_factors: response['system_factors'] = system_factors db.session.commit() return jsonify(response)
def add_distance(): payload = request.get_json(force=True) mandatory = set(('token', 'source', 'system', 'schedules')) missing_attrs = [a for a in mandatory if not payload.get(a)] if missing_attrs: message = 'Missing attributes: ' + ', '.join(missing_attrs) return jsonify({ 'recorded': False, 'missing': missing_attrs, message: message }) try: token = Token.verify(payload['token']) token.record_script_version(payload.get('script_version')) except InvalidTokenException: return jsonify({'recorded': False, 'message': 'Invalid token'}) station = get_station(payload['system'], payload['source']) count = 0 new = 0 price_count = 0 for schedule in payload['schedules']: distances = [t for t in schedule['distances'] if t[0] and t[1]] if not distances: continue destination = get_station(payload['system'], schedule['destination']) pair = get_station_pair(station, destination) first_price_ratio = None for d_tuple in distances: price = None travel_time = None departure, distance, *rest = d_tuple if len(rest): travel_time = rest[0] if len(rest) >= 2: price = rest[1] if not isinstance(distance, (int, float)): continue distance = int(distance) departure = parse_gct(departure) or departure if price is not None and first_price_ratio is None: if isinstance(price, str): price = price.replace(',', '') price = float(price) first_price_ratio = price / distance count += 1 existing = StationDistanceReading.query.filter_by( station_pair_id=pair.id, distance_km=distance, when=departure, ).first() if not existing: new += 1 if travel_time and re.search('[0-9]', travel_time): travel_time = int(re.sub(r'[^0-9]', '', travel_time)) else: travel_time = None sdr = StationDistanceReading( station_pair=pair, distance_km=distance, when=departure, travel_time_u=travel_time, token=token, ) db.session.add(sdr) if first_price_ratio is not None: price_count += 1 db.session.add( ShuttlePriceReading( source_station=station, destination_station=destination, price_per_distance=first_price_ratio, token=token, )) db.session.commit() print('Recorded {} distance pairs ({} new, {} prices) for {} by {}'.format( count, new, price_count, payload['source'], token.character.name)) return jsonify({ 'recorded': True, 'message': 'Recorded {} distance pairs, of which {} were new. +1 brownie point'. format(count, new) })