def handle_venue(self, venue): self.venue = venue self.fetch_root_html() beers_found = self.parse_root_html() taps = self.parse_beers(beers_found) existing_taps = {i.tap_number: i for i in venue.taps.all()} LOG.debug("existing taps %s", existing_taps) taps_hit = [] latest_time = CENTRAL_TIME.localize(datetime.datetime(1970, 1, 1, 0)) for tap_number, beer in taps.items(): time_tapped = self.fill_in_beer_details(beer) if time_tapped > latest_time: latest_time = time_tapped try: tap = existing_taps[tap_number] except KeyError: tap = Tap( venue=self.venue, tap_number=tap_number, ) tap.beer = beer tap.time_added = time_tapped tap.save() taps_hit.append(tap.tap_number) LOG.debug("Deleting all taps except %s", taps_hit) Tap.objects.filter(venue=venue, ).exclude( tap_number__in=taps_hit, ).delete() return latest_time
def handle_venue(self, venue): self.categories = [ i.casefold() for i in venue.api_configuration.untappd_categories ] LOG.debug("Categories: %s", self.categories) self.location_url = self.URL.format( venue.api_configuration.untappd_location, venue.api_configuration.untappd_theme, ) data = self.fetch_data() self.parse_html_and_js(data) taps = {tap.tap_number: tap for tap in venue.taps.all()} manufacturers = {} tap_list = self.taps() use_sequential_taps = any(tap_info["tap_number"] is None for tap_info in tap_list) for index, tap_info in enumerate(tap_list): # 1. get the tap # if the venue doesn't give tap numbers, just use a 1-based # counter if use_sequential_taps: tap_number = index + 1 else: tap_number = tap_info["tap_number"] try: tap = taps[tap_number] except KeyError: tap = Tap(venue=venue, tap_number=tap_number) if tap_info["added"]: tap.time_added = tap_info["added"] if tap_info["updated"]: tap.time_updated = tap_info["updated"] # 2. parse the manufacturer try: manufacturer = manufacturers[tap_info["manufacturer"]["name"]] except KeyError: location = tap_info["manufacturer"]["location"] defaults = { "untappd_url": tap_info["manufacturer"]["untappd_url"], } if location: defaults["location"] = location manufacturer = self.get_manufacturer( tap_info["manufacturer"]["name"], **defaults, ) manufacturers[manufacturer.name] = manufacturer # 3. get the beer, creating if necessary beer_name = tap_info["beer"].pop("name") beer = self.get_beer( beer_name, manufacturer, venue=venue, pricing=tap_info["pricing"], **tap_info["beer"], ) # 4. assign the beer to the tap tap.beer = beer tap.save()
def handle_venue(self, venue): self.venue = venue self.fetch_root_html() beers_found = self.parse_root_html() taps = self.parse_beers(beers_found) existing_taps = {i.tap_number: i for i in venue.taps.all()} for tap_number, beer in taps.items(): self.fill_in_beer_details(beer) try: tap = existing_taps[tap_number] except KeyError: tap = Tap( venue=self.venue, tap_number=tap_number, ) tap.beer = beer tap.save()
def handle_venue(self, venue): url = venue.api_configuration.url self.fetch_html(url) taps = {tap.tap_number: tap for tap in venue.taps.all()} manufacturers = { mfg.name: mfg for mfg in Manufacturer.objects.filter( name__in=self.get_manufacturers()) } for index, (name, mfg, abv, style) in self.venue_details(): tap_number = index + 1 # 1. get the tap try: tap = taps[tap_number] except KeyError: tap = Tap(venue=venue, tap_number=tap_number) # 2. get the mfg try: manufacturer = manufacturers[mfg] except KeyError: manufacturer = self.get_manufacturer(name=mfg) manufacturers[manufacturer.name] = manufacturer # 3. get the beer beer = self.get_beer( name, manufacturer, abv=abv, api_vendor_style=style, ) if tap.beer_id != beer.id: tap.beer = beer # only save if beer changed so as not to disturb updated time LOG.debug('Saving %s on tap %s', beer, tap.tap_number) tap.save() else: LOG.debug( 'Not saving changes to beer %s on tap %s', beer, tap.tap_number, )
def handle_venue(self, venue): self.venue = venue self.fetch_root_html() beers_found = self.parse_root_html() taps = self.parse_beers(beers_found) existing_taps = {i.tap_number: i for i in venue.taps.all()} LOG.debug('existing taps %s', existing_taps) taps_hit = [] for tap_number, beer in taps.items(): self.fill_in_beer_details(beer) try: tap = existing_taps[tap_number] except KeyError: tap = Tap( venue=self.venue, tap_number=tap_number, ) tap.beer = beer tap.save() taps_hit.append(tap.tap_number) LOG.debug('Deleting all taps except %s', taps_hit) Tap.objects.filter(venue=venue, ).exclude( tap_number__in=taps_hit, ).delete()
def handle_venue(self, venue): venue_id = venue.api_configuration.digital_pour_venue_id location_number = venue.api_configuration.digital_pour_location_number self.url = self.URL.format(venue_id, location_number, self.APIKEY) data = self.fetch() taps = {tap.tap_number: tap for tap in venue.taps.all()} manufacturers = {} for entry in data: if not entry['Active']: # in the cooler, not on tap continue # 1. parse the tap tap_info = self.parse_tap(entry) try: tap = taps[tap_info['tap_number']] except KeyError: tap = Tap(venue=venue, tap_number=tap_info['tap_number']) tap.time_added = tap_info['added'] tap.time_updated = tap_info['updated'] tap.estimated_percent_remaining = tap_info['percent_full'] if tap_info['gas_type'] in [i[0] for i in Tap.GAS_CHOICES]: tap.gas_type = tap_info['gas_type'] else: tap.gas_type = '' # 2. parse the manufacturer, creating if needed parsed_manufacturer = self.parse_manufacturer(entry) try: manufacturer = manufacturers[parsed_manufacturer['name']] except KeyError: defaults = {} for field in ['location', 'logo_url', 'twitter_handle']: if parsed_manufacturer[field]: defaults[field] = parsed_manufacturer[field] manufacturer = self.get_manufacturer( name=parsed_manufacturer['name'], **defaults, ) manufacturers[manufacturer.name] = manufacturer # 3. get the beer, creating if necessary parsed_beer = self.parse_beer(entry) name = parsed_beer.pop('name') color_html = parsed_beer.pop('color', '') if color_html: # convert 0xabcde into #0abcde color_html = f'#{color_html[2:]:0>6}' parsed_beer['color_html'] = color_html else: # clear the color if unknown parsed_beer['color_html'] = '' LOG.debug( 'looking up beer: name %s, mfg %s, other data %s', name, manufacturer, parsed_beer, ) beer = self.get_beer( name, manufacturer, pricing=self.parse_pricing(entry), venue=venue, **parsed_beer, ) # 4. assign the beer to the tap tap.beer = beer tap.save()
def handle_venue(self, venue): location = venue.api_configuration.taphunter_location self.url = self.URL.format(location) data = self.fetch() taps = {tap.tap_number: tap for tap in venue.taps.all()} manufacturers = {} use_sequential_taps = any((tap_info['serving_info']['tap_number'] == '' for tap_info in data['taps'])) for index, entry in enumerate(data['taps']): # 1. parse the tap tap_info = self.parse_tap(entry) if use_sequential_taps: tap_number = index + 1 else: tap_number = tap_info['tap_number'] try: tap = taps[tap_number] except KeyError: tap = Tap(venue=venue, tap_number=tap_number) tap.time_added = tap_info['added'] tap.time_updated = tap_info['updated'] if 'percent_full' in tap_info: tap.estimated_percent_remaining = tap_info['percent_full'] else: tap.estimated_percent_remaining = None if 'gas_type' in tap_info and tap_info['gas_type'] in [ i[0] for i in Tap.GAS_CHOICES ]: tap.gas_type = tap_info['gas_type'] else: tap.gas_type = '' # 2. parse the manufacturer, creating if needed parsed_manufacturer = self.parse_manufacturer(entry) try: manufacturer = manufacturers[parsed_manufacturer['name']] except KeyError: kwargs = { key: val for key, val in parsed_manufacturer.items() if key != 'name' and val } manufacturer = self.get_manufacturer( name=parsed_manufacturer['name'], **kwargs, ) manufacturers[manufacturer.name] = manufacturer # 3. get the beer, creating if necessary parsed_beer = self.parse_beer(entry) name = parsed_beer.pop('name') # TODO (#37): map styles style = parsed_beer.pop('style', {}) if style: parsed_beer['api_vendor_style'] = \ f"{style['category']} - {style['name']}" color_srm = parsed_beer.pop('srm', 0) if color_srm: parsed_beer['color_srm'] = color_srm LOG.debug( 'looking up beer: name %s, mfg %s, other data %s', name, manufacturer, parsed_beer, ) beer = self.get_beer( name, manufacturer, pricing=self.parse_pricing(entry), venue=venue, **parsed_beer, ) # 4. assign the beer to the tap tap.beer = beer tap.save()
def handle_venue(self, venue): location = venue.api_configuration.taphunter_location excluded_lists = venue.api_configuration.taphunter_excluded_lists self.url = self.URL.format(location) data = self.fetch() taps = {tap.tap_number: tap for tap in venue.taps.all()} manufacturers = {} use_sequential_taps = any((tap_info["serving_info"]["tap_number"] == "" for tap_info in data["taps"])) latest_timestamp = UTC.localize(datetime.datetime(1970, 1, 1, 12)) for index, entry in enumerate(data["taps"]): # 1. parse the tap tap_info = self.parse_tap(entry) # Is it in an excluded list? if (excluded_lists and entry.get("list", {"name": -1})["name"] in excluded_lists): LOG.debug( "Skipping %s because it is in excluded list %s", entry["beer"]["beer_name"], entry["list"]["name"], ) continue if use_sequential_taps: tap_number = index + 1 else: tap_number = tap_info["tap_number"] try: tap = taps[tap_number] except KeyError: tap = Tap(venue=venue, tap_number=tap_number) tap.time_added = tap_info["added"] tap.time_updated = tap_info["updated"] parsed_time = parse(tap_info["updated"]) if parsed_time > latest_timestamp: latest_timestamp = parsed_time if "percent_full" in tap_info: tap.estimated_percent_remaining = tap_info["percent_full"] else: tap.estimated_percent_remaining = None if "gas_type" in tap_info and tap_info["gas_type"] in [ i[0] for i in Tap.GAS_CHOICES ]: tap.gas_type = tap_info["gas_type"] else: tap.gas_type = "" # 2. parse the manufacturer, creating if needed parsed_manufacturer = self.parse_manufacturer(entry) try: manufacturer = manufacturers[parsed_manufacturer["name"]] except KeyError: kwargs = { key: val for key, val in parsed_manufacturer.items() if key != "name" and val } manufacturer = self.get_manufacturer( name=parsed_manufacturer["name"], **kwargs, ) manufacturers[manufacturer.name] = manufacturer # 3. get the beer, creating if necessary parsed_beer = self.parse_beer(entry) name = parsed_beer["name"] style = parsed_beer.pop("style", {}) if style: parsed_beer["style"] = f"{style['category']} - {style['name']}" color_srm = parsed_beer.pop("srm", 0) if color_srm: parsed_beer["color_srm"] = color_srm LOG.debug( "looking up beer: name %s, mfg %s, other data %s", name, manufacturer, parsed_beer, ) beer = self.get_beer( manufacturer=manufacturer, pricing=self.parse_pricing(entry), venue=venue, **parsed_beer, ) # 4. assign the beer to the tap tap.beer = beer tap.save() return latest_timestamp
def handle_venue(self, venue): self.categories = [ i.casefold() for i in venue.api_configuration.untappd_categories ] LOG.debug('Categories: %s', self.categories) self.location_url = self.URL.format( venue.api_configuration.untappd_location, venue.api_configuration.untappd_theme, ) data = self.fetch_data() self.parse_html_and_js(data) taps = {tap.tap_number: tap for tap in venue.taps.all()} manufacturers = {} tap_list = self.taps() use_sequential_taps = any( tap_info['tap_number'] is None for tap_info in tap_list ) for index, tap_info in enumerate(tap_list): # 1. get the tap # if the venue doesn't give tap numbers, just use a 1-based # counter if use_sequential_taps: tap_number = index + 1 else: tap_number = tap_info['tap_number'] try: tap = taps[tap_number] except KeyError: tap = Tap(venue=venue, tap_number=tap_number) if tap_info['added']: tap.time_added = tap_info['added'] if tap_info['updated']: tap.time_updated = tap_info['updated'] # 2. parse the manufacturer try: manufacturer = manufacturers[tap_info['manufacturer']['name']] except KeyError: location = tap_info['manufacturer']['location'] defaults = { 'untappd_url': tap_info['manufacturer']['untappd_url'], } if location: defaults['location'] = location manufacturer = self.get_manufacturer( tap_info['manufacturer']['name'], **defaults, ) manufacturers[manufacturer.name] = manufacturer # 3. get the beer, creating if necessary beer_name = tap_info['beer'].pop('name') style = tap_info['beer'].pop('style', {}) if style: if style['category']: tap_info['beer'][ 'style' ] = f"{style['category']} - {style['name']}" else: tap_info['beer']['style'] = style['name'] beer = self.get_beer( beer_name, manufacturer, venue=venue, pricing=tap_info['pricing'], **tap_info['beer'] ) # 4. assign the beer to the tap tap.beer = beer tap.save()
def handle_venue(self, venue: Venue) -> datetime.datetime: venue_id = venue.api_configuration.digital_pour_venue_id location_number = venue.api_configuration.digital_pour_location_number self.url = self.URL.format(venue_id, location_number, self.APIKEY) data = self.fetch() taps = {tap.tap_number: tap for tap in venue.taps.all()} self.update_date = UTC.localize(datetime.datetime(1970, 1, 1, 0, 0, 0)) manufacturers = {} for entry in data: if not entry["Active"]: # in the cooler, not on tap continue # 1. parse the tap tap_info = self.parse_tap(entry) try: tap = taps[tap_info["tap_number"]] except KeyError: tap = Tap(venue=venue, tap_number=tap_info["tap_number"]) tap.time_added = tap_info["added"] tap.time_updated = tap_info["updated"] if tap.time_updated and tap.time_updated > self.update_date: LOG.debug("Updating venue timestamp to %s", tap.time_updated) self.update_date = tap.time_updated tap.estimated_percent_remaining = tap_info["percent_full"] if tap_info["gas_type"] in [i[0] for i in Tap.GAS_CHOICES]: tap.gas_type = tap_info["gas_type"] else: tap.gas_type = "" # 2. parse the manufacturer, creating if needed parsed_manufacturer = self.parse_manufacturer(entry) try: manufacturer = manufacturers[parsed_manufacturer["name"]] except KeyError: defaults = { field: parsed_manufacturer[field] for field in [ "location", "logo_url", "twitter_handle", "url", ] if parsed_manufacturer[field] } manufacturer = self.get_manufacturer( name=parsed_manufacturer["name"], **defaults, ) manufacturers[manufacturer.name] = manufacturer # 3. get the beer, creating if necessary parsed_beer = self.parse_beer(entry) name = parsed_beer.pop("name") color_html = parsed_beer.pop("color", "") if color_html: # convert 0xabcde into #0abcde color_html = f"#{color_html[2:]:0>6}" parsed_beer["color_html"] = color_html else: # clear the color if unknown parsed_beer["color_html"] = "" LOG.debug( "looking up beer: name %s, mfg %s, other data %s", name, manufacturer, parsed_beer, ) if name.casefold().strip() == "N/A".casefold(): if not parsed_beer.get("abv"): # it's an empty tap LOG.info("Tap %s is unused", tap.tap_number) tap.beer = None tap.save() continue beer = self.get_beer( name, manufacturer, pricing=self.parse_pricing(entry), venue=venue, **parsed_beer, ) # 4. assign the beer to the tap tap.beer = beer tap.save() return self.update_date
def handle_venue(self, venue): self.categories = [ i.casefold() for i in venue.api_configuration.untappd_categories ] LOG.debug("Categories: %s", self.categories) self.location_url = self.URL.format( venue.api_configuration.untappd_location, venue.api_configuration.untappd_theme, ) data = self.fetch_data() self.parse_html_and_js(data) taps = {tap.tap_number: tap for tap in venue.taps.all()} manufacturers = {} tap_list = self.taps() use_sequential_taps = any( tap_info["tap_number"] is None for tap_info in tap_list ) LOG.debug("use sequential taps? %s", use_sequential_taps) if not use_sequential_taps: populated_taps: list[int] = [ tap_info["tap_number"] for tap_info in tap_list ] else: populated_taps = list(range(1, len(tap_list) + 1)) LOG.debug("populated taps: %s", populated_taps) cleared = ( Tap.objects.filter( venue=venue, ) .exclude( tap_number__in=populated_taps, ) .delete()[1] .get("taps.Tap", 0) ) if cleared: LOG.info( "Cleared %s now unused taps (not in %s)", cleared, sorted(populated_taps), ) # pylint: disable=no-value-for-parameter latest_timestamp = UTC.localize(datetime.datetime(1970, 1, 1, 12)) for index, tap_info in enumerate(tap_list): # 1. get the tap # if the venue doesn't give tap numbers, just use a 1-based # counter if use_sequential_taps: tap_number = index + 1 else: tap_number = tap_info["tap_number"] try: tap = taps[tap_number] except KeyError: tap = Tap(venue=venue, tap_number=tap_number) if tap_info["added"]: tap.time_added = dateutil.parser.parse(tap_info["added"]) if tap.time_added > latest_timestamp: LOG.debug( "latest timestamp updated to %s (added)", tap.time_updated, ) latest_timestamp = tap.time_added if tap_info["updated"]: tap.time_updated = dateutil.parser.parse(tap_info["updated"]) if tap.time_updated > latest_timestamp: LOG.debug( "latest timestamp updated to %s (updated)", tap.time_updated, ) latest_timestamp = tap.time_updated # 2. parse the manufacturer try: manufacturer = manufacturers[tap_info["manufacturer"]["name"]] except KeyError: location = tap_info["manufacturer"]["location"] defaults = { "untappd_url": tap_info["manufacturer"]["untappd_url"], } if location: defaults["location"] = location manufacturer = self.get_manufacturer( tap_info["manufacturer"]["name"], **defaults, ) manufacturers[manufacturer.name] = manufacturer # 3. get the beer, creating if necessary beer_name = tap_info["beer"].pop("name") beer = self.get_beer( beer_name, manufacturer, venue=venue, pricing=tap_info["pricing"], **tap_info["beer"], ) # 4. assign the beer to the tap tap.beer = beer tap.save() if latest_timestamp == UTC.localize(datetime.datetime(1970, 1, 1, 12)): return None return latest_timestamp