class LovecraftComicsSkill(OVOSCommonPlaybackSkill): def __init__(self): super().__init__("LovecraftComics") self.supported_media = [MediaType.GENERIC, MediaType.AUDIOBOOK, MediaType.VISUAL_STORY, MediaType.VIDEO] self.default_bg = join(dirname(__file__), "ui", "bg.png") self.default_image = join(dirname(__file__), "ui", "dagon.png") self.skill_icon = join(dirname(__file__), "ui", "icon.png") self.db = JsonStorage(join(dirname(__file__), "res", "JeremyZahn_lovecraft_comics.json")) self.db2 = JsonStorage(join(dirname(__file__), "res", "TanabeGou_lovecraft_comics.json")) def get_base_score(self, original, media_type): score = 0 if media_type == MediaType.AUDIOBOOK: score += 10 elif media_type == MediaType.VIDEO: score += 5 elif media_type == MediaType.VISUAL_STORY: score += 30 if self.voc_match(original, "reading") or \ self.voc_match(original, "audio_theatre"): score += 10 if self.voc_match(original, "lovecraft"): score += 30 if self.voc_match(original, "video"): score += 10 if self.voc_match(original, "comic"): score += 10 return score @ocp_search() def ocp_motioncomics_lovecraft_playlist(self, phrase, media_type): score = self.get_base_score(phrase, media_type) if self.voc_match(phrase, "comic") or \ media_type == MediaType.VISUAL_STORY: score += 10 if self.voc_match(phrase, "lovecraft"): score += 30 pl = [ { "match_confidence": score, "media_type": MediaType.VISUAL_STORY, "uri": entry["uri"], "playback": PlaybackType.VIDEO, "image": entry["image"], "bg_image": self.default_bg, "skill_icon": self.skill_icon, "title": entry["title"], "author": "H. P. Lovecraft", "album": "Lovecraft Motion Comics by Jeremy Zahn" } for title, entry in self.db.items() ] pl2 = [ { "match_confidence": score, "media_type": MediaType.VISUAL_STORY, "uri": entry["uri"], "playback": PlaybackType.VIDEO, "image": entry["image"], "bg_image": self.default_bg, "skill_icon": self.skill_icon, "title": entry["title"], "author": "H. P. Lovecraft", "album": "Lovecraft Illustrated by Tanabe Gou" } for title, entry in self.db2.items() ] return [{ "match_confidence": score, "media_type": MediaType.VISUAL_STORY, "playlist": pl, "playback": PlaybackType.VIDEO, "skill_icon": self.skill_icon, "image": "https://img.youtube.com/vi/Gv1I0y6PHfg/hqdefault.jpg", "bg_image": self.default_image, "title": "Lovecraft Comics by Jeremy Zahn (Playlist)", "author": "H. P. Lovecraft", "album": "Lovecraft Motion Comics by Jeremy Zahn" }, { "match_confidence": score, "media_type": MediaType.VISUAL_STORY, "playlist": pl2, "playback": PlaybackType.VIDEO, "skill_icon": self.skill_icon, "image": "https://img.youtube.com/vi/jW_G7cGxCWY/hqdefault.jpg", "bg_image": self.default_image, "title": "Lovecraft Illustrated by Tanabe Gou (Playlist)", "author": "H. P. Lovecraft", "album": "Lovecraft Illustrated by Tanabe Gou" }] @ocp_featured_media() def featured_media(self): pl = [ { "media_type": MediaType.VISUAL_STORY, "uri": entry["uri"], "playback": PlaybackType.VIDEO, "image": entry["image"], "bg_image": self.default_bg, "skill_icon": self.skill_icon, "title": entry["title"], "author": "H. P. Lovecraft", "album": "Lovecraft Motion Comics by Jeremy Zahn" } for title, entry in self.db.items() ] pl2 = [ { "media_type": MediaType.VISUAL_STORY, "uri": entry["uri"], "playback": PlaybackType.VIDEO, "image": entry["image"], "bg_image": self.default_bg, "skill_icon": self.skill_icon, "title": entry["title"], "author": "H. P. Lovecraft", "album": "Lovecraft Illustrated by Tanabe Gou" } for title, entry in self.db2.items() ] return pl + pl2
class EpicHorrorTheatreSkill(OVOSCommonPlaybackSkill): def __init__(self): super().__init__("Epic Horror Theatre") self.db = JsonStorage(join(dirname(__file__), "res", "epichorrortheatre.json")) self.supported_media = [MediaType.GENERIC, MediaType.RADIO_THEATRE, MediaType.AUDIOBOOK] self.default_bg = join(dirname(__file__), "ui", "bg.jpg") self.skill_icon = join(dirname(__file__), "ui", "icon.png") # common play def clean_vocs(self, phrase): phrase = self.remove_voc(phrase, "reading") phrase = self.remove_voc(phrase, "lovecraft") phrase = self.remove_voc(phrase, "atlanta") phrase = self.remove_voc(phrase, "epic_horror") phrase = self.remove_voc(phrase, "audio_theatre") phrase = self.remove_voc(phrase, "play") phrase = phrase.strip() return phrase def get_base_score(self, phrase, media_type): original = phrase score = 0 if self.voc_match(original, "atlanta"): score += 15 if self.voc_match(phrase, "audio_theatre") or \ media_type == MediaType.RADIO_THEATRE: score += 35 elif media_type == MediaType.AUDIOBOOK: score += 15 if self.voc_match(original, "horror"): score += 15 elif self.voc_match(original, "epic_horror"): score += 30 if self.voc_match(original, "lovecraft"): score += 50 return score @ocp_search() def ocp_epichorrortheatre_playlist(self, phrase, media_type): score = self.get_base_score(phrase, media_type) if self.voc_match(phrase, "atlanta"): score += 15 if self.voc_match(phrase, "audio_theatre") or \ media_type == MediaType.RADIO_THEATRE: score += 10 pl = [ { "match_confidence": score, "media_type": MediaType.AUDIOBOOK, "uri": entry["uri"], "playback": PlaybackType.AUDIO, "image": join(dirname(__file__), entry["image"]), "bg_image": self.default_bg, "skill_icon": self.skill_icon, "title": title, "author": "H. P. Lovecraft", "album": "by Atlanta Radio Theatre" } for title, entry in self.db.items() ] if pl: yield { "match_confidence": score, "media_type": MediaType.AUDIOBOOK, "playlist": pl, "playback": PlaybackType.AUDIO, "skill_icon": self.skill_icon, "image": self.default_bg, "bg_image": self.default_bg, "title": "Epic Horror Theatre (Atlanta Radio Theatre)", "author": "H. P. Lovecraft", "album": "by Atlanta Radio Theatre" } @ocp_search() def search(self, phrase, media_type): score = self.get_base_score(phrase, media_type) phrase = self.clean_vocs(phrase) scores = {k: score for k, v in self.db.items()} if self.voc_match(phrase, "color_out_of_space"): scores["The Color Out of Space"] += 70 elif self.voc_match(phrase, "innsmouth"): scores["The Shadow Over Innsmouth"] += 70 elif self.voc_match(phrase, "mountains_of_madness"): scores["At The Mountains of Madness"] += 70 elif media_type not in [MediaType.RADIO_THEATRE, MediaType.AUDIOBOOK]: return if score >= MatchConfidence.AVERAGE: for k in scores: yield { "match_confidence": min(100, scores[k]), "media_type": MediaType.AUDIOBOOK, "uri": self.db[k]["uri"], "playback": PlaybackType.AUDIO, "image": join(dirname(__file__), self.db[k]["image"]), "bg_image": self.default_bg, "skill_icon": self.skill_icon, "title": k, "author": "H. P. Lovecraft", "album": "by Atlanta Radio Theatre" }
class WayneJuneLovecraftReadingsSkill(OVOSCommonPlaybackSkill): def __init__(self): super().__init__("Wayne June Lovecraft Readings") self.supported_media = [ MediaType.GENERIC, MediaType.AUDIOBOOK, MediaType.VISUAL_STORY, MediaType.VIDEO ] self.default_image = join(dirname(__file__), "ui", "wayne_june.png") self.skill_icon = join(dirname(__file__), "ui", "icon.png") self.default_bg = join(dirname(__file__), "ui", "bg.jpeg") self.db = JsonStorage(join(dirname(__file__), "res", "waynejune.json")) def get_base_score(self, phrase): score = 0 if self.voc_match(phrase, "reading"): score += 10 if self.voc_match(phrase, "audio_theatre"): score += 10 if self.voc_match(phrase, "lovecraft"): score += 50 if self.voc_match(phrase, "wayne_june"): score += 35 if self.voc_match(phrase, "lovecraft"): score += 10 if self.voc_match(phrase, "horror"): score += 10 if self.voc_match(phrase, "cthulhu"): score += 10 return score @ocp_search() def ocp_waynejune_lovecraft_playlist(self, phrase): score = self.get_base_score(phrase) if self.voc_match(phrase, "wayne_june"): score += 50 yield { "match_confidence": score, "media_type": MediaType.AUDIOBOOK, "playlist": self.featured_media(), "playback": PlaybackType.AUDIO, "skill_icon": self.skill_icon, "image": self.default_bg, "bg_image": self.default_bg, "title": "Lovecraft - read by Wayne June (Compilation Playlist)", "author": "H. P. Lovecraft", "album": "read by Wayne June" } def clean_vocs(self, phrase): phrase = self.remove_voc(phrase, "reading") phrase = self.remove_voc(phrase, "audio_theatre") phrase = self.remove_voc(phrase, "play") phrase = phrase.strip() return phrase @ocp_search() def search(self, phrase, media_type): """Analyze phrase to see if it is a play-able phrase with this skill. Arguments: phrase (str): User phrase uttered after "Play", e.g. "some music" media_type (MediaType): requested CPSMatchType to media for Returns: search_results (list): list of dictionaries with result entries { "match_confidence": MatchConfidence.HIGH, "media_type": CPSMatchType.MUSIC, "uri": "https://audioservice.or.gui.will.play.this", "playback": PlaybackType.VIDEO, "image": "http://optional.audioservice.jpg", "bg_image": "http://optional.audioservice.background.jpg" } """ score = self.get_base_score(phrase) if media_type != MediaType.AUDIOBOOK: score -= 20 phrase = self.clean_vocs(phrase) # calculate scores for individual stories # NOTE: each match is designed to be 70 for exact match, # the other 30 are reserved for author/media type # NOTE2: all my lovecraft skills are designed to return confidence # of 40 if the query only contains the author, this is important to # ensure all stories are equal without extra information scores = {} for k in self.db: scores[k] = score if self.voc_match(phrase, "horror"): scores["The Horror At Red Hook"] += 10 scores["The Dunwich Horror"] += 10 if self.voc_match(phrase, "red_hook"): scores["The Horror At Red Hook"] += 40 if self.voc_match(phrase, "horror"): scores["The Horror At Red Hook"] += 20 if self.voc_match(phrase, "dunwich"): scores["The Dunwich Horror"] += 40 if self.voc_match(phrase, "horror"): scores["The Dunwich Horror"] += 20 if self.voc_match(phrase, "lurking_fear"): scores["The Lurking Fear"] += 70 if self.voc_match(phrase, "mountains"): scores["At The Mountains Of Madness"] += 70 if self.voc_match(phrase, "tomb"): scores["The Tomb"] += 70 # if self.voc_match(phrase, "virgin_finlay"): # scores["To Virgil Finlay"] += 70 if self.voc_match(phrase, "reanimator"): scores["Herbert West–Reanimator"] += 40 if self.voc_match(phrase, "herbert_west"): scores["Herbert West–Reanimator"] += 30 if self.voc_match(phrase, "innsmouth"): scores["The Shadow Over Innsmouth"] += 40 if self.voc_match(phrase, "shadow"): scores["The Shadow Over Innsmouth"] += 30 if self.voc_match(phrase, "cthulhu"): scores["The Call Of Cthulhu"] += 40 if self.voc_match(phrase, "call"): scores["The Call Of Cthulhu"] += 20 if self.voc_match(phrase, "doorstep"): scores["The Thing On The Doorstep"] += 10 if self.voc_match(phrase, "thing"): scores["The Thing On The Doorstep"] += 10 if self.voc_match(phrase, "thing") and \ self.voc_match(phrase, "doorstep"): scores["The Thing On The Doorstep"] += 50 if self.voc_match(phrase, "house"): scores["The Shunned House"] += 10 if self.voc_match(phrase, "shunned"): scores["The Shunned House"] += 10 if self.voc_match(phrase, "shunned") and \ self.voc_match(phrase, "house"): scores["The Shunned House"] += 50 for k, v in scores.items(): if v >= MatchConfidence.AVERAGE_LOW: yield { "match_confidence": min(100, v), "media_type": MediaType.AUDIOBOOK, "uri": self.db[k]["uri"], "playback": PlaybackType.AUDIO, "image": join(dirname(__file__), self.db[k]["image"]), "bg_image": self.default_bg, "skill_icon": self.skill_icon, "length": self.db[k]["length"], "title": k, "author": "H. P. Lovecraft", "album": "read by Wayne June" } @ocp_featured_media() def featured_media(self): return [{ "media_type": MediaType.AUDIOBOOK, "uri": entry["uri"], "playback": PlaybackType.AUDIO, "image": join(dirname(__file__), entry["image"]), "bg_image": self.default_bg, "skill_icon": self.skill_icon, "length": entry["length"], "title": title, "author": "H. P. Lovecraft", "album": "read by Wayne June" } for title, entry in self.db.items()]