summaryrefslogtreecommitdiffstats
path: root/modules/oblique.py
blob: d93446e324396fc60d38b3ffee7245761d046b27 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/bin/env python
"""
oblique.py - Web Services Interface
Copyright 2008-9, Sean B. Palmer, inamidst.com
Licensed under the Eiffel Forum License 2.

http://inamidst.com/phenny/
"""

import re, urllib
import web

definitions = 'https://github.com/nslater/oblique/wiki'

r_item = re.compile(r'(?i)<li>(.*?)</li>')
r_tag = re.compile(r'<[^>]+>')

def mappings(uri): 
   result = {}
   bytes = web.get(uri)
   for item in r_item.findall(bytes): 
      item = r_tag.sub('', item).strip(' \t\r\n')
      if not ' ' in item: continue

      command, template = item.split(' ', 1)
      if not command.isalnum(): continue
      if not template.startswith('http://'): continue
      result[command] = template.replace('&amp;', '&')
   return result

def service(phenny, input, command, args): 
   t = o.services[command]
   template = t.replace('${args}', urllib.quote(args.encode('utf-8'), ''))
   template = template.replace('${nick}', urllib.quote(input.nick, ''))
   uri = template.replace('${sender}', urllib.quote(input.sender, ''))

   info = web.head(uri)
   if isinstance(info, list): 
      info = info[0]
   if not 'text/plain' in info.get('content-type', '').lower(): 
      return phenny.reply("Sorry, the service didn't respond in plain text.")
   bytes = web.get(uri)
   lines = bytes.splitlines()
   if not lines: 
      return phenny.reply("Sorry, the service didn't respond any output.")
   try: line = lines[0].encode('utf-8')[:350]
   except: line = lines[0][:250]
   phenny.say(line)

def refresh(phenny): 
   if hasattr(phenny.config, 'services'): 
      services = phenny.config.services
   else: services = definitions

   old = o.services
   o.serviceURI = services
   o.services = mappings(o.serviceURI)
   return len(o.services), set(o.services) - set(old)

def o(phenny, input): 
   """Call a webservice."""
   text = input.group(2)

   if (not o.services) or (text == 'refresh'): 
      length, added = refresh(phenny)
      if text == 'refresh': 
         msg = 'Okay, found %s services.' % length
         if added: 
            msg += ' Added: ' + ', '.join(sorted(added)[:5])
            if len(added) > 5: msg += ', &c.'
         return phenny.reply(msg)

   if not text: 
      return phenny.reply('Try %s for details.' % o.serviceURI)

   if ' ' in text: 
      command, args = text.split(' ', 1)
   else: command, args = text, ''
   command = command.lower()

   if command == 'service': 
      msg = o.services.get(args, 'No such service!')
      return phenny.reply(msg)

   if not o.services.has_key(command): 
      return phenny.reply('Service not found in %s' % o.serviceURI)

   if hasattr(phenny.config, 'external'): 
      default = phenny.config.external.get('*')
      manifest = phenny.config.external.get(input.sender, default)
      if manifest: 
         commands = set(manifest)
         if (command not in commands) and (manifest[0] != '!'): 
            return phenny.reply('Sorry, %s is not whitelisted' % command)
         elif (command in commands) and (manifest[0] == '!'): 
            return phenny.reply('Sorry, %s is blacklisted' % command)
   service(phenny, input, command, args)
o.commands = ['o']
o.example = '.o servicename arg1 arg2 arg3'
o.services = {}
o.serviceURI = None

def snippet(phenny, input): 
   if not o.services: 
      refresh(phenny)

   search = urllib.quote(input.group(2).encode('utf-8'))
   py = "BeautifulSoup.BeautifulSoup(re.sub('<.*?>|(?<= ) +', '', " + \
        "''.join(chr(ord(c)) for c in " + \
        "eval(urllib.urlopen('http://ajax.googleapis.com/ajax/serv" + \
        "ices/search/web?v=1.0&q=" + search + "').read()" + \
        ".replace('null', 'None'))['responseData']['resul" + \
        "ts'][0]['content'].decode('unicode-escape')).replace(" + \
        "'&quot;', '\x22')), convertEntities=True)"
   service(phenny, input, 'py', py)
snippet.commands = ['snippet']

if __name__ == '__main__': 
   print __doc__.strip()