def times_from_location(q: str, twentyfour: bool) -> Dict[str, List[str]]: api_key = configuration.get('google_maps_api_key') if not api_key: raise NotConfiguredException('No value found for google_maps_api_key') url = 'https://maps.googleapis.com/maps/api/geocode/json?address={q}&key={api_key}&sensor=false'.format( q=fetch_tools.escape(q), api_key=api_key) info = fetch_tools.fetch_json(url) if 'error_message' in info: return info['error_message'] try: location = info['results'][0]['geometry']['location'] except IndexError as e: raise TooFewItemsException(e) from e url = 'https://maps.googleapis.com/maps/api/timezone/json?location={lat},{lng}×tamp={timestamp}&key={api_key}&sensor=false'.format( lat=fetch_tools.escape(str(location['lat'])), lng=fetch_tools.escape(str(location['lng'])), timestamp=fetch_tools.escape(str(dtutil.dt2ts(dtutil.now()))), api_key=api_key) timezone_info = fetch_tools.fetch_json(url) if 'error_message' in timezone_info: return timezone_info['error_message'] if timezone_info['status'] == 'ZERO_RESULTS': raise TooFewItemsException(timezone_info['status']) try: timezone = dtutil.timezone(timezone_info['timeZoneId']) except KeyError as e: raise TooFewItemsException( f'Unable to find a timezone in {timezone_info}') from e return { current_time(timezone, twentyfour): [info['results'][0]['formatted_address']] }
def fetch() -> None: all_prices, timestamps = {}, [] ch_urls = configuration.get_list('cardhoarder_urls') if ch_urls: for _, url in enumerate(ch_urls): s = fetch_tools.fetch(url) s = ftfy.fix_encoding(s) timestamps.append( dtutil.parse_to_ts( s.split('\n', 1)[0].replace('UPDATED ', ''), '%Y-%m-%dT%H:%M:%S+00:00', dtutil.CARDHOARDER_TZ)) all_prices[url] = parser.parse_cardhoarder_prices(s) url = configuration.get_str('mtgotraders_url') if url: s = fetch_tools.fetch(url) timestamps.append(dtutil.dt2ts(dtutil.now())) all_prices['mtgotraders'] = parser.parse_mtgotraders_prices(s) if not timestamps: raise TooFewItemsException( 'Did not get any prices when fetching {urls} ({all_prices})'. format(urls=itertools.chain( configuration.get_list('cardhoarder_urls'), [configuration.get_str('mtgotraders_url')]), all_prices=all_prices)) count = store(min(timestamps), all_prices) cleanup(count)
def load_cards(names: Iterable[str] = None, where: Optional[str] = None) -> List[Card]: if names == []: return [] if names: setnames = set(names) else: setnames = set() if setnames: names_clause = 'c.name IN ({names})'.format(names=', '.join( sqlescape(name) for name in setnames)) else: names_clause = '(1 = 1)' if where is None: where = '(1 = 1)' sql = multiverse.cached_base_query('({where} AND {names})'.format( where=where, names=names_clause)) rs = db().select(sql) if setnames and len(setnames) != len(rs): missing = setnames.symmetric_difference([r['name'] for r in rs]) raise TooFewItemsException( 'Expected `{namelen}` and got `{rslen}` with `{names}`. missing=`{missing}`' .format(namelen=len(setnames), rslen=len(rs), names=setnames, missing=missing)) return [Card(r) for r in rs]
def times_from_timezone_code(q: str, twentyfour: bool) -> Dict[str, List[str]]: possibles = list(filter(lambda x: datetime.datetime.now(pytz.timezone(x)).strftime('%Z') == q.upper(), pytz.common_timezones)) if not possibles: raise TooFewItemsException(f'Not a recognized timezone: {q.upper()}') results: Dict[str, List[str]] = {} for possible in possibles: timezone = dtutil.timezone(possible) t = current_time(timezone, twentyfour) results[t] = results.get(t, []) + [possible] return results
def time(q: str) -> str: if len(q) > 3: url = 'http://maps.googleapis.com/maps/api/geocode/json?address={q}&sensor=false'.format(q=internal.escape(q)) info = internal.fetch_json(url) try: location = info['results'][0]['geometry']['location'] except IndexError as e: raise TooFewItemsException(e) url = 'https://maps.googleapis.com/maps/api/timezone/json?location={lat},{lng}×tamp={timestamp}&sensor=false'.format(lat=internal.escape(str(location['lat'])), lng=internal.escape(str(location['lng'])), timestamp=internal.escape(str(dtutil.dt2ts(dtutil.now())))) timezone_info = internal.fetch_json(url) if timezone_info['status'] == 'ZERO_RESULTS': raise TooFewItemsException(timezone_info['status']) timezone = dtutil.timezone(timezone_info['timeZoneId']) else: try: timezone = dtutil.timezone(q.upper()) except pytz.exceptions.UnknownTimeZoneError: # type: ignore raise TooFewItemsException('Not a recognized timezone: {q}'.format(q=q)) return dtutil.now(timezone).strftime('%l:%M %p')
def load_cards(names=None, where=None): if names: names = set(names) if names: names_clause = 'LOWER(c.name) IN ({names})'.format(names=', '.join(sqlescape(name).lower() for name in names)) else: names_clause = '(1 = 1)' if where is None: where = '(1 = 1)' sql = multiverse.cached_base_query('({where} AND {names})'.format(where=where, names=names_clause)) rs = db().execute(sql) if names and len(names) != len(rs): missing = names.symmetric_difference([r['name'] for r in rs]) raise TooFewItemsException('Expected `{namelen}` and got `{rslen}` with `{names}`. missing=`{missing}`'.format(namelen=len(names), rslen=len(rs), names=names, missing=missing)) return [card.Card(r) for r in rs]
def fetch(): all_prices, timestamps = {}, [] for i, url in enumerate(configuration.get('cardhoarder_urls')): s = fetcher_internal.fetch(url) s = ftfy.fix_encoding(s) timestamps.append(dtutil.parse_to_ts(s.split('\n', 1)[0].replace('UPDATED ', ''), '%Y-%m-%dT%H:%M:%S+00:00', dtutil.CARDHOARDER_TZ)) all_prices[i] = parse_cardhoarder_prices(s) url = configuration.get('mtgotraders_url') if url: s = fetcher_internal.fetch(configuration.get('mtgotraders_url')) timestamps.append(dtutil.dt2ts(dtutil.now())) all_prices['mtgotraders'] = parse_mtgotraders_prices(s) if not timestamps: raise TooFewItemsException('Did not get any prices when fetching {urls} ({all_prices})'.format(urls=configuration.get('cardhoarder_urls') + [configuration.get('mtgotraders_url')], all_prices=all_prices)) store(min(timestamps), all_prices)
def load_cards(names=None): if names: names = set(names) if names: names_clause = 'HAVING LOWER({name_query}) IN ({names})'.format(name_query=card.name_query().format(table='u'), names=', '.join(sqlescape(name).lower() for name in names)) else: names_clause = '' sql = """ {base_query} {names_clause} """.format(base_query=base_query(), names_clause=names_clause) rs = db().execute(sql) if names and len(names) != len(rs): missing = names.symmetric_difference([r['name'] for r in rs]) raise TooFewItemsException('Expected `{namelen}` and got `{rslen}` with `{names}`. missing=`{missing}`'.format(namelen=len(names), rslen=len(rs), names=names, missing=missing)) return [card.Card(r) for r in rs]
def delete_match(match_id: int) -> None: db().begin('delete_match') rs = db().select( 'SELECT deck_id, games FROM deck_match WHERE match_id = %s', [match_id]) if not rs: raise TooFewItemsException( 'No deck_match entries found for match_id `{match_id}`') left_id = rs[0]['deck_id'] left_games = rs[0]['games'] if len(rs) > 1: right_id = rs[1]['deck_id'] right_games = rs[1]['games'] else: right_id, right_games = 0, 0 update_cache(left_id, left_games, right_games, delete=True) update_cache(right_id, right_games, left_games, delete=True) sql = 'DELETE FROM `match` WHERE id = %s' db().execute(sql, [match_id]) db().commit('delete_match') if rs: redis.clear(f'decksite:deck:{left_id}', f'decksite:deck:{right_id}')