def gse(text): """<query> -- Returns first Google search result for <query>.""" if not dev_key: return "This command requires a Google Developers Console API key." if not cx: return "This command requires a custom Google Search Engine ID." parsed = requests.get(API_CS, params={ "cx": cx, "q": text, "key": dev_key }).json() try: result = parsed['items'][0] except KeyError: return "No results found." title = formatting.truncate_str(result['title'], 60) content = result['snippet'] if not content: content = "No description available." else: content = formatting.truncate_str(content.replace('\n', ''), 150) return u'{} -- \x02{}\x02: "{}"'.format(result['link'], title, content)
def test_truncate_str(): assert truncate(test_truncate_str_input, length=test_truncate_str_length_a) == test_truncate_str_result_a assert truncate(test_truncate_str_input, length=test_truncate_str_length_b) == test_truncate_str_result_b # compatibility assert truncate_str(test_truncate_str_input, length=test_truncate_str_length_a) == test_truncate_str_result_a assert truncate_str(test_truncate_str_input, length=test_truncate_str_length_b) == test_truncate_str_result_b
def issues(text): """<username|repo> [number] - gets issue [number]'s summary, or the open issue count if no issue is specified""" args = text.split() repo = args[0] if args[0] not in shortcuts else shortcuts[args[0]] issue = args[1] if len(args) > 1 else None if issue: r = requests.get('https://api.github.com/repos/{}/issues/{}'.format(repo, issue)) j = r.json() url = web.try_shorten(j['html_url'], service='git.io') number = j['number'] title = j['title'] summary = formatting.truncate_str(j['body'].split('\n')[0], 25) if j['state'] == 'open': state = '\x033\x02Opened\x02\x0f by {}'.format(j['user']['login']) else: state = '\x034\x02Closed\x02\x0f by {}'.format(j['closed_by']['login']) return 'Issue #{} ({}): {} | {}: {}'.format(number, state, url, title, summary) else: r = requests.get('https://api.github.com/repos/{}/issues'.format(repo)) j = r.json() count = len(j) if count is 0: return 'Repository has no open issues.' else: return 'Repository has {} open issues.'.format(count)
def drama(text): """<phrase> - gets the first paragraph of the Encyclopedia Dramatica article on <phrase>""" search_response = requests.get(api_url, params={"action": "opensearch", "search": text}) if search_response.status_code != requests.codes.ok: return "Error searching: {}".format(search_response.status_code) data = search_response.json() if not data[1]: return "No results found." article_name = data[1][0].replace(' ', '_') url = ed_url + parse.quote(article_name, '') page_response = requests.get(url) if page_response.status_code != requests.codes.ok: return "Error getting page: {}".format(search_response.status_code) page = html.fromstring(page_response.text) for p in page.xpath('//div[@id="bodyContent"]/p'): if p.text_content(): summary = " ".join(p.text_content().splitlines()) summary = re.sub("\[\d+\]", "", summary) summary = formatting.truncate_str(summary, 220) return "{} - {}".format(summary, url) return "Unknown Error."
def rss(text, message): """rss <feed> -- Gets the first three items from the RSS feed <feed>.""" limit = 3 # preset news feeds strip = text.lower().strip() if strip == "bukkit": feed = "http://dl.bukkit.org/downloads/craftbukkit/feeds/latest-rb.rss" limit = 1 elif strip == "xkcd": feed = "http://xkcd.com/rss.xml" elif strip == "ars": feed = "http://feeds.arstechnica.com/arstechnica/index" else: feed = text query = "SELECT title, link FROM rss WHERE url=@feed LIMIT @limit" result = web.query(query, {"feed": feed, "limit": limit}) if not result.rows: return "Could not find/read RSS feed." for row in result.rows: title = formatting.truncate_str(row["title"], 100) link = web.try_shorten(row["link"]) message("{} - {}".format(title, link))
def gse(text): """<query> -- Returns first Google search result for <query>.""" if not dev_key: return "This command requires a Google Developers Console API key." if not cx: return "This command requires a custom Google Search Engine ID." parsed = requests.get(API_CS, params={ "cx": cx, "q": text, "key": dev_key }).json() if "error" in list(parsed) and len(parsed["error"]) > 0: return "Error: {}".format(parsed["error"]) try: result = parsed['items'][0] except KeyError: return "No results found." title = formatting.truncate_str(result['title'], 250) #content = result['snippet'] #if not content: # content = "" #else: # content = formatting.truncate_str(content.replace('\n', ''), 150) return u'{} [div] {}'.format(result['link'], title)
def suggest(text): """suggest <phrase> -- Gets suggested phrases for a google search""" params = {'output': 'json', 'client': 'hp', 'q': text} try: request = requests.get('http://google.com/complete/search', params=params) request.raise_for_status() except (requests.exceptions.HTTPError, requests.exceptions.ConnectionError) as e: return "Could not get suggestions: {}".format(e) page = request.text page_json = page.split('(', 1)[1][:-1] suggestions = json.loads(page_json)[1] suggestions = [suggestion[0] for suggestion in suggestions] if not suggestions: return 'no suggestions found' out = ", ".join(suggestions) # defuckify text (might not be needed now, but I'll keep it) soup = BeautifulSoup(out) out = soup.get_text() return formatting.truncate_str(out, 200)
def format_output(data): """ takes plugin data and returns two strings representing information about that plugin """ name = data["plugin_name"] description = formatting.truncate_str(data['description'], 30) url = data['website'] if data['authors']: authors = data['authors'][0] authors = authors[0] + "\u200b" + authors[1:] else: authors = "Unknown" stage = data['stage'] current_version = data['versions'][0] last_update = time.strftime('%d %B %Y %H:%M', time.gmtime(current_version['date'])) version_number = data['versions'][0]['version'] bukkit_versions = ", ".join(current_version['game_versions']) link = web.try_shorten(current_version['link']) if description: line_a = "\x02{}\x02, by \x02{}\x02 - {} - ({}) \x02{}".format(name, authors, description, stage, url) else: line_a = "\x02{}\x02, by \x02{}\x02 ({}) \x02{}".format(name, authors, stage, url) line_b = "Last release: \x02v{}\x02 for \x02{}\x02 at {} \x02{}\x02".format(version_number, bukkit_versions, last_update, link) return line_a, line_b
def wiki(text): """wiki <phrase> -- Gets first sentence of Wikipedia article on <phrase>.""" x = http.get_xml(search_url, search=text) ns = '{http://opensearch.org/searchsuggest2}' items = x.findall(ns + 'Section/' + ns + 'Item') if not items: if x.find('error') is not None: return 'error: %(code)s: %(info)s' % x.find('error').attrib else: return 'No results found.' def extract(item): return [item.find(ns + x).text for x in ('Text', 'Description', 'Url')] title, desc, url = extract(items[0]) if 'may refer to' in desc: title, desc, url = extract(items[1]) title = paren_re.sub('', title) if title.lower() not in desc.lower(): desc = title + desc desc = ' '.join(desc.split()) # remove excess spaces desc = formatting.truncate_str(desc, 200) return '{} :: {}'.format(desc, http.quote(url, ':/'))
def format_data(app_id, show_url=True): """ takes a steam appid and returns a formatted string with info :param appid: string :return: string """ params = {'appids': app_id} try: request = requests.get(API_URL, params=params) request.raise_for_status() except (requests.exceptions.HTTPError, requests.exceptions.ConnectionError) as e: return "Could not get game info: {}".format(e) data = request.json() game = data[app_id]["data"] out = [] # basic info out.append("\x02{}\x02".format(game["name"])) desc = formatting.strip_html(game["about_the_game"]) out.append(formatting.truncate_str(desc, 70)) # genres genres = ", ".join([g['description'] for g in game["genres"]]) out.append("\x02{}\x02".format(genres)) # release date if game['release_date']['coming_soon']: out.append("coming \x02{}\x02".format(game['release_date']['date'])) else: out.append("released \x02{}\x02".format(game['release_date']['date'])) # pricing if game['is_free']: out.append("\x02free\x02") else: price = game['price_overview'] if price['final'] == price['initial']: out.append("\x02$%d.%02d\x02" % divmod(price['final'], 100)) else: price_now = "$%d.%02d" % divmod(price['final'], 100) price_original = "$%d.%02d" % divmod(price['initial'], 100) out.append("\x02{}\x02 (was \x02{}\x02)".format(price_now, price_original)) if show_url: url = web.try_shorten(STORE_URL.format(game['steam_appid'])) out.append(url) return " - ".join(out)
def searchquote(text, message, db): """<text> - Returns IDs for quotes matching <text>.""" data = db.query(quotes) \ .filter(quotes.quote.like(f"%{text}%")) \ .all() if data: message(formatting.truncate_str("Quotes: {}".format( ', '.join([str(d.id) for d in data])), 350)) else: return "None found."
def google(text): """<query> - returns the first google search result for <query>""" parsed = api_get('web', text) if not 200 <= parsed['responseStatus'] < 300: raise IOError('error searching for pages: {}: {}'.format(parsed['responseStatus'], '')) if not parsed['responseData']['results']: return 'No results found.' result = parsed['responseData']['results'][0] title = http.unescape(result['titleNoFormatting']) title = formatting.truncate_str(title, 60) content = http.unescape(result['content']) if not content: content = "No description available." else: content = http.html.fromstring(content).text_content() content = formatting.truncate_str(content, 150).replace('\n', '') return '{} -- \x02{}\x02: "{}"'.format(result['unescapedUrl'], title, content)
def answer(text): """answer <query> -- find the answer to a question on Yahoo! Answers""" query = "SELECT Subject, ChosenAnswer, Link FROM answers.search WHERE query=@query LIMIT 1" result = web.query(query, {"query": text.strip()}).one() short_url = web.try_shorten(result["Link"]) # we split the answer and .join() it to remove newlines/extra spaces answer_text = formatting.truncate_str(' '.join(result["ChosenAnswer"].split()), 80) return '\x02{}\x02 "{}" - {}'.format(result["Subject"], answer_text, short_url)
def books(text): """books <query> -- Searches Google Books for <query>.""" if not dev_key: return "This command requires a Google Developers Console API key." json = requests.get(book_search_api, params={ "q": text, "key": dev_key, "country": "US" }).json() if json.get('error'): if json['error']['code'] == 403: print(json['error']['message']) return "The Books API is off in the Google Developers Console (or check the console)." else: return 'Error performing search.' if json['totalItems'] == 0: return 'No results found.' book = json['items'][0]['volumeInfo'] title = book['title'] try: author = book['authors'][0] except KeyError: try: author = book['publisher'] except KeyError: author = "Unknown Author" try: description = formatting.truncate_str(book['description'], 130) except KeyError: description = "No description available." try: year = book['publishedDate'][:4] except KeyError: year = "No Year" try: page_count = book['pageCount'] pages = ' - \x02{:,}\x02 page{}'.format(page_count, "s"[page_count == 1:]) except KeyError: pages = '' link = web.shorten(book['infoLink'], service="goo.gl", key=dev_key) return "\x02{}\x02 by \x02{}\x02 ({}){} - {} - {}".format( title, author, year, pages, description, link)
def bing(text, bot): """<query> - returns the first bing search result for <query>""" api_key = bot.config.get("api_keys", {}).get("bing_azure") # handle NSFW show_nsfw = text.endswith(" nsfw") # remove "nsfw" from the input string after checking for it if show_nsfw: text = text[:-5].strip().lower() rating = NSFW_FILTER if show_nsfw else DEFAULT_FILTER if not api_key: return "Error: No Bing Azure API details." # why are these all differing formats and why does format have a $? ask microsoft params = { "Sources": bingify("web"), "Query": bingify(text), "Adult": bingify(rating), "$format": "json" } request = requests.get(API_URL, params=params, auth=(api_key, api_key)) # I'm not even going to pretend to know why results are in ['d']['results'][0] j = request.json()['d']['results'][0] if not j["Web"]: return "No results." result = j["Web"][0] # not entirely sure this even needs un-escaping, but it wont hurt to leave it in title = formatting.truncate_str(unescape(result["Title"]), 60) desc = formatting.truncate_str(unescape(result["Description"]), 150) url = unescape(result["Url"]) return '{} -- \x02{}\x02: "{}"'.format(url, title, desc)
def gse(text): """<query> -- Returns first Google search result for <query>.""" if not dev_key: return "This command requires a Google Developers Console API key." if not cx: return "This command requires a custom Google Search Engine ID." parsed = requests.get(API_CS, params={"cx": cx, "q": text, "key": dev_key}).json() try: result = parsed['items'][0] except KeyError: return "No results found." title = formatting.truncate_str(result['title'], 60) content = result['snippet'] if not content: content = "No description available." else: content = formatting.truncate_str(content.replace('\n', ''), 150) return u'{} -- \x02{}\x02: "{}"'.format(result['link'], title, content)
def reddit(text): """<subreddit> [n] - gets a random post from <subreddit>, or gets the [n]th post in the subreddit""" id_num = None if text: # clean and split the input parts = text.lower().strip().split() # find the requested post number (if any) if len(parts) > 1: url = base_url.format(parts[0].strip()) try: id_num = int(parts[1]) - 1 except ValueError: return "Invalid post number." else: url = base_url.format(parts[0].strip()) else: url = "http://reddit.com/.json" try: data = http.get_json(url, user_agent=http.ua_chrome) except Exception as e: return "Error: " + str(e) data = data["data"]["children"] # get the requested/random post if id_num is not None: try: item = data[id_num]["data"] except IndexError: length = len(data) return "Invalid post number. Number must be between 1 and {}.".format(length) else: item = random.choice(data)["data"] item["title"] = formatting.truncate_str(item["title"], 50) item["link"] = short_url.format(item["id"]) raw_time = datetime.fromtimestamp(int(item["created_utc"])) item["timesince"] = timesince.timesince(raw_time) if item["over_18"]: item["warning"] = " \x02NSFW\x02" else: item["warning"] = "" return "\x02{title} : {subreddit}\x02 - posted by \x02{author}\x02" \ " {timesince} ago - {ups} upvotes, {downs} downvotes -" \ " {link}{warning}".format(**item)
def google(text): """<query> - returns the first google search result for <query>""" parsed = api_get('web', text) if not 200 <= parsed['responseStatus'] < 300: raise IOError('error searching for pages: {}: {}'.format( parsed['responseStatus'], '')) if not parsed['responseData']['results']: return 'No results found.' result = parsed['responseData']['results'][0] title = http.unescape(result['titleNoFormatting']) title = formatting.truncate_str(title, 60) content = http.unescape(result['content']) if not content: content = "No description available." else: content = http.html.fromstring(content).text_content() content = formatting.truncate_str(content, 150).replace('\n', '') return '{} -- \x02{}\x02: "{}"'.format(result['unescapedUrl'], title, content)
def wolframalpha(text, bot): """wa <query> -- Computes <query> using Wolfram Alpha.""" api_key = bot.config.get("api_keys", {}).get("wolframalpha", None) if not api_key: return "error: missing api key" url = 'http://api.wolframalpha.com/v2/query?format=plaintext' result = http.get_xml(url, input=text, appid=api_key) # get the URL for a user to view this query in a browser query_url = "http://www.wolframalpha.com/input/?i=" + \ http.quote_plus(text.encode('utf-8')) short_url = web.try_shorten(query_url) pod_texts = [] for pod in result.xpath("//pod[@primary='true']"): title = pod.attrib['title'] if pod.attrib['id'] == 'Input': continue results = [] for subpod in pod.xpath('subpod/plaintext/text()'): subpod = subpod.strip().replace('\\n', '; ') subpod = re.sub(r'\s+', ' ', subpod) if subpod: results.append(subpod) if results: pod_texts.append(title + ': ' + ', '.join(results)) ret = ' - '.join(pod_texts) if not pod_texts: return 'No results.' ret = re.sub(r'\\(.)', r'\1', ret) def unicode_sub(match): return chr(int(match.group(1), 16)) ret = re.sub(r'\\:([0-9a-z]{4})', unicode_sub, ret) ret = formatting.truncate_str(ret, 250) if not ret: return 'No results.' return "{} - {}".format(ret, short_url)
def get_steam_info(url): page = http.get(url) soup = BeautifulSoup(page, 'lxml', from_encoding="utf-8") data = {"name": soup.find('div', {'class': 'apphub_AppName'}).text, "desc": truncate_str(soup.find('meta', {'name': 'description'})['content'].strip(), 80)} # get the element details_block details = soup.find('div', {'class': 'details_block'}) # loop over every <b></b> tag in details_block for b in details.findAll('b'): # get the contents of the <b></b> tag, which is our title title = b.text.lower().replace(":", "") if title == "languages": # we have all we need! break # find the next element directly after the <b></b> tag next_element = b.nextSibling if next_element: # if the element is some text if isinstance(next_element, NavigableString): text = next_element.string.strip() if text: # we found valid text, save it and continue the loop data[title] = text continue else: # the text is blank - sometimes this means there are # useless spaces or tabs between the <b> and <a> tags. # so we find the next <a> tag and carry on to the next # bit of code below next_element = next_element.find_next('a', href=True) # if the element is an <a></a> tag if isinstance(next_element, Tag) and next_element.name == 'a': text = next_element.string.strip() if text: # we found valid text (in the <a></a> tag), # save it and continue the loop data[title] = text continue data["price"] = soup.find('div', {'class': 'game_purchase_price price'}).text.strip() return "\x02{name}\x02: {desc}, \x02Genre\x02: {genre}, \x02Release Date\x02: {release date}," \ " \x02Price\x02: {price}".format(**data)
def etymology(text, message): """<word> - Retrieves the etymology of chosen word.""" url = 'http://www.etymonline.com/search' try: params = {'q': text} h = http.get_html(url, params=params) except: return "Error fetching etymology." etym = h.xpath('//section') if not etym: return 'No etymology found for ' + text etym = etym[0].text_content() etym = ' '.join(etym.split()) message(formatting.truncate_str(etym, 400))
def soundcloud(url, api_key): data = http.get_json(api_url + '/resolve.json?' + urlencode({'url': url, 'client_id': api_key})) if data['description']: desc = ": {} ".format(formatting.truncate_str(data['description'], 50)) else: desc = "" if data['genre']: genre = "- Genre: \x02{}\x02 ".format(data['genre']) else: genre = "" url = web.try_shorten(data['permalink_url']) return "SoundCloud track: \x02{}\x02 by \x02{}\x02 {}{}- {} plays, {} downloads, {} comments - {}".format( data['title'], data['user']['username'], desc, genre, data['playback_count'], data['download_count'], data['comment_count'], url)
def books(text): """books <query> -- Searches Google Books for <query>.""" if not dev_key: return "This command requires a Google Developers Console API key." json = requests.get(book_search_api, params={"q": text, "key": dev_key, "country": "US"}).json() if json.get('error'): if json['error']['code'] == 403: print(json['error']['message']) return "The Books API is off in the Google Developers Console (or check the console)." else: return 'Error performing search.' if json['totalItems'] == 0: return 'No results found.' book = json['items'][0]['volumeInfo'] title = book['title'] try: author = book['authors'][0] except KeyError: try: author = book['publisher'] except KeyError: author = "Unknown Author" try: description = formatting.truncate_str(book['description'], 130) except KeyError: description = "No description available." try: year = book['publishedDate'][:4] except KeyError: year = "No Year" try: page_count = book['pageCount'] pages = ' - \x02{:,}\x02 page{}'.format(page_count, "s"[page_count == 1:]) except KeyError: pages = '' link = web.shorten(book['infoLink'], service="goo.gl", key=dev_key) return "\x02{}\x02 by \x02{}\x02 ({}){} - {} - {}".format(title, author, year, pages, description, link)
def google(text, message): """<query> - Returns first Google search result for <query>.""" api_key = bot.config.get_api_key("google") if not api_key: return "This command requires a Google Developers Console API key." try: parsed = custom_get(text, api_key) except Exception as e: return "Error: {}".format(e) if 'items' not in parsed: return "No results" link = web.try_shorten(parsed['items'][0]['link']) title = formatting.truncate_str(parsed['items'][0]['title'], 250) title = ' '.join(re.sub('\r|\n', ' ', title).split()).strip('| ') message(f"{link} - \x02{title}\x02")
def mcwiki(text): """mcwiki <phrase> - gets the first paragraph of the Minecraft Wiki article on <phrase>""" try: request = requests.get(api_url, params={'search': text.strip()}) request.raise_for_status() j = request.json() except (requests.exceptions.HTTPError, requests.exceptions.ConnectionError) as e: return "Error fetching search results: {}".format(e) except ValueError as e: return "Error reading search results: {}".format(e) if not j[1]: return "No results found." # we remove items with a '/' in the name, because # gamepedia uses sub-pages for different languages # for some stupid reason items = [item for item in j[1] if "/" not in item] if items: article_name = items[0].replace(' ', '_').encode('utf8') else: # there are no items without /, just return a / one article_name = j[1][0].replace(' ', '_').encode('utf8') url = mc_url + requests.utils.quote(article_name, '') try: request_ = requests.get(url) request_.raise_for_status() except (requests.exceptions.HTTPError, requests.exceptions.ConnectionError) as e: return "Error fetching wiki page: {}".format(e) page = html.fromstring(request_.text) for p in page.xpath('//div[@class="mw-content-ltr"]/p'): if p.text_content(): summary = " ".join(p.text_content().splitlines()) summary = re.sub("\[\d+\]", "", summary) summary = formatting.truncate_str(summary, 200) return "{} :: {}".format(summary, url) # this shouldn't happen return "Unknown Error."
def format_item(item, show_url=True): """ takes a newegg API item object and returns a description """ title = formatting.truncate_str(item["Title"], 50) # format the rating nicely if it exists if not item["ReviewSummary"]["TotalReviews"] == "[]": rating = "Rated {}/5 ({} ratings)".format(item["ReviewSummary"]["Rating"], item["ReviewSummary"]["TotalReviews"][1:-1]) else: rating = "No Ratings" if not item["FinalPrice"] == item["OriginalPrice"]: price = "{FinalPrice}, was {OriginalPrice}".format(**item) else: price = item["FinalPrice"] tags = [] if item["Instock"]: tags.append("\x02Stock Available\x02") else: tags.append("\x02Out Of Stock\x02") if item["FreeShippingFlag"]: tags.append("\x02Free Shipping\x02") if item["IsFeaturedItem"]: tags.append("\x02Featured\x02") if item["IsShellShockerItem"]: tags.append("\x02SHELL SHOCKER\u00AE\x02") # join all the tags together in a comma separated string ("tag1, tag2, tag3") tag_text = ", ".join(tags) if show_url: # create the item URL and shorten it url = web.try_shorten(ITEM_URL.format(item["NeweggItemNumber"])) return "\x02{}\x02 ({}) - {} - {} - {}".format(title, price, rating, tag_text, url) else: return "\x02{}\x02 ({}) - {} - {}".format(title, price, rating, tag_text)
def imdb_url(match): imdb_id = match.group(4).split('/')[-1] if imdb_id == "": imdb_id = match.group(4).split('/')[-2] content = http.get_json("http://www.omdbapi.com/", i=imdb_id) if content.get('Error', None) == 'Movie not found!': return 'Movie not found!' elif content['Response'] == 'True': content['URL'] = 'http://www.imdb.com/title/%(imdbID)s' % content content['Plot'] = formatting.truncate_str(content['Plot'], 50) out = '\x02%(Title)s\x02 (%(Year)s) (%(Genre)s): %(Plot)s' if content['Runtime'] != 'N/A': out += ' \x02%(Runtime)s\x02.' if content['imdbRating'] != 'N/A' and content['imdbVotes'] != 'N/A': out += ' \x02%(imdbRating)s/10\x02 with \x02%(imdbVotes)s\x02' \ ' votes.' return out % content else: return 'Unknown error.'
def suggest(text): """suggest <phrase> -- Gets suggested phrases for a google search""" page = http.get('http://google.com/complete/search', output='json', client='hp', q=text) page_json = page.split('(', 1)[1][:-1] suggestions = json.loads(page_json)[1] suggestions = [suggestion[0] for suggestion in suggestions] if not suggestions: return 'no suggestions found' out = ", ".join(suggestions) # defuckify text (might not be needed now, but I'll keep it) soup = BeautifulSoup(out) out = soup.get_text() return formatting.truncate_str(out, 200)
def mcwiki(text): """mcwiki <phrase> - gets the first paragraph of the Minecraft Wiki article on <phrase>""" try: j = http.get_json(api_url, search=text) except (http.HTTPError, http.URLError) as e: return "Error fetching search results: {}".format(e) except ValueError as e: return "Error reading search results: {}".format(e) if not j[1]: return "No results found." # we remove items with a '/' in the name, because # gamepedia uses sub-pages for different languages # for some stupid reason items = [item for item in j[1] if not "/" in item] if items: article_name = items[0].replace(' ', '_').encode('utf8') else: # there are no items without /, just return a / one article_name = j[1][0].replace(' ', '_').encode('utf8') url = mc_url + http.quote(article_name, '') try: page = http.get_html(url) except (http.HTTPError, http.URLError) as e: return "Error fetching wiki page: {}".format(e) for p in page.xpath('//div[@class="mw-content-ltr"]/p'): if p.text_content(): summary = " ".join(p.text_content().splitlines()) summary = re.sub("\[\d+\]", "", summary) summary = formatting.truncate_str(summary, 200) return "{} :: {}".format(summary, url) # this shouldn't happen return "Unknown Error."
def wiki(text): """wiki <phrase> -- Gets first sentence of Wikipedia article on <phrase>.""" try: request = requests.get(search_url, params={'search': text.strip()}) request.raise_for_status() except (requests.exceptions.HTTPError, requests.exceptions.ConnectionError) as e: return "Could not get Wikipedia page: {}".format(e) x = html.fromstring(request.text) ns = '{http://opensearch.org/searchsuggest2}' items = x.findall(ns + 'Section/' + ns + 'Item') if not items: if x.find('error') is not None: return 'Could not get Wikipedia page: %(code)s: %(info)s' % x.find('error').attrib else: return 'No results found.' def extract(item): return [item.find(ns + i).text for i in ('Text', 'Description', 'Url')] title, desc, url = extract(items[0]) if 'may refer to' in desc: title, desc, url = extract(items[1]) title = paren_re.sub('', title) if title.lower() not in desc.lower(): desc = title + desc desc = ' '.join(desc.split()) # remove excess spaces desc = formatting.truncate_str(desc, 200) return '{} :: {}'.format(desc, requests.utils.quote(url, ':/'))
def urban(text): """urban <phrase> [id] -- Looks up <phrase> on urbandictionary.com.""" headers = { "Referer": "http://m.urbandictionary.com" } if text: # clean and split the input text = text.lower().strip() parts = text.split() # if the last word is a number, set the ID to that number if parts[-1].isdigit(): id_num = int(parts[-1]) # remove the ID from the input string del parts[-1] text = " ".join(parts) else: id_num = 1 # fetch the definitions try: params = {"term": text} request = requests.get(define_url, params=params, headers=headers) request.raise_for_status() except (requests.exceptions.HTTPError, requests.exceptions.ConnectionError) as e: return "Could not get definition: {}".format(e) page = request.json() if page['result_type'] == 'no_results': return 'Not found.' else: # get a random definition! try: request = requests.get(random_url, headers=headers) request.raise_for_status() except (requests.exceptions.HTTPError, requests.exceptions.ConnectionError) as e: return "Could not get definition: {}".format(e) page = request.json() id_num = None definitions = page['list'] if id_num: # try getting the requested definition try: definition = definitions[id_num - 1] def_text = " ".join(definition['definition'].split()) # remove excess spaces def_text = formatting.truncate_str(def_text, 200) except IndexError: return 'Not found.' url = definition['permalink'] output = "[{}/{}] {} - {}".format(id_num, len(definitions), def_text, url) else: definition = random.choice(definitions) def_text = " ".join(definition['definition'].split()) # remove excess spaces def_text = formatting.truncate_str(def_text, 200) name = definition['word'] url = definition['permalink'] output = "\x02{}\x02: {} - {}".format(name, def_text, url) return output
def list_factoids(chan, message): """- lists all available factoids.""" message( formatting.truncate_str(", ".join(sorted(factoid_cache[chan].keys())), 400) or "None")