Ejemplo n.º 1
0
def ud(query, res):
    u = f'http://api.urbandictionary.com/v0/define?term={query}'
    r = requests.get(u, timeout=30)
    j = r.json()['list'][res]
    word = j['word']
    definition = p_truncate(j['definition'], msg_len, 71, True)
    example = p_truncate(j['example'], msg_len, 15, True)
    author = j['author']
    t_up = j['thumbs_up']
    t_down = j['thumbs_down']
    pl = j['permalink'].rsplit('/', 1)[0]
    return (word, definition, example, author, t_up, t_down, pl)
Ejemplo n.º 2
0
def mw_parse_section(url, section_list, page, sect, limit):
    '''
    Uses the MediaWiki API:Parsing_wikitext#parse
    https://www.mediawiki.org/wiki/Special:MyLanguage/API:Parsing_wikitext#parse

    This function finds the position of the section ('sect')
    requested in 'section_list' and calls the MediaWiki API,
    which returns a JSON document containing the html of the
    requested section which is parsed by beautifulsoup4,
    limited to the specified amount of characters and returned.

    'url' is the url of the MediaWiki website
    'section_list' is the second item returned by mw_list_sections()
    'page' should be the name of the MediaWiki article as
    returned by mw_opensearch()
    'sect' is the section requested to be viewed
    'limit' if True truncate the text
    '''
    id_index = section_list[0].index(sect)
    u = (f'{url}/w/api.php'
         '?action=parse&format=json&prop=text'
         f'&section={section_list[1][id_index]}&page={page}')
    r = requests.get(u, timeout=r_timeout)
    html = r.json()['parse']['text']['*']
    soup = bs4.BeautifulSoup(html, bs4_parser)
    soup = text_cleanup(soup)
    text = soup.find('span', id=sect)
    text = text.find_next('p').text
    if limit:
        text = p_truncate(text, msg_len, 85, True)
    return text
Ejemplo n.º 3
0
def mw_parse_intro(url, page, limit):
    '''
    Uses the MediaWiki API:Parsing_wikitext#parse
    https://www.mediawiki.org/wiki/Special:MyLanguage/API:Parsing_wikitext#parse

    This function calls the MediaWiki API, which returns a JSON
    document containing the html of the introduction section
    of an article, which is parsed by beautifulsoup4, limited
    to the specified amount of characters and returned.

    'url' is the url of the MediaWiki website
    'page' should be the name of the MediaWiki article as
    returned by mw_opensearch()
    'limit' if True truncate the text
    '''
    u = (f'{url}/w/api.php'
         f'?action=parse&format=json&prop=text&section=0&page={page}')
    r = requests.get(u, timeout=r_timeout)
    html = r.json()['parse']['text']['*']
    soup = bs4.BeautifulSoup(html, bs4_parser)
    soup = text_cleanup(soup)
    text = soup.find('p').text
    if text == 'Redirect to:':
        n_title = soup.find('a').text
        n_text = mw_parse_intro(url, n_title, limit)
        text = f'\x0302[Redirect to: {n_title}]\x0F {n_text}'
    if limit:
        text = p_truncate(text, msg_len, 85, True)
    return text
Ejemplo n.º 4
0
def main(i, irc):
    msgtarget = i.msg.get_msgtarget()
    nickname = i.msg.get_nickname()
    botcmd = i.msg.get_botcmd()
    prefix = i.msg.get_botcmd_prefix()
    args = i.msg.get_args()

    if not args:
        m = (f'Usage: {prefix}{botcmd} <Word> [-e <NUM>]')
        irc.out.notice(msgtarget, m)
        return

    argv = args.split()

    if '-e' in argv:
        idx = argv.index('-e')
        res = int(argv[idx + 1])
    else:
        res = 1

    q = search_query(argv)
    q_web = q.replace(" ", "_")
    url = f"https://en.wiktionary.org/wiki/{q_web}"
    result = wiktionary(url, res)
    result_length = len(result)

    if res not in range(1, result_length + 1):
        m = f'Wiktionary: No definition was found for "{q}" | {url}'
        irc.out.notice(msgtarget, m)
        return

    try:
        result = result[f"Etymology_{res}"]
    except KeyError:
        result = result["Etymology"]

    msg_len = (irc.msg_len - 9 - 8 - len(str(result_length)) -
               (len(result) * 5) - len(url))
    p_tr_percent = 100 / len(result)

    txt = ""
    for part, cont in result.items():
        rslt = f"{part}: {cont}"
        if nickname != msgtarget:
            rslt = p_truncate(rslt, msg_len, p_tr_percent, True)
        txt += f"{rslt} | "

    rpl = f"{q} | {txt}({result_length}) | {url}"
    irc.out.notice(msgtarget, rpl)
Ejemplo n.º 5
0
def main(i, irc):
    if not i.msg_nocmd:
        msg = (f'Usage: {i.cmd_prefix}{i.cmd} <Word> [-e <NUM>]')
        return irc.privmsg(i.channel, msg)

    args = i.msg_nocmd.split()

    if '-e' in args:
        idx = args.index('-e')
        res = int(args[idx + 1])
    else:
        res = 1

    q = query(args)
    q_web = q.replace(" ", "_")
    url = f"https://en.wiktionary.org/wiki/{q_web}"
    result = wiktionary(url, res)
    result_length = len(result)

    if res not in range(1, result_length + 1):
        msg = f'Wiktionary: No definition was found for "{q}" | {url}'
        return irc.privmsg(i.channel, msg)

    if res == 1:
        try:
            result = result["Etymology"]
        except KeyError:
            result = result["Etymology_1"]
    else:
        result = result[f"Etymology_{res}"]

    msg_len = (irc.var.msg_len - 9 - 8 - len(str(result_length))
               - (len(result) * 5) - len(url))
    p_tr_percent = 100 / len(result)

    txt = ""
    for part, cont in result.items():
        rslt = f"{part}: {cont}"
        if not i.nickname == i.channel:
            rslt = p_truncate(rslt, msg_len, p_tr_percent, True)
        txt += f"{rslt} | "

    rpl = f"{q} | {txt}({result_length}) | {url}"
    irc.privmsg(i.channel, rpl)
Ejemplo n.º 6
0
def main(i, irc):
    sed_parse = re.compile('(?<!\\\\)/')
    sed_cmd = re.compile('^s/.*/.*')
    sed_out = ''

    if not sed_cmd.match(i.msg):
        write(i.varget, i.varset, i.channel, i.msg)
        return

    sed_args = sed_parse.split(i.msg)

    if len(sed_args) < 4:
        # check if the last / is missed etc.
        return

    msglist = read(i.varget, i.channel)

    # Extension to allow the user match previous messages.
    # It uses the special syntax: "s///-n" where n is the
    # number of matches to skip.
    # Sideffect: because it matches upto two decimals after -,
    #            sed string positioning (or other commands
    #            with decimals in them) should be issued
    #            before the - command or two characters after
    #            the - .
    # The following code is for parsing the command. It
    # edits the "goback" variable which will be used in the
    # loop below.
    # We use two decimals because the queue save upto 50
    # messages.
    goback = False
    if '-' in sed_args[3]:
        s = sed_args[3]
        idx = s.index('-')
        if len(s[idx:]) > 2 and s[idx + 2].isdecimal():
            goback = int(f'{s[idx + 1]}{s[idx + 2]}')
            sed_args[3] = f'{s[:idx]}{s[idx + 3:]}'
        elif len(s[idx:]) > 1 and s[idx + 1].isdecimal():
            goback = int(s[idx + 1])
            sed_args[3] = f'{s[:idx]}{s[idx + 2:]}'

    n = 1
    while n <= 50:
        if 'i' in sed_args[3]:
            db_search = re.search(sed_args[1], msglist[-n], re.I)
        else:
            db_search = re.search(sed_args[1], msglist[-n])
        if db_search:
            if goback:
                # Check if the goback command was issued.
                goback -= 1
                n = n + 1
                continue
            a = n
            break
        else:
            a = False
        n = n + 1

    if a:
        if '\x01ACTION' in msglist[-a][:7]:
            msg_len = irc.var.msg_len - 9 - len(i.channel) - 10 - 2
            sed_out = call_sed(msglist[-a][7:], sed_args)
            sed_out = sed_out.rstrip('\n').replace('\x01',
                                                   "").replace('\ca', "")
            sed_out = p_truncate(sed_out, msg_len, 98, True)
            irc.privmsg(i.channel, f'\x01ACTION {sed_out}')
        else:
            msg_len = irc.var.msg_len - 9 - len(i.channel) - 2
            sed_out = call_sed(msglist[-a], sed_args).strip()
            sed_out = sed_out.rstrip('\n').replace('\x01',
                                                   "").replace('\ca', "")
            sed_out = p_truncate(sed_out, msg_len, 98, True)
            irc.privmsg(i.channel, sed_out)

    if sed_out:
        # We try to limit the string saved in the queue to avoid:
        # OSError: [Errno 7] Argument list too long: 'echo'
        # when calling 'echo' in @call_sed .
        # 512 chars are more than enough, since the bot will
        # never be able to send a message with that many.
        write(i.varget, i.varset, i.channel, sed_out)
Ejemplo n.º 7
0
def main(i, irc):
    nickname = i.msg.get_nickname()
    msgtarget = i.msg.get_msgtarget()
    text = i.msg.get_text()

    if not sed_cmd.match(text):
        write(i.varget, i.varset, msgtarget, text)
        return

    sed_out = ""
    sed_args = sed_parse.split(text)

    if len(sed_args) < 4:
        # check if the last / is missed etc.
        return

    msglist = read(i.varget, msgtarget)

    # Extension to allow the user match previous messages.
    # It uses the special syntax: "s///-n" where n is the
    # number of matches to skip.
    # Sideffect: because it matches upto two decimals after -,
    #            sed string positioning (or other commands
    #            with decimals in them) should be issued
    #            before the - command or two characters after
    #            the - .
    # The following code is for parsing the command. It
    # edits the "goback" variable which will be used in the
    # loop below.
    # We use two decimals because the queue save upto 50
    # messages.
    goback = False
    if '-' in sed_args[3]:
        s = sed_args[3]
        idx = s.index('-')
        if len(s[idx:]) > 2 and s[idx + 2].isdecimal():
            goback = int(f'{s[idx + 1]}{s[idx + 2]}')
            sed_args[3] = f'{s[:idx]}{s[idx + 3:]}'
        elif len(s[idx:]) > 1 and s[idx + 1].isdecimal():
            goback = int(s[idx + 1])
            sed_args[3] = f'{s[:idx]}{s[idx + 2:]}'

    n = 1
    while n <= 50:
        flags = 0
        if 'i' in sed_args[3]:
            flags |= re.I

        try:
            db_search = re.search(sed_args[1], msglist[-n], flags)
        except re.error as e:  # Invalid pattern given
            irc.out.notice(nickname, f"sed: regexp error: {e}")
            return

        if db_search:
            if goback:
                # Check if the goback command was issued.
                goback -= 1
                n = n + 1
                continue
            a = n
            break
        else:
            a = False
        n = n + 1

    if a:
        if "\x01ACTION " in msglist[-a][:8]:
            msg_len = irc.msg_len - 9 - len(msgtarget) - 10 - 2
            sed_out = call_sed(msglist[-a][8:], sed_args).strip()
            sed_out = sed_out.rstrip('\n').replace('\x01', "")
            sed_out = p_truncate(sed_out, msg_len, 98, True)
            irc.out.privmsg(msgtarget, f"\x01ACTION {sed_out}\x01")
        else:
            msg_len = irc.msg_len - 9 - len(msgtarget) - 2
            sed_out = call_sed(msglist[-a], sed_args).strip()
            sed_out = sed_out.rstrip('\n').replace('\x01', "")
            sed_out = p_truncate(sed_out, msg_len, 98, True)
            irc.out.privmsg(msgtarget, sed_out)

    if sed_out:
        # We try to limit the string saved in the queue to avoid:
        # OSError: [Errno 7] Argument list too long: 'echo'
        # when calling 'echo' in @call_sed .
        # 512 chars are more than enough, since the bot will
        # never be able to send a message with that many.
        write(i.varget, i.varset, msgtarget, sed_out)