|
@@ -20,13 +20,15 @@ |
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
|
# SOFTWARE. |
|
|
# SOFTWARE. |
|
|
|
|
|
|
|
|
|
|
|
import re |
|
|
|
|
|
|
|
|
from earwigbot import exceptions |
|
|
from earwigbot import exceptions |
|
|
from earwigbot.commands import Command |
|
|
from earwigbot.commands import Command |
|
|
|
|
|
|
|
|
class Dictionary(Command): |
|
|
class Dictionary(Command): |
|
|
"""Define words and stuff.""" |
|
|
"""Define words and stuff.""" |
|
|
name = "dictionary" |
|
|
name = "dictionary" |
|
|
commands = ["dict", "dictionary"] |
|
|
|
|
|
|
|
|
commands = ["dict", "dictionary", "define"] |
|
|
|
|
|
|
|
|
def process(self, data): |
|
|
def process(self, data): |
|
|
if not data.args: |
|
|
if not data.args: |
|
@@ -41,7 +43,7 @@ class Dictionary(Command): |
|
|
msg = "cannot find a {0}-language Wiktionary." |
|
|
msg = "cannot find a {0}-language Wiktionary." |
|
|
self.reply(data, msg.format(lang)) |
|
|
self.reply(data, msg.format(lang)) |
|
|
else: |
|
|
else: |
|
|
self.reply(data, "{0}: {1}".format(term, defined.encode("utf8"))) |
|
|
|
|
|
|
|
|
self.reply(data, defined.encode("utf8")) |
|
|
|
|
|
|
|
|
def define(self, term, lang): |
|
|
def define(self, term, lang): |
|
|
try: |
|
|
try: |
|
@@ -55,4 +57,93 @@ class Dictionary(Command): |
|
|
except (exceptions.PageNotFoundError, exceptions.InvalidPageError): |
|
|
except (exceptions.PageNotFoundError, exceptions.InvalidPageError): |
|
|
return "no definition found." |
|
|
return "no definition found." |
|
|
|
|
|
|
|
|
return entry |
|
|
|
|
|
|
|
|
languages = self.get_languages(entry) |
|
|
|
|
|
if not languages: |
|
|
|
|
|
return u"couldn't parse {0}!".format(page.url) |
|
|
|
|
|
|
|
|
|
|
|
result = [] |
|
|
|
|
|
for lang, section in sorted(languages.items()): |
|
|
|
|
|
this = u"({0}) {1}".format(lang, self.get_definition(section)) |
|
|
|
|
|
result.append(this) |
|
|
|
|
|
return u"; ".join(result) |
|
|
|
|
|
|
|
|
|
|
|
def get_languages(self, entry): |
|
|
|
|
|
regex = r"(?:\A|\n)==\s*([a-zA-Z0-9_ ]*?)\s*==(?:\Z|\n)" |
|
|
|
|
|
split = re.split(regex, entry) |
|
|
|
|
|
if len(split) % 2 == 0: |
|
|
|
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
split.pop(0) |
|
|
|
|
|
languages = {} |
|
|
|
|
|
for i in xrange(0, len(split), 2): |
|
|
|
|
|
languages[split[i]] = split[i + 1] |
|
|
|
|
|
return languages |
|
|
|
|
|
|
|
|
|
|
|
def get_definition(self, section): |
|
|
|
|
|
parts_of_speech = { |
|
|
|
|
|
"v.": "Verb", |
|
|
|
|
|
"n.": "Noun", |
|
|
|
|
|
"pron.": "Pronoun", |
|
|
|
|
|
"adj.": "Adjective", |
|
|
|
|
|
"adv.": "Adverb", |
|
|
|
|
|
"prep.": "Preposition", |
|
|
|
|
|
"conj.": "Conjunction", |
|
|
|
|
|
"inter.": "Interjection", |
|
|
|
|
|
"symbol": "Symbol", |
|
|
|
|
|
"suffix": "Suffix", |
|
|
|
|
|
"initialism": "Initialism", |
|
|
|
|
|
"phrase": "Phrase", |
|
|
|
|
|
"proverb": "Proverb", |
|
|
|
|
|
} |
|
|
|
|
|
defs = [] |
|
|
|
|
|
for part, fullname in parts_of_speech.iteritems(): |
|
|
|
|
|
if re.search("===\s*" + fullname + "\s*===", section): |
|
|
|
|
|
regex = "===\s*" + fullname + "\s*===(.*?)(?:(?:===)|\Z)" |
|
|
|
|
|
body = re.findall(regex, section, re.DOTALL) |
|
|
|
|
|
if body: |
|
|
|
|
|
definition = self.parse_body(body[0]) |
|
|
|
|
|
if definition: |
|
|
|
|
|
defs.append("\x02{0}\x0F {1}".format(part, definition)) |
|
|
|
|
|
|
|
|
|
|
|
return "; ".join(defs) |
|
|
|
|
|
|
|
|
|
|
|
def parse_body(self, body): |
|
|
|
|
|
senses = [] |
|
|
|
|
|
for line in body.splitlines(): |
|
|
|
|
|
line = line.strip() |
|
|
|
|
|
if re.match("#\s*[^:*]", line): |
|
|
|
|
|
line = re.sub("\[\[(.*?)\|(.*?)\]\]", r"\2", line) |
|
|
|
|
|
line = self.strip_templates(line) |
|
|
|
|
|
line = line[1:].replace("'''", "").replace("''", "") |
|
|
|
|
|
line = line.replace("[[", "").replace("]]", "") |
|
|
|
|
|
senses.append(line.strip()) |
|
|
|
|
|
|
|
|
|
|
|
if not senses: |
|
|
|
|
|
return None |
|
|
|
|
|
if len(senses) == 1: |
|
|
|
|
|
return senses[0] |
|
|
|
|
|
|
|
|
|
|
|
result = [] # Number the senses incrementally |
|
|
|
|
|
for i, sense in enumerate(senses): |
|
|
|
|
|
result.append(u"{0}. {1}".format(i + 1, sense)) |
|
|
|
|
|
return " ".join(result) |
|
|
|
|
|
|
|
|
|
|
|
def strip_templates(self, line): |
|
|
|
|
|
line = list(line) |
|
|
|
|
|
stripped = "" |
|
|
|
|
|
depth = 0 |
|
|
|
|
|
while line: |
|
|
|
|
|
this = line.pop(0) |
|
|
|
|
|
if line: |
|
|
|
|
|
next = line[0] |
|
|
|
|
|
else: |
|
|
|
|
|
next = "" |
|
|
|
|
|
if this == "{" and next == "{": |
|
|
|
|
|
line.pop(0) |
|
|
|
|
|
depth += 1 |
|
|
|
|
|
elif this == "}" and next == "}": |
|
|
|
|
|
line.pop(0) |
|
|
|
|
|
depth -= 1 |
|
|
|
|
|
elif depth == 0: |
|
|
|
|
|
stripped += this |
|
|
|
|
|
return stripped |