From 419333fac3f6c4171f1e8df57606a96a37de8396 Mon Sep 17 00:00:00 2001 From: "Casper V. Kristensen" Date: Fri, 3 Aug 2018 03:24:57 +0200 Subject: [PATCH] Make string matching in Steam and GOG store search case insensitive. --- dailyreleases/gog.py | 16 +++++++--------- dailyreleases/steam.py | 13 ++++--------- dailyreleases/util.py | 11 +++++++++++ 3 files changed, 22 insertions(+), 18 deletions(-) create mode 100644 dailyreleases/util.py diff --git a/dailyreleases/gog.py b/dailyreleases/gog.py index 3ded6a7..0545640 100644 --- a/dailyreleases/gog.py +++ b/dailyreleases/gog.py @@ -1,6 +1,7 @@ -import difflib import logging +from dailyreleases import util + logger = logging.getLogger(__name__) @@ -14,18 +15,15 @@ class GOG(object): "limit": 5, "search": query } - results = self.cache.get("https://www.gog.com/games/ajax/filtered", params=payload).json()["products"] + products = {p["title"]: p + for p in self.cache.get("https://www.gog.com/games/ajax/filtered", params=payload).json()["products"] + if p["isGame"]} - best_match = difflib.get_close_matches(query, - [r["title"] for r in results if r["isGame"]], - n=1, - cutoff=0.90) + best_match = util.case_insensitive_close_matches(query, products, n=1, cutoff=0.90) if not best_match: logger.debug("Unable to find %s in GOG search results", query) return logger.debug("Best match is '%s'", best_match[0]) - return next("https://gog.com{}".format(r["url"]) - for r in results - if r["title"] == best_match[0]) + return "https://gog.com{url}".format(**products[best_match[0]]) diff --git a/dailyreleases/steam.py b/dailyreleases/steam.py index adc0ac7..2ded1f9 100644 --- a/dailyreleases/steam.py +++ b/dailyreleases/steam.py @@ -1,4 +1,3 @@ -import difflib import logging logger = logging.getLogger(__name__) @@ -51,18 +50,14 @@ class Steam(object): payload = { "term": query } - results = self.cache.get("https://store.steampowered.com/api/storesearch", params=payload).json()["items"] + items = {i["name"]: i for i in self.cache.get("https://store.steampowered.com/api/storesearch", + params=payload).json()["items"]} - best_match = difflib.get_close_matches(query, - [r["name"] for r in results], - n=1, - cutoff=0.90) + best_match = util.case_insensitive_close_matches(query, items, n=1, cutoff=0.90) if not best_match: logger.debug("Unable to find %s in Steam search results", query) return logger.debug("Best match is '%s'", best_match[0]) - return next("https://store.steampowered.com/{}/{}".format(r["type"], r["id"]) - for r in results - if r["name"] == best_match[0]) + return "https://store.steampowered.com/{type}/{id}".format(**items[best_match[0]]) diff --git a/dailyreleases/util.py b/dailyreleases/util.py new file mode 100644 index 0000000..cb59b0b --- /dev/null +++ b/dailyreleases/util.py @@ -0,0 +1,11 @@ +import difflib + + +def case_insensitive_close_matches(word, possibilities, n=3, cutoff=0.6): + """ + Python's difflib.get_close_matches does case sensitive sequence matching, this function decorates the library + function to make it case insensitive. + """ + possibilities = {sequence.lower(): sequence for sequence in possibilities} + close_matches = difflib.get_close_matches(word.lower(), possibilities, n=n, cutoff=cutoff) + return [possibilities[m] for m in close_matches]