def gif_search(search_string): logger.info("Searching Giphy for: %s", search_string) param = { "api_key": config.GIPHY_API_KEY, "rating": config.GIPHY_RATING, "limit": config.GIPHY_POOL, "q": search_string } try: response = get("http://api.giphy.com/v1/gifs/search", param) response.raise_for_status() results = response.json().get('data', []) except Exception: logger.exception("Bad response from API") return PrivateResponse("API error, please try again later") try: selected = random.choice(results) except IndexError: return PrivateResponse("No matches for: {}".format(search_string)) logger.info("Selected %s (from %d items)", selected["url"], len(results)) try: image_url = _get_image_url(selected["images"]) except Exception: logger.exception("Unable to extract image url") return PrivateResponse("API error, please try again later") title = selected.get("title", "_gif_") user = selected.get("user", {}) info = [] if user.get("display_name"): info.append("Via: {}".format(user["display_name"])) if selected.get("source_tld"): info.append("Source: {}".format(selected["source_tld"])) if "rating" in selected: info.append("[{}]".format(selected["rating"])) return IndirectResponse( feedback=True, # Echo command invokation to channel indirect=Attachment(title=html.unescape(title), title_link=selected["url"], fallback=title, text=html.unescape(", ".join(info)), image_url=image_url))
def command_replygif(text, **kwargs): tags = [s.strip() for s in text.split(",")] if not tags[0]: return PrivateResponse( "Usage: `/replygif *tag* [, *tag2*, *tag3*, ...]`") return replygif.gif_search(tags)
def unregister_unit(name): logger.info("Unregistering unit: %s", name) try: definition = redis.hget(UNIT_KEY, name) if not definition: return PrivateResponse(f"Custom unit {name} is not defined") redis.hdel(UNIT_KEY, name) logger.warning("Removed custom unit: %s = %s", name, definition) return f"Removed custom unit: {name}" except Exception: logger.exception("Unable to unregister unit: %s", name) return PrivateResponse("Internal error")
def unit_converter(src, dest): logger.info("Converting %s to %s", src, dest) try: units = _load_units() except Exception: logger.exception("Unable to load units") return PrivateResponse("Internal error") try: src_unit = units(src) result = src_unit.to(units(dest)) except Exception as e: logger.warning("Conversion failed: %r", e) return PrivateResponse(f"Conversion failed: {e}") logger.debug("Conversion result: %s", result) neat_result = f"{result.m:.02f}".rstrip('0').rstrip('.') return f"{src_unit!s} =~ {neat_result} {result.u}"
def gif_search(tags): try: matched_tags = fuzzy_match(tags) except Exception as e: return PrivateResponse(str(e)) logger.info("Searching ReplyGif for tags: %s", matched_tags) try: response = get("http://replygif.net/api/gifs", { "api-key": config.REPLYGIF_API_KEY, "tag-operator": "and", "tag": ",".join(matched_tags) }) response.raise_for_status() results = response.json() except Exception: logger.exception("Bad response from API: %r", response) return PrivateResponse("API error, please try again later") try: replygif = random.choice(results) except IndexError: return PrivateResponse("No matches for tags: {}".format(matched_tags)) logger.info("Selected %s (from %d items)", replygif["url"], len(results)) title = "#{}".format(replygif["id"]) if replygif["caption"]: title += ": {}".format(replygif["caption"]) return IndirectResponse( feedback=True, # Echo command invokation to channel indirect=Attachment( title=html.unescape(title), title_link=replygif["url"], fallback=title, text=html.unescape(", ".join(replygif["tags"])), image_url=replygif["file"]))
def register_unit(name, conversion): logger.info("Registering unit: %s = %s", name, conversion) if not name.isalpha(): return PrivateResponse("Custom units can only contain letters") if conversion.startswith("birthday "): try: raw_date = conversion.split(" ")[1].strip() birthday = date.fromisoformat(raw_date) except Exception: logger.exception("Unable to parse birthday: %s", conversion) return PrivateResponse("birthdays must be iso-formatted") # Converted to seconds from now in _load_units() definition = f"__age {birthday}" else: # Custom units must map to standard units try: units = UnitRegistry() to_unit = units(conversion) except UndefinedUnitError: return PrivateResponse(f"Unknown conversion unit: {conversion}") definition = f"{to_unit.m} {to_unit.u}" try: redis.hset(UNIT_KEY, name, definition) except Exception: logger.exception("Unable to register unit: %s = %s", name, definition) return PrivateResponse("Internal error") return f"New unit defined: {name}"
def command_define(text, **kwargs): parser = InlineArgumentParser(prog="/define", add_help=False) parser.add_argument("-u", action="store_true", dest="undefine", help="Undefine a custom unit") parser.add_argument("definition", type=str, nargs="+", help="Definition") try: parsed = parser.parse_args(text.split()) args = " ".join(parsed.definition) except Exception: return PrivateResponse(parser.format_usage()) if parsed.undefine: return convert.unregister_unit(args) try: name, conversion = args.split(" = ") return convert.register_unit(name, conversion) except Exception: return PrivateResponse("Usage: `/define *new_unit* = *qty* *unit*`")
def command_convert(text, **kwargs): parser = InlineArgumentParser(prog="/convert", add_help=False) parser.add_argument("args", type=str, nargs="+", help="*qty* *unit* to *unit*") try: parsed = parser.parse_args(text.split()) args = " ".join(parsed.args) src, dest = args.split(' to ') except Exception: return PrivateResponse(parser.format_usage()) else: return convert.unit_converter(src, dest)
def command_giphy(text, **kwargs): if not text: return PrivateResponse("Usage: `/giphy *search_string*`") return giphy.gif_search(text)