mirror of
https://github.com/oddluck/limnoria-plugins.git
synced 2025-04-25 12:31:07 -05:00
215 lines
8.2 KiB
Python
215 lines
8.2 KiB
Python
###
|
|
# Copyright (c) 2013, spline
|
|
# Copyright (c) 2020, oddluck <oddluck@riseup.net>
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions are met:
|
|
#
|
|
# * Redistributions of source code must retain the above copyright notice,
|
|
# this list of conditions, and the following disclaimer.
|
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
# this list of conditions, and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
# * Neither the name of the author of this software nor the name of
|
|
# contributors to this software may be used to endorse or promote products
|
|
# derived from this software without specific prior written consent.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
# POSSIBILITY OF SUCH DAMAGE.
|
|
###
|
|
|
|
from __future__ import unicode_literals
|
|
|
|
# my libs
|
|
import json
|
|
import re
|
|
|
|
# supybot libs
|
|
import supybot.utils as utils
|
|
from supybot.commands import *
|
|
import supybot.plugins as plugins
|
|
import supybot.ircutils as ircutils
|
|
import supybot.callbacks as callbacks
|
|
from supybot.i18n import PluginInternationalization, internationalizeDocstring
|
|
|
|
_ = PluginInternationalization("UrbanDictionary")
|
|
|
|
|
|
@internationalizeDocstring
|
|
class UrbanDictionary(callbacks.Plugin):
|
|
"""Add the help for "@plugin help UrbanDictionary" here
|
|
This should describe *how* to use this plugin."""
|
|
|
|
threaded = True
|
|
|
|
######################
|
|
# INTERNAL FUNCTIONS #
|
|
######################
|
|
|
|
def _red(self, string):
|
|
"""return a red string."""
|
|
return ircutils.mircColor(string, "red")
|
|
|
|
def _bu(self, string):
|
|
"""bold and underline string."""
|
|
return ircutils.bold(ircutils.underline(string))
|
|
|
|
def cleanjson(self, s):
|
|
"""clean up json and return."""
|
|
|
|
s = s.replace("\n", "")
|
|
s = s.replace("\r", "")
|
|
s = s.replace("\t", "")
|
|
s = s.strip()
|
|
# return
|
|
return s
|
|
|
|
####################
|
|
# PUBLIC FUNCTIONS #
|
|
####################
|
|
|
|
def urbandictionary(self, irc, msg, args, optlist, optterm):
|
|
"""[--disableexamples | --showvotes | --num # | --showtags] <term>
|
|
|
|
Fetches definition for <term> on UrbanDictionary.com
|
|
|
|
Use --disableexamples to not display examples.
|
|
Use --showvotes to show votes [default: off]
|
|
Use --num # to limit the number of definitions. [default:10]
|
|
Use --showtags to display tags (if available)
|
|
"""
|
|
|
|
# default args for output. can manip via --getopts.
|
|
args = {
|
|
"showExamples": True,
|
|
"numberOfDefinitions": self.registryValue("maxNumberOfDefinitions"),
|
|
"showVotes": False,
|
|
"showTags": False,
|
|
}
|
|
# optlist to change args.
|
|
if optlist:
|
|
for (key, value) in optlist:
|
|
if key == "disableexamples":
|
|
args["showExamples"] = False
|
|
if key == "showvotes":
|
|
args["showVotes"] = True
|
|
if key == "showtags":
|
|
args["showTags"] = True
|
|
if key == "num": # if number is >, default to config var.
|
|
if 0 <= value <= self.registryValue("maxNumberOfDefinitions"):
|
|
args["numberOfDefinitions"] = value
|
|
# build and fetch url.
|
|
url = "http://api.urbandictionary.com/v0/define?term=%s" % utils.web.urlquote(
|
|
optterm
|
|
)
|
|
try:
|
|
html = utils.web.getUrl(url)
|
|
except utils.web.Error as e:
|
|
self.log.error("ERROR opening {0} message: {1}".format(url, e))
|
|
irc.reply("ERROR: could not open {0} message: {1}".format(url, e))
|
|
return
|
|
# try parsing json.
|
|
# irc.reply("{0}".format(self._repairjson(html.decode('utf-8'))))
|
|
try:
|
|
# jsondata = self._repairjson(html.decode('utf-8')) # decode utf-8. fix \r\n that ud puts in below.
|
|
jsondata = html.decode()
|
|
jsondata = json.loads(jsondata) # odds chars in UD.
|
|
except Exception as e:
|
|
self.log.error("Error parsing JSON from UD: {0}".format(e))
|
|
irc.reply("ERROR: Failed to parse json data. Check logs for error")
|
|
return
|
|
# process json.
|
|
results = jsondata.get("result_type") # exact, no_results, fulltext .
|
|
if not results:
|
|
# assume exact i guess...
|
|
results = "exact"
|
|
definitions = jsondata.get("list")
|
|
# prep output now depending on results.
|
|
if results == "exact": # we did not find anything.
|
|
outdefs = []
|
|
for i in definitions[
|
|
0 : args["numberOfDefinitions"]
|
|
]: # iterate through each def.
|
|
# clean these up.
|
|
definition = self.cleanjson(
|
|
"".join(i["definition"])
|
|
) # .encode('utf-8')
|
|
example = self.cleanjson("".join(i["example"]))
|
|
# now add
|
|
outputstring = "{0}".format(definition) # default string.
|
|
if args["showExamples"]: # show examples?
|
|
outputstring += " {0} {1} {2}".format(
|
|
self._bu("[ex:]"), example, self._bu("[/ex]")
|
|
)
|
|
if args["showVotes"]: # show votes?
|
|
outputstring += " (+{0}/-{1})".format(
|
|
i["thumbs_up"], i["thumbs_down"]
|
|
)
|
|
outdefs.append(outputstring) # add to our list.
|
|
output = " | ".join(
|
|
[item for item in outdefs]
|
|
) # create string with everything.
|
|
elif results == "fulltext": # not direct. yields related terms.
|
|
output = " | ".join(
|
|
sorted(set([item["word"] for item in definitions]))
|
|
) # sorted, unique words.
|
|
# output time.
|
|
if results == "no_results" or len(definitions) == 0: # NOTHING FOUND.
|
|
irc.reply("ERROR: '{0}' not defined on UrbanDictionary.".format(optterm))
|
|
return
|
|
else: # we have definitions, so we're gonna output.
|
|
# check if we should add tags.
|
|
if args["showTags"]: # display tags.
|
|
tags = jsondata.get("tags")
|
|
if tags: # we have tags. add it to optterm.
|
|
tags = " | ".join([i for i in tags])
|
|
else:
|
|
tags = False
|
|
else:
|
|
tags = False
|
|
# now lets output.
|
|
if self.registryValue("disableANSI"): # disable formatting.
|
|
if tags:
|
|
irc.reply(
|
|
"{0} :: {1} :: {2}".format(
|
|
optterm, tags, ircutils.stripFormatting(output)
|
|
)
|
|
)
|
|
else:
|
|
irc.reply(
|
|
"{0} :: {1}".format(optterm, ircutils.stripFormatting(output))
|
|
)
|
|
else: # colors.
|
|
if tags:
|
|
irc.reply(
|
|
"{0} :: {1} :: {2}".format(self._red(optterm), tags, output)
|
|
)
|
|
else:
|
|
irc.reply("{0} :: {1}".format(self._red(optterm), output))
|
|
|
|
urbandictionary = wrap(
|
|
urbandictionary,
|
|
[
|
|
getopts(
|
|
{"showtags": "", "showvotes": "", "num": "int", "disableexamples": ""}
|
|
),
|
|
"text",
|
|
],
|
|
)
|
|
|
|
|
|
Class = UrbanDictionary
|
|
|
|
|
|
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=250:
|