def beer_style(self, ident, sort_type=None, sort_order=None): """Get all the beers from a specific beer style page. Args: ident (integer): The ID of the beer style from beer_style_list(). For example, for 'Abbey Dubbel' it would be 71. sort_type (string): The sorting of the results. The valid choices are "score" (default), "count", and "abv". sort_order (string): "ascending" (low-to-high) or "descending" (high-to-low, default) Returns: A list of generator of beers. """ if sort_type is None: sort_type = 'score' if sort_order is None: sort_order = 'descending' sort_type = sort_type.lower() sort_order = sort_order.lower() so = {'score': 0, 'count': 1, 'abv': 2}.get(sort_type) o = {'descending': 0, 'ascending': 1}.get(sort_order) soup = soup_helper._get_soup('/ajax/top-beer.asp?s={}&so={}&o={}'.format(ident, so, o)) rows = iter(soup.table.find_all('tr')) next(rows) # Get rid of the header for row in rows: data = row.find_all('td') link = data[1].a dataout = models.Beer(link.get('href')) dataout.name = link.text yield dataout
def search(self, query): """Returns a list of beers and breweries that matched the search query. Args: query (string): The text of the search. Returns: A dictionary containing two lists, ``breweries`` and ``beers``. Each list contains a dictionary of attributes of that brewery or beer. """ try: query = unicode(query, 'UTF8').encode('iso-8859-1') except (TypeError, NameError): # Python 3 does not have unicode() query = query.encode('iso-8859-1') request = requests.post( soup_helper._BASE_URL + "/findbeer.asp", data={"BeerName": query} ) soup = BeautifulSoup(request.text, "lxml") output = {"breweries": [], "beers": []} # Locate rows that contain the brewery and beer info beer_table = soup.find('h2', string='beers') if beer_table: for row in beer_table.next_sibling('tr'): # Only include ratable beers if row.find(title='Rate This Beer'): url = row('td')[0].a.get('href') url = re.sub(r"\s+", "", url, flags=re.UNICODE) beer = models.Beer(url) beer.name = row('td')[0].a.string.strip() overall_rating = row('td')[3].string num_ratings = row('td')[4].string if overall_rating: beer.overall_rating = int(overall_rating.strip()) if num_ratings: beer.num_ratings = int(num_ratings.strip()) output['beers'].append(beer) brewer_table = soup.find('h2', string='brewers') if brewer_table: for row in brewer_table.next_sibling('tr'): url = row.a.get('href') url = re.sub(r"\s+", "", url, flags=re.UNICODE) brewer = models.Brewery(url) brewer.name = row.a.string brewer.location = row('td')[1].string.strip() output['breweries'].append(brewer) return output
def search(self, query): """Returns a list of beers and breweries that matched the search query. Args: query (string): The text of the search. Returns: A dictionary containing two lists, ``breweries`` and ``beers``. Each list contains a dictionary of attributes of that brewery or beer. """ data = { "query": "query beerSearch($query: String, $order: SearchOrder, $first: Int, $after: ID) { searchResultsArr: beerSearch(query: $query, order: $order, first: $first, after: $after) { totalCount last items { beer { id name imageUrl overallScore ratingCount __typename } review { id score __typename } __typename } __typename } }", "variables": { "query": query, "order": "MATCH", "first": 20 }, "operationName": "beerSearch" } # options = requests.options("https://beta.ratebeer.com/v1/api/graphql/") request = requests.post("https://beta.ratebeer.com/v1/api/graphql/", data=json.dumps(data), headers={"content-type": "application/json"}) output = {"breweries": [], "beers": []} try: search_results = json.loads(request.text) except: raise rb_exceptions.JSONParseException(query) for result in search_results['data']['searchResultsArr']['items']: if 'beer' in result: beer_data = result['beer'] # double check this... url = '/beer/{0}/{1}/'.format( beer_data['name'].replace(' ', '-').lower(), beer_data['id']) beer = models.Beer(url, id=beer_data['id']) beer.name = beer_data['name'] beer.overall_rating = beer_data['overallScore'] beer.num_ratings = beer_data['ratingCount'] output['beers'].append(beer) return output
def beer_style(self, url, sort_type="overall"): """Get all the beers from a specific beer style page. Args: url (string): The specific url of the beer style. Looks like: "/beerstyles/abbey-dubbel/71/" sort_type (string): The sorting of the results. "overall" returns the highest- rated beers, while "trending" returns the newest and trending ones. Returns: A list of generator of beers. """ sort_type = sort_type.lower() url_codes = {"overall": 0, "trending": 1} sort_flag = url_codes.get(sort_type) if sort_flag is None: raise ValueError("Invalid ``sort_type``.") style_id = re.search(r"/(?P<id>\d*)/", url).group('id') req = requests.post( soup_helper._BASE_URL + ( "/ajax/top-beer-by-style.asp?style={0}&sort={1}" "&order=0&min=10&max=9999&retired=0&new=0&mine=0&" ) .format(style_id, sort_flag), allow_redirects=True ) soup = BeautifulSoup(req.text, "lxml") rows = iter(soup.table.find_all('tr')) next(rows) for row in rows: data = row.find_all('td') link = data[1].a dataout = models.Beer(link.get('href')) dataout.name = link.text yield dataout raise StopIteration
def add_beer(): error = None if session['logged_in'] == True: if request.method == 'POST': genre = models.Genre.query.filter_by( name=request.form['genre']).first() brewery = models.Brewery.query.filter_by( name=request.form['brewery']).first() if genre is None or brewery is None: error = "List a valid Genre or Brewery..." return render_template('add_beer.html', error=error) new_beer = models.Beer(request.form['name'], request.form['abv'], request.form['photo'], request.form['special'], genre, brewery) # For some reason this needs to be a merge() instead of an # add(), but I have no idea why. There be dragons...Or, # I'm a retard. db.session.merge(new_beer) db.session.commit() # Set the session to remember the beer just added session['newest_beer'] = request.form['name'] return redirect(url_for('beer_landing')) else: # ends POST return render_template('add_beer.html') else: # ends logged in return redirect(url_for('show_home'))
def get_beer(self, url, fetch=None): """Returns a Beer object for the requested URL""" if fetch is None: fetch = False return models.Beer(url, fetch)