-1

I'm currently building a Python IRC bot. I've found some stuff that pulled data from bash.org and posted a random quote to the channel. I've tried modifying it to pull from another source - modifying the classes that it's looking at - but it ends up erroring out with a "maximum recursion depth exceeded while calling a Python object" error. I'm pulling my hair out at this point. Any suggestions would be helpful.

from plugins.util import command, get_url
from bs4 import BeautifulSoup


@command("q", "qdb")
def quote(m):
    """Return a quote from sysadmin quotes."""


    #- Post a quote from quote.org. If given a quote number, it will try to post it. Otherwise it
    #- will post a random quote. If the quote is too long, it will direct the user to the URL.
    #- Please note that there is no filtering here, so some of the quotes may be inappropriate.

    if len(m.line) > 1 and m.line[1].isnumeric():
        quote_specific(m, m.line[1])
    else:
        quote_rand(m)


def quote_rand(m):
    """Get a random quote from sysadmin quotes"""
    resp = get_url(m, "http://quotes.sysadmin.technology/?random1")
    soup = BeautifulSoup(resp)
    raw = soup.find(class_="quote_quote")
    if raw:
        meta = soup.find(class_="quote_option-bar")
        while True:
            if not raw:
                quote_rand(m)
                return
            lines = raw.get_text().splitlines()
            if len(lines) <= 5:
                break
            raw = raw.find_next(class_="quote_quote")
            meta = soup.find_next(class_="quote_option-bar")
        format_quote(m, lines, meta)
    else:
        m.bot.private_message(m.location, "Could not find quote.")


def quote_specific(m, number):
    """Get a specific quote from sysadmin quotes."""
    resp = get_url(m, "http://quotes.sysadmin.technology/?" + number)
    soup = BeautifulSoup(resp)
    raw = soup.find(class_="quote_qoute")
    if raw:
        meta = soup.find(class_="quote_option-bar")
        lines = raw.get_text().splitlines()
        if len(lines) > 5 and not m.is_pm:
            m.bot.private_message(m.location, "This quote is too long to post publicly, "
                                              "but you can view it at http://quotes.sysadmin.technology/?"
                                              "{}.".format(number))
        else:
            format_quote(m, lines, meta, number)
    else:
        m.bot.private_message(m.location, "Could not find quote.")


def format_quote(m, raw, meta, number=None):
    """Format the quote with some metadata."""
    try:
        score = meta.font.string
        score_str = "\x0304{}\x03".format(score) if "-" in score else "\x0303{}\x03".format(score)
        url = "http://quotes.sysadmin.technology/?" + (number if number else meta.b.string.strip("#"))
        meta_str = "--- {} ({}) {} ".format(meta.b.string, score_str, url)
    except AttributeError as e:
        if number:
            m.bot.private_message(m.location, "Could not find quote.")
        else:
            quote_rand(m)
    else:
        m.bot.private_message(m.location, meta_str.ljust(83, '-'))
        for line in raw:
            m.bot.private_message(m.location, line)
        m.bot.private_message(m.location, "-" * 80)
hiiambo
  • 85
  • 1
  • 8

1 Answers1

1

Python has a limited recursion depth, so for problems that might hit this limit, you better come up with an iterative version of your algorithm. If you are too lazy to do that and are sure that your recursion is always just slightly deeper than the default limit set by Python, you might get away by just changing this limit. How so? Head over to What is the maximum recursion depth in Python, and how to increase it?

Community
  • 1
  • 1
Dr. Jan-Philip Gehrcke
  • 29,627
  • 13
  • 79
  • 123