Loading alexa_metal_archives_lookup.py +103 −12 Original line number Diff line number Diff line #!/usr/bin/env python3 # -*- coding: utf-8 -*- from itertools import chain import re from typing import Sequence from flask import Flask from flask_ask import Ask, statement import jinja2 import metallum app = Flask(__name__) ask = Ask(app, '/') @ask.intent('BandLookup') def hello(bandName): if bandName == 'darkthrone': genre = 'Black Metal' elif bandName == 'joy division': genre = 'Post Punk' def starts_with_vowel(s: str) -> bool: return s and s[0].lower() in {'a', 'e', 'i', 'o', 'u'} def format_genres(genres: Sequence[str]) -> str: cleaned_genres = [] for i, genre in enumerate(genres): cleaned_genres.append(genre.replace(' (early)', '') .replace(' (mid)', '') .replace(' (later)', '')) if i == len(genres) - 1: # Don’t append comma or “and” after the last genre. pass elif i == len(genres) - 2: # Append “and” after the last genre. cleaned_genres.append('and') else: genre = None cleaned_genres.append(',') if len(cleaned_genres) == 1: return cleaned_genres[0] else: cleaned_genres[-2] = 'and' return ' '.join(cleaned_genres) BAND_TEMPLATE = jinja2.Template( '''{% if band.genres | length == 1 %} {{ band.name }} is {{ 'an' if starts_with_vowel(band.genres[0]) else 'a' }} {{ band.genres[0] }} band from {{ band.country }}. {% else %} {{ band.name }} is a band from {{ band.country }} who have played {{ format_genres(band.genres) }} {% endif %} They formed in {{ band.formed_in }} and {% if band.status == 'Active' %} are still active. {% else %} are not active, any more. {% endif %} ''' ) BAND_RESULTS_TEMPLATE = jinja2.Template( '''There are {{ band_results | length }} bands called {{ band_results[0].name }}: {% for result in band_results %} A band from {{ result.country }} playing {{ format_genres(result.genres) }}. {% endfor %} ''' ) DEFAULT_ENVIRONMENT = {'format_genres': format_genres, 'starts_with_vowel': starts_with_vowel} if genre: speech_text = '{} is a {} band.'.format(bandName, genre) def render_template(template, **env): final_env = {k: v for k, v in chain(DEFAULT_ENVIRONMENT.items(), env.items())} return template.render(**final_env) def describe_band(band: metallum.Band) -> str: rendered = render_template(BAND_TEMPLATE, band=band) with_cleaned_whitespace = re.sub(r'\s+', ' ', rendered).strip() return with_cleaned_whitespace def name_bands(band_results: Sequence[metallum.BandResult]) -> str: rendered = render_template(BAND_RESULTS_TEMPLATE, band_results=band_results) with_cleaned_whitespace = re.sub(r'\s+', ' ', rendered).strip() return with_cleaned_whitespace def say_number_of_bands(band_results: Sequence[metallum.BandResult]) -> str: return ('There are {} bands called {}.' .format(len(band_results), band_results[0].name)) def band_lookup(band_name: str) -> str: search_results = metallum.band_search(band_name) if len(search_results) == 0: response = ('I don’t know anything about the band {}, sorry.' .format(band_name)) elif len(search_results) == 1: band = search_results[0].get() response = describe_band(band) elif len(search_results) < 5: response = name_bands(search_results) else: speech_text = 'I don’t know anything about {}, sorry.'.format( bandName) response = say_number_of_bands(search_results) return response @ask.intent('BandLookup') def band_lookup_endpoint(bandName: str) -> statement: response = band_lookup(bandName) return statement(response).simple_card('BandLookup', response) return statement(speech_text).simple_card('Hello', speech_text) if __name__ == '__main__': app.run() Loading
alexa_metal_archives_lookup.py +103 −12 Original line number Diff line number Diff line #!/usr/bin/env python3 # -*- coding: utf-8 -*- from itertools import chain import re from typing import Sequence from flask import Flask from flask_ask import Ask, statement import jinja2 import metallum app = Flask(__name__) ask = Ask(app, '/') @ask.intent('BandLookup') def hello(bandName): if bandName == 'darkthrone': genre = 'Black Metal' elif bandName == 'joy division': genre = 'Post Punk' def starts_with_vowel(s: str) -> bool: return s and s[0].lower() in {'a', 'e', 'i', 'o', 'u'} def format_genres(genres: Sequence[str]) -> str: cleaned_genres = [] for i, genre in enumerate(genres): cleaned_genres.append(genre.replace(' (early)', '') .replace(' (mid)', '') .replace(' (later)', '')) if i == len(genres) - 1: # Don’t append comma or “and” after the last genre. pass elif i == len(genres) - 2: # Append “and” after the last genre. cleaned_genres.append('and') else: genre = None cleaned_genres.append(',') if len(cleaned_genres) == 1: return cleaned_genres[0] else: cleaned_genres[-2] = 'and' return ' '.join(cleaned_genres) BAND_TEMPLATE = jinja2.Template( '''{% if band.genres | length == 1 %} {{ band.name }} is {{ 'an' if starts_with_vowel(band.genres[0]) else 'a' }} {{ band.genres[0] }} band from {{ band.country }}. {% else %} {{ band.name }} is a band from {{ band.country }} who have played {{ format_genres(band.genres) }} {% endif %} They formed in {{ band.formed_in }} and {% if band.status == 'Active' %} are still active. {% else %} are not active, any more. {% endif %} ''' ) BAND_RESULTS_TEMPLATE = jinja2.Template( '''There are {{ band_results | length }} bands called {{ band_results[0].name }}: {% for result in band_results %} A band from {{ result.country }} playing {{ format_genres(result.genres) }}. {% endfor %} ''' ) DEFAULT_ENVIRONMENT = {'format_genres': format_genres, 'starts_with_vowel': starts_with_vowel} if genre: speech_text = '{} is a {} band.'.format(bandName, genre) def render_template(template, **env): final_env = {k: v for k, v in chain(DEFAULT_ENVIRONMENT.items(), env.items())} return template.render(**final_env) def describe_band(band: metallum.Band) -> str: rendered = render_template(BAND_TEMPLATE, band=band) with_cleaned_whitespace = re.sub(r'\s+', ' ', rendered).strip() return with_cleaned_whitespace def name_bands(band_results: Sequence[metallum.BandResult]) -> str: rendered = render_template(BAND_RESULTS_TEMPLATE, band_results=band_results) with_cleaned_whitespace = re.sub(r'\s+', ' ', rendered).strip() return with_cleaned_whitespace def say_number_of_bands(band_results: Sequence[metallum.BandResult]) -> str: return ('There are {} bands called {}.' .format(len(band_results), band_results[0].name)) def band_lookup(band_name: str) -> str: search_results = metallum.band_search(band_name) if len(search_results) == 0: response = ('I don’t know anything about the band {}, sorry.' .format(band_name)) elif len(search_results) == 1: band = search_results[0].get() response = describe_band(band) elif len(search_results) < 5: response = name_bands(search_results) else: speech_text = 'I don’t know anything about {}, sorry.'.format( bandName) response = say_number_of_bands(search_results) return response @ask.intent('BandLookup') def band_lookup_endpoint(bandName: str) -> statement: response = band_lookup(bandName) return statement(response).simple_card('BandLookup', response) return statement(speech_text).simple_card('Hello', speech_text) if __name__ == '__main__': app.run()