Пример #1
0
 def handle_venue(self, venue):
     self.display_id = venue.api_configuration.taplist_io_display_id
     self.taplist_access_code = venue.api_configuration.taplist_io_access_code
     self.fetch_data()
     taps = {i.tap_number: i for i in venue.taps.all()}
     timestamp = parse(self._data['date_modified'])
     for index, tap in enumerate(self._data['on_tap']):
         tap_dict = self.parse_tap(tap)
         tap_number = tap_dict.pop('tap_number', index + 1)
         current_tap = taps.get(tap_number,
                                Tap(tap_number=tap_number, venue=venue))
         if not tap_dict:
             current_tap.beer = None
             current_tap.time_updated = timestamp
             current_tap.save()
             continue
         current_tap.time_added = tap_dict.pop('time_added')
         mfg_dict = tap_dict.pop('manufacturer')
         manufacturer = self.get_manufacturer(**mfg_dict)
         beer = self.get_beer(manufacturer=manufacturer,
                              venue=venue,
                              **tap_dict)
         current_tap.beer = beer
         if current_tap.time_updated != timestamp:
             current_tap.time_updated = timestamp
             current_tap.save()
Пример #2
0
 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):
        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()
Пример #4
0
 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
Пример #5
0
 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,
             )
Пример #6
0
 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 test_beers(self):
     mfg = ManufacturerFactory()
     beers = Beer.objects.bulk_create(
         BeerFactory.build(manufacturer=mfg) for dummy in range(10))
     taps = Tap.objects.bulk_create(
         Tap(
             beer=beer,
             tap_number=index + 1,
             venue=self.venue,
         ) for index, beer in enumerate(beers))
     response = self.client.get(f"{self.url}beers/")
     self.assertEqual(len(taps), len(beers))
     self.assertEqual(Beer.objects.count(), len(beers))
     self.assertEqual(response.status_code, 200, response.data)
     self.assertEqual(len(response.data["results"]), len(beers))
Пример #8
0
    def handle_venue(self, venue: Venue) -> datetime.datetime:
        self.categories = venue.api_configuration.beermenus_categories
        self.location_url = self.URL.format(
            venue.api_configuration.beermenus_slug)
        data = self.fetch_data()
        beers = self.parse_html(data)
        self.parse_beers(beers)
        LOG.info("Found %s taps from %s", len(beers), venue)
        existing_taps = {tap.tap_number: tap for tap in venue.taps.all()}
        # delete unused taps
        Tap.objects.filter(venue=venue, tap_number__gt=len(beers)).delete()

        for index, beer in enumerate(beers):
            tap_number = index + 1
            tap = existing_taps.get(tap_number,
                                    Tap(venue=venue, tap_number=tap_number))
            manufacturer = self.get_manufacturer(
                name=beer.brewery_name,
                location=beer.brewery_location,
                beermenus_slug=beer.brewery_slug.split("/")[-1],
            )
            beer = self.get_beer(
                name=beer.name,
                style=beer.style,
                venue=venue,
                pricing=[{
                    "volume_oz": beer.serving_size,
                    "price": beer.price,
                }],
                abv=beer.abv,
                beermenus_slug=beer.url.split("/")[-1],
                manufacturer=manufacturer,
            )
            if not tap.id or tap.beer_id != beer.id:
                tap.beer = beer
                LOG.debug("Saving %s to tap number %s", beer, tap_number)
                tap.save()
            else:
                LOG.debug(
                    "Not updating tap %s because it is already assigned to %s",
                    tap_number,
                    beer,
                )
        return self.updated_date
Пример #9
0
 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()
Пример #10
0
    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()
Пример #11
0
    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
Пример #12
0
    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()
Пример #13
0
 def handle_venue(self, venue: Venue) -> datetime.datetime:
     self.location_id = venue.api_configuration.arryved_location_id
     self.menu_id = venue.api_configuration.arryved_menu_id
     self.serving_sizes = set(venue.api_configuration.arryved_serving_sizes)
     BeerPrice.objects.filter(venue=venue).delete()
     try:
         self.manufacturer = Manufacturer.objects.get(
             name=venue.api_configuration.arryved_manufacturer_name)
     except Manufacturer.DoesNotExist as exc:
         raise ValueError(
             "You must create a manufacturer for "
             f"{venue.api_configuration.arryved_manufacturer_name or venue} before"
             " parsing!") from exc
     json_data = self.parse_json(self.fetch())
     taps = {i.tap_number: i for i in venue.taps.all()}
     manufacturer_beers = {
         beer.name: beer
         for beer in Beer.objects.filter(manufacturer=self.manufacturer)
     }
     last_updated = UTC.localize(datetime.datetime(1970, 1, 1, 0))
     prices = []
     serving_sizes = {i.volume_oz: i for i in ServingSize.objects.all()}
     tap_number = 1
     for beer in json_data["beers"]:
         tap = taps.get(tap_number, Tap(tap_number=tap_number, venue=venue))
         existing_beer_pk = tap.beer_id
         beer_created = False
         try:
             tap.beer = manufacturer_beers[beer["name"]]
         except KeyError:
             try:
                 tap.beer = Beer.objects.get(
                     manufacturer=self.manufacturer,
                     alternate_names__name=beer["name"],
                 )
             except Beer.DoesNotExist:
                 LOG.info("Creating beer %s for %s", beer["name"],
                          self.manufacturer)
                 new_beer = Beer.objects.create(
                     manufacturer=self.manufacturer,
                     ibu=beer["ibu"],
                     abv=beer["abv"],
                     name=beer["name"],
                 )
                 tap.beer = new_beer
                 beer_created = True
         tap_prices = self.process_serving_sizes(tap.beer, venue,
                                                 beer["serving_sizes"],
                                                 serving_sizes)
         if not tap_prices:
             LOG.debug("Skipping beer %s because it is not on tap",
                       tap.beer)
             if beer_created:
                 tap.beer.delete()
             continue
         prices += tap_prices
         if tap.beer.id != existing_beer_pk:
             tap.time_added = beer["last_updated"]
         if beer["ibu"]:
             tap.beer.ibu = beer["ibu"]
         if beer["abv"]:
             tap.beer.abv = beer["abv"]
         tap.time_updated = beer["last_updated"]
         LOG.debug("Saving tap %s: %s", tap.tap_number, tap.beer)
         tap.save()
         if beer["last_updated"] > last_updated:
             last_updated = beer["last_updated"]
         tap_number += 1
     delete_result = Tap.objects.filter(
         venue=venue,
         tap_number__gte=tap_number,
     ).delete()
     LOG.debug("Deleted %s extra taps", delete_result[0])
     BeerPrice.objects.bulk_create(prices)
     self.check_timestamp = last_updated
     return last_updated
Пример #14
0
 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
Пример #15
0
    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