125 lines
3.9 KiB
Python
Executable File
125 lines
3.9 KiB
Python
Executable File
# coding=utf-8
|
|
# Copyright 2010, Michael Yanovich (yanovich.net), and Morgan Goose
|
|
# Copyright 2012, Lior Ramati
|
|
# Copyright 2013, Elsie Powell (embolalia.com)
|
|
# Licensed under the Eiffel Forum License 2.
|
|
from __future__ import unicode_literals, absolute_import, print_function, division
|
|
|
|
import random
|
|
import re
|
|
import requests
|
|
from modules.search import google_search
|
|
from module import commands, url
|
|
|
|
ignored_sites = [
|
|
# For google searching
|
|
'almamater.xkcd.com',
|
|
'blog.xkcd.com',
|
|
'blag.xkcd.com',
|
|
'forums.xkcd.com',
|
|
'fora.xkcd.com',
|
|
'forums3.xkcd.com',
|
|
'store.xkcd.com',
|
|
'wiki.xkcd.com',
|
|
'what-if.xkcd.com',
|
|
]
|
|
sites_query = ' site:xkcd.com -site:' + ' -site:'.join(ignored_sites)
|
|
|
|
|
|
def get_info(number=None, verify_ssl=True):
|
|
if number:
|
|
url = 'https://xkcd.com/{}/info.0.json'.format(number)
|
|
else:
|
|
url = 'https://xkcd.com/info.0.json'
|
|
data = requests.get(url, verify=verify_ssl).json()
|
|
data['url'] = 'https://xkcd.com/' + str(data['num'])
|
|
return data
|
|
|
|
|
|
def google(query):
|
|
url = google_search(query + sites_query)
|
|
if not url:
|
|
return None
|
|
match = re.match('(?:https?://)?xkcd.com/(\d+)/?', url)
|
|
if match:
|
|
return match.group(1)
|
|
|
|
|
|
@commands('xkcd')
|
|
def xkcd(bot, trigger):
|
|
"""
|
|
.xkcd - Finds an xkcd comic strip. Takes one of 3 inputs:
|
|
If no input is provided it will return a random comic
|
|
If numeric input is provided it will return that comic, or the nth-latest
|
|
comic if the number is non-positive
|
|
If non-numeric input is provided it will return the first google result for those keywords on the xkcd.com site
|
|
"""
|
|
verify_ssl = bot.config.core.verify_ssl
|
|
# get latest comic for rand function and numeric input
|
|
latest = get_info(verify_ssl=verify_ssl)
|
|
max_int = latest['num']
|
|
|
|
# if no input is given (pre - lior's edits code)
|
|
if not trigger.group(2): # get rand comic
|
|
random.seed()
|
|
requested = get_info(random.randint(1, max_int + 1),
|
|
verify_ssl=verify_ssl)
|
|
else:
|
|
query = trigger.group(2).strip()
|
|
|
|
numbered = re.match(r"^(#|\+|-)?(\d+)$", query)
|
|
if numbered:
|
|
query = int(numbered.group(2))
|
|
if numbered.group(1) == "-":
|
|
query = -query
|
|
return numbered_result(bot, query, latest)
|
|
else:
|
|
# Non-number: google.
|
|
if (query.lower() == "latest" or query.lower() == "newest"):
|
|
requested = latest
|
|
else:
|
|
number = google(query)
|
|
if not number:
|
|
bot.say('Could not find any comics for that query.')
|
|
return
|
|
requested = get_info(number, verify_ssl=verify_ssl)
|
|
|
|
say_result(bot, requested)
|
|
|
|
|
|
def numbered_result(bot, query, latest, verify_ssl=True):
|
|
max_int = latest['num']
|
|
if query > max_int:
|
|
bot.say(("Sorry, comic #{} hasn't been posted yet. "
|
|
"The last comic was #{}").format(query, max_int))
|
|
return
|
|
elif query <= -max_int:
|
|
bot.say(("Sorry, but there were only {} comics "
|
|
"released yet so far").format(max_int))
|
|
return
|
|
elif abs(query) == 0:
|
|
requested = latest
|
|
elif query == 404 or max_int + query == 404:
|
|
bot.say("404 - Not Found") # don't error on that one
|
|
return
|
|
elif query > 0:
|
|
requested = get_info(query, verify_ssl=verify_ssl)
|
|
else:
|
|
# Negative: go back that many from current
|
|
requested = get_info(max_int + query, verify_ssl=verify_ssl)
|
|
|
|
say_result(bot, requested)
|
|
|
|
|
|
def say_result(bot, result):
|
|
message = '{} | {} | Alt-text: {}'.format(result['url'], result['title'],
|
|
result['alt'])
|
|
bot.say(message)
|
|
|
|
|
|
@url('xkcd.com/(\d+)')
|
|
def get_url(bot, trigger, match):
|
|
verify_ssl = bot.config.core.verify_ssl
|
|
latest = get_info(verify_ssl=verify_ssl)
|
|
numbered_result(bot, int(match.group(1)), latest)
|