]>
Commit | Line | Data |
---|---|---|
685e346e A |
1 | import json |
2 | import re | |
3 | from urllib import urlencode | |
4 | from feed import HtmlFeed, XmlFeed, get_json | |
5 | from utils import unescape | |
6 | ||
7 | class Google(object): | |
8 | def __init__(self): | |
9 | pass | |
10 | ||
11 | # Google shutdown their iGoogle "API", | |
12 | #def calc(self, expr): | |
13 | # url = 'http://www.google.com/ig/calculator?' | |
14 | # url += urlencode({'q': expr}) | |
15 | # page = HtmlFeed(url) #, fake_ua=True) | |
16 | # text = page.html() | |
17 | # # Convert to valid JSON: {foo: "1"} -> {"foo" : "1"}, | |
18 | # # {"foo": "\x25"} -> {"foo": "\u0025"} | |
19 | # result = re.sub("([a-z]+):", '"\\1" :', text) | |
20 | # # XXX: HACK; using two substitutes instead of one, but I can't into regex | |
21 | # result = re.sub('\\\\x([0-9a-f]{2})', '\\u00\\1', result) | |
22 | # result = re.sub('\\\\x([0-9a-f]{1})', '\\u000\\1', result) | |
23 | # | |
24 | # result = unicode(result, 'unicode_escape') | |
25 | # result = unescape(result) | |
26 | # # Special case: fractions; those are <sup></sup> unicode-slash <sub></sub> | |
27 | # result = re.sub(u'<sup>([^<]*)</sup>\u2044<sub>([^<]*)</sub>', ' \\1/\\2', result) | |
28 | # # Also un-html-ify <sup>/</sup> because google doesn't send proper plaintext | |
29 | # result = re.sub('<sup>([^<]*)</sup>', '^\\1', result) | |
30 | # # Same with <sub>. | |
31 | # result = re.sub('<sub>([^<]*)</sub>', '_\\1', result) | |
32 | # result = json.loads(result.encode('utf-8')) | |
33 | # return result | |
34 | ||
35 | def search(self, query, userip=None): | |
36 | url = 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&' | |
37 | parameters = {'q': query} | |
38 | if userip: | |
39 | parameters['userip'] = userip | |
40 | url += urlencode(parameters) | |
41 | json = get_json(url) | |
42 | return json | |
43 | ||
cb6afe7c M |
44 | def image_search(self, query, userip=None): |
45 | url = 'http://ajax.googleapis.com/ajax/services/search/images?v=1.0&' | |
46 | parameters = {'q': query} | |
47 | if userip: | |
48 | parameters['userip'] = userip | |
49 | url += urlencode(parameters) | |
50 | json = get_json(url) | |
51 | return json | |
52 | ||
685e346e A |
53 | def yt_search(self, query, num=1): |
54 | url = 'https://gdata.youtube.com/feeds/api/videos?v=2&max-results=5&' | |
55 | url += urlencode({'q': query}) | |
56 | xml = XmlFeed(url) | |
57 | entry = xml.elements('/feed/entry[%d]' % num) | |
58 | if not entry: | |
59 | return None | |
60 | ||
61 | v = entry[0] | |
62 | return { | |
63 | 'title': v.text('title'), | |
64 | 'duration': v.int('media:group/yt:duration/@seconds'), | |
65 | 'uploaded': v.text('media:group/yt:uploaded'), | |
66 | 'id': v.text('media:group/yt:videoid'), | |
67 | 'rating': v.decimal('gd:rating/@average'), | |
68 | 'rate_count': v.int('gd:rating/@numRaters'), | |
69 | 'favorite_count': v.int('yt:statistics/@favoriteCount'), | |
70 | 'view_count': v.int('yt:statistics/@viewCount'), | |
71 | 'liked': v.int('yt:rating/@numLikes'), | |
72 | 'disliked': v.int('yt:rating/@numDislikes') | |
73 | } |