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))
Exemple #2
0
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}"
Exemple #5
0
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)
Exemple #9
0
def command_giphy(text, **kwargs):
    if not text:
        return PrivateResponse("Usage: `/giphy *search_string*`")

    return giphy.gif_search(text)