linx is now optional because of spongebob

master
Andrei M 2012-11-26 22:04:36 -05:00
parent 900ac0c5c9
commit 1002bf04c6
3 changed files with 132 additions and 30 deletions

View File

@ -14,6 +14,7 @@ import urllib.error
import http.client import http.client
import http.cookiejar import http.cookiejar
import time import time
from html.entities import name2codepoint
import web import web
from tools import deprecated from tools import deprecated
from modules.linx import get_title from modules.linx import get_title
@ -23,22 +24,24 @@ opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
urllib.request.install_opener(opener) urllib.request.install_opener(opener)
def head(phenny, input): def head(phenny, input):
"""Provide HTTP HEAD information.""" """Provide HTTP HEAD information."""
uri = input.group(2) uri = input.group(2)
uri = (uri or '') uri = (uri or '')
if ' ' in uri: if ' ' in uri:
uri, header = uri.rsplit(' ', 1) uri, header = uri.rsplit(' ', 1)
else: uri, header = uri, None else:
uri, header = uri, None
if not uri and hasattr(phenny, 'last_seen_uri'): if not uri and hasattr(phenny, 'last_seen_uri'):
try: uri = phenny.last_seen_uri[input.sender] try:
except KeyError: return phenny.say('?') uri = phenny.last_seen_uri[input.sender]
except KeyError:
return phenny.say('?')
if not uri.startswith('htt'): if not uri.startswith('htt'):
uri = 'http://' + uri uri = 'http://' + uri
# uri = uri.replace('#!', '?_escaped_fragment_=') # uri = uri.replace('#!', '?_escaped_fragment_=')
start = time.time() start = time.time()
try: try:
@ -53,63 +56,73 @@ def head(phenny, input):
resptime = time.time() - start resptime = time.time() - start
if header is None: if header is None:
data = [] data = []
if 'Status' in info: if 'Status' in info:
data.append(info['Status']) data.append(info['Status'])
if 'content-type' in info: if 'content-type' in info:
data.append(info['content-type'].replace('; charset=', ', ')) data.append(info['content-type'].replace('; charset=', ', '))
if 'last-modified' in info: if 'last-modified' in info:
modified = info['last-modified'] modified = info['last-modified']
modified = time.strptime(modified, '%a, %d %b %Y %H:%M:%S %Z') modified = time.strptime(modified, '%a, %d %b %Y %H:%M:%S %Z')
data.append(time.strftime('%Y-%m-%d %H:%M:%S UTC', modified)) data.append(time.strftime('%Y-%m-%d %H:%M:%S UTC', modified))
if 'content-length' in info: if 'content-length' in info:
data.append(info['content-length'] + ' bytes') data.append(info['content-length'] + ' bytes')
data.append('{0:1.2f} s'.format(resptime)) data.append('{0:1.2f} s'.format(resptime))
phenny.reply(', '.join(data)) phenny.reply(', '.join(data))
else: else:
headerlower = header.lower() headerlower = header.lower()
if headerlower in info: if headerlower in info:
phenny.say(header + ': ' + info.get(headerlower)) phenny.say(header + ': ' + info.get(headerlower))
else: else:
msg = 'There was no %s header in the response.' % header msg = 'There was no %s header in the response.' % header
phenny.say(msg) phenny.say(msg)
head.commands = ['head'] head.commands = ['head']
head.example = '.head http://www.w3.org/' head.example = '.head http://www.w3.org/'
@deprecated @deprecated
def f_title(self, origin, match, args): def f_title(self, origin, match, args):
""".title <URI> - Return the title of URI.""" """.title <URI> - Return the title of URI."""
uri = match.group(2) uri = match.group(2)
uri = (uri or '') uri = (uri or '')
if not uri and hasattr(self, 'last_seen_uri'): if not uri and hasattr(self, 'last_seen_uri'):
uri = self.last_seen_uri.get(origin.sender) uri = self.last_seen_uri.get(origin.sender)
if not uri: if not uri:
return self.msg(origin.sender, 'I need a URI to give the title of...') return self.msg(origin.sender, 'I need a URI to give the title of...')
title = get_title(uri) title = gettitle(uri)
if title: if title:
self.msg(origin.sender, origin.nick + ': ' + title) self.msg(origin.sender, origin.nick + ': ' + title)
else: self.msg(origin.sender, origin.nick + ': No title found') else:
self.msg(origin.sender, origin.nick + ': No title found')
f_title.commands = ['title'] f_title.commands = ['title']
r_title = re.compile(r'(?ims)<title[^>]*>(.*?)</title\s*>') r_title = re.compile(r'(?ims)<title[^>]*>(.*?)</title\s*>')
r_entity = re.compile(r'&[A-Za-z0-9#]+;') r_entity = re.compile(r'&[A-Za-z0-9#]+;')
def noteuri(phenny, input):
def noteuri(phenny, input):
uri = input.group(1) uri = input.group(1)
if not hasattr(phenny.bot, 'last_seen_uri'): if not hasattr(phenny.bot, 'last_seen_uri'):
phenny.bot.last_seen_uri = {} phenny.bot.last_seen_uri = {}
phenny.bot.last_seen_uri[input.sender] = uri phenny.bot.last_seen_uri[input.sender] = uri
noteuri.rule = r'.*(http[s]?://[^<> "\x01]+)[,.]?' noteuri.rule = r'.*(http[s]?://[^<> "\x01]+)[,.]?'
noteuri.priority = 'low' noteuri.priority = 'low'
titlecommands = r'(?:' + r'|'.join(f_title.commands) + r')' titlecommands = r'(?:' + r'|'.join(f_title.commands) + r')'
def snarfuri(phenny, input): def snarfuri(phenny, input):
if re.match(r'(?i)' + phenny.config.prefix + titlecommands, input.group()): if re.match(r'(?i)' + phenny.config.prefix + titlecommands, input.group()):
return return
uri = input.group(1) uri = input.group(1)
title = get_title(uri, input.sender)
if phenny.config.linx_api_key != "":
title = get_title(phenny, uri, input.sender)
else:
title = gettitle(uri)
if title: if title:
phenny.msg(input.sender, title) phenny.msg(input.sender, title)
snarfuri.rule = r'.*(http[s]?://[^<> "\x01]+)[,.]?' snarfuri.rule = r'.*(http[s]?://[^<> "\x01]+)[,.]?'
@ -117,5 +130,90 @@ snarfuri.priority = 'low'
snarfuri.thread = True snarfuri.thread = True
if __name__ == '__main__': def gettitle(uri):
if not ':' in uri:
uri = 'http://' + uri
uri = uri.replace('#!', '?_escaped_fragment_=')
title = None
localhost = [
'http://localhost/', 'http://localhost:80/',
'http://localhost:8080/', 'http://127.0.0.1/',
'http://127.0.0.1:80/', 'http://127.0.0.1:8080/',
'https://localhost/', 'https://localhost:80/',
'https://localhost:8080/', 'https://127.0.0.1/',
'https://127.0.0.1:80/', 'https://127.0.0.1:8080/',
]
for s in localhost:
if uri.startswith(s):
return phenny.reply('Sorry, access forbidden.')
try:
redirects = 0
while True:
info = web.head(uri)
if not isinstance(info, list):
status = '200'
else:
status = str(info[1])
info = info[0]
if status.startswith('3'):
uri = urllib.parse.urljoin(uri, info['Location'])
else:
break
redirects += 1
if redirects >= 25:
return None
try:
mtype = info['content-type']
except:
return None
if not (('/html' in mtype) or ('/xhtml' in mtype)):
return None
bytes = web.get(uri)
#bytes = u.read(262144)
#u.close()
except IOError:
return
m = r_title.search(bytes)
if m:
title = m.group(1)
title = title.strip()
title = title.replace('\t', ' ')
title = title.replace('\r', ' ')
title = title.replace('\n', ' ')
while ' ' in title:
title = title.replace(' ', ' ')
if len(title) > 200:
title = title[:200] + '[...]'
def e(m):
entity = m.group(0)
if entity.startswith('&#x'):
cp = int(entity[3:-1], 16)
return chr(cp)
elif entity.startswith('&#'):
cp = int(entity[2:-1])
return chr(cp)
else:
char = name2codepoint[entity[1:-1]]
return chr(char)
title = r_entity.sub(e, title)
if title:
title = title.replace('\n', '')
title = title.replace('\r', '')
else:
title = None
return title
if __name__ == '__main__':
print(__doc__.strip()) print(__doc__.strip())

View File

@ -11,10 +11,10 @@ import web
import json import json
def get_title(url, channel): def get_title(phenny, url, channel):
""" Have linx retrieve the (augmented) title """ """ Have linx retrieve the (augmented) title """
try: try:
return web.post("http://linx.li/vtluuggettitle", {'url': url, 'channel': channel}) return web.post("http://linx.li/vtluuggettitle", {'url': url, 'channel': channel, 'api_key': phenny.config.linx_api_key})
except: except:
return return
@ -28,7 +28,7 @@ def linx(phenny, input, short=False):
return return
try: try:
req = web.post("http://linx.li/vtluug", {'url': url, 'short': short}) req = web.post("http://linx.li/vtluug", {'url': url, 'short': short, 'api_key': phenny.config.linx_api_key})
except (HTTPError, IOError): except (HTTPError, IOError):
raise GrumbleError("THE INTERNET IS FUCKING BROKEN. Please try again later.") raise GrumbleError("THE INTERNET IS FUCKING BROKEN. Please try again later.")
@ -70,7 +70,7 @@ def lines(phenny, input):
date = "today" date = "today"
try: try:
req = web.post("http://linx.li/vtluuglines", {'nickname': nickname, 'date': date, 'sender': input.nick, 'channel': input.sender}) req = web.post("http://linx.li/vtluuglines", {'nickname': nickname, 'date': date, 'sender': input.nick, 'channel': input.sender, 'api_key': phenny.config.linx_api_key})
except (HTTPError, IOError): except (HTTPError, IOError):
raise GrumbleError("THE INTERNET IS FUCKING BROKEN. Please try again later.") raise GrumbleError("THE INTERNET IS FUCKING BROKEN. Please try again later.")
@ -88,7 +88,7 @@ def posted(phenny, input):
return return
try: try:
req = web.post("http://linx.li/vtluugposted", {'message': message, 'sender': input.nick, 'channel': input.sender}) req = web.post("http://linx.li/vtluugposted", {'message': message, 'sender': input.nick, 'channel': input.sender, 'api_key': phenny.config.linx_api_key})
except (HTTPError, IOError): except (HTTPError, IOError):
raise GrumbleError("THE INTERNET IS FUCKING BROKEN. Please try again later.") raise GrumbleError("THE INTERNET IS FUCKING BROKEN. Please try again later.")

4
phenny
View File

@ -38,6 +38,10 @@ def create_default_config(fn):
# password = 'example' # password = 'example'
# serverpass = 'serverpass' # serverpass = 'serverpass'
# linx-enabled features (.linx, .posted, .lines, snarfuri with special capabilities)
# leave the api key blank to not use them and be sure to add the 'linx' module to the ignore list.
linx_api_key = ""
# These are people who will be able to use admin.py's functions... # These are people who will be able to use admin.py's functions...
admins = [owner, 'someoneyoutrust'] admins = [owner, 'someoneyoutrust']
# But admin.py is disabled by default, as follows: # But admin.py is disabled by default, as follows: