108 lines
2.8 KiB
Python
108 lines
2.8 KiB
Python
"""
|
|
QDB module
|
|
Grabs quotes from an online QDB database
|
|
"""
|
|
|
|
import random
|
|
import requests
|
|
import bs4
|
|
|
|
from bot import command
|
|
|
|
# map of supported databases
|
|
QDB_URLS = {
|
|
'xkcd':'http://www.xkcdb.com/random',
|
|
'bash':'http://www.bash.org/?random',
|
|
'qdb': 'http://www.qdb.us/random',
|
|
'wg':'https://qdb.worldgenesis.net/?random',
|
|
'tilde': 'https://quotes.tilde.chat/random'
|
|
}
|
|
|
|
@command( 'qdb' )
|
|
async def get_quote( bot, parms, ctx ):
|
|
"""
|
|
Grabs a random quote from specified quote database,
|
|
default random or database with same name as current network.
|
|
Supported databases: xkcd, bash, qdb, tilde, wg.
|
|
Does not output quotes with more than 5 lines by default unless 'spam' is first param.
|
|
"""
|
|
|
|
con = ctx['con']
|
|
dst = ctx['dst']
|
|
|
|
spam = False
|
|
db_name = ''
|
|
sv_name = con.cfg['sv']['name'].lower()
|
|
if sv_name in QDB_URLS.keys(): db_name = sv_name
|
|
|
|
if parms:
|
|
if parms[0] == 'spam':
|
|
spam = True
|
|
if len( parms ) > 1:
|
|
db_name = parms[1].lower()
|
|
else: db_name = parms[0].lower()
|
|
|
|
if not db_name: db_name = random.choice( list( QDB_URLS.keys() ) )
|
|
|
|
if db_name not in QDB_URLS.keys():
|
|
con.say_to( dst, 'No QDB known by name \'{}\'!'.format( db_name ) )
|
|
return
|
|
|
|
con.say_to( dst, 'Grabbing a quote from QDB \'{}\'...'.format( db_name ) )
|
|
|
|
req = requests.get( QDB_URLS[db_name] )
|
|
|
|
soup = bs4.BeautifulSoup( req.text, 'html.parser' )
|
|
|
|
qts = []
|
|
|
|
# element filter for soup depending on database
|
|
# do you even switch bro
|
|
if db_name == 'wg':
|
|
qts = soup.findAll( 'div', {'class':'quote_quote'} )
|
|
elif db_name == 'xkcd':
|
|
qts = soup.findAll( 'span', {'class':'quote'} )
|
|
elif db_name == 'qdb':
|
|
qts = soup.findAll( 'span', {'class':'qt'} )
|
|
elif db_name == 'bash':
|
|
qts = soup.findAll( 'p', {'class': 'qt'} )
|
|
elif db_name == 'tilde':
|
|
qts = soup.findAll( 'pre' )
|
|
|
|
# quote number notes.
|
|
# wg: <a class="quote_number">
|
|
# bash: first <b> child of <p> quote
|
|
# xkcd: first <a> child of <span class="quotehead">
|
|
# qdb: <a class="ql">
|
|
# tilde: ???
|
|
|
|
if qts:
|
|
# number of quotes per page
|
|
#print( len( qts ) )
|
|
# one random quote from page
|
|
rqt = random.choice( qts )
|
|
# grab raw quote text and split to lines
|
|
qt_lines = rqt.text.strip().split('\n')
|
|
# if too many lines for spam filter, try to find a shorter one
|
|
while not spam and len( qt_lines ) > 5:
|
|
#for q in qts:
|
|
if not qts:
|
|
qt_lines = None; break
|
|
qt_lines = qts.pop().text.strip().split('\n')
|
|
|
|
if not qt_lines:
|
|
con.say_to( dst, 'Quote had too many lines!' ); return
|
|
for l in qt_lines:
|
|
# find some kind of resemblence of a nick. doesnt account for timestamps
|
|
nsep = l.find( '>' )+1
|
|
if nsep <= 0: nsep = l.find( ':' )+1
|
|
if nsep <= 0: nsep = l.find( ' ' )
|
|
nn = l[: nsep]
|
|
nnc = 0
|
|
for c in nn: nnc += ord( c )
|
|
nnc %= 16
|
|
con.say_to( dst, '> \002\003{}{}\003\002{}'.format( nnc, nn, l[nsep:] ) )
|
|
else:
|
|
con.say_to( dst, 'No quotes found! :(' )
|
|
|