1 #!/usr/bin/env python2.5
3 Filename: google_correct.py
4 Purpose: correct a keyword using google search
5 Authors: (c) Michael Prokop <mika@grml.org>
6 Bug-Reports: see http://grml.org/bugs/
7 License: This file is licensed under the GPL v2 or any later version.
8 Latest change: Sun Mar 09 19:19:04 CET 2008 [mika]
12 * requires xsel binary
13 * requires python >= 2.4 (for urllib2), version 2.5 suggested :)
14 * if python-notify is installed it's used as notification system
18 * 2008-03-09: improve cmdline parsing logic [gregor herrmann]
19 include support for libnotify [mika]
20 usage information for -h/--help [mika]
21 provide output on stdout even when using xsel [mika]
22 * 2008-02-11: initial version [mika]
26 * support multiple keywords in one single invocation
27 * use python-xlib instead of xsel,
28 like in http://kalvdans.no-ip.org/svn/saturnapps/selection.py ?
29 * support something like a search gateway for anonymous search requests
30 * support different backends (like fuzzy search in local dictionaries)
31 * provide small selection menu for X, vim,...
41 _correction_re = re.compile(r'<font[^>]*>Did you mean: </font><a[^>]*>'
42 r'<b><i>(.*?)</i></b></a>(?i)')
46 google_correct.py: correct a keyword using google's 'Did you mean' feature
52 google_correct.py <keyword>
54 or select keyword in X and execute the script to set new X selection:
58 Send bug reports, feature requests and patches to Michael Prokop <mika@grml.org>
62 """Check whether a given program can be executed"""
63 for path in (os.environ.get('PATH') or os.defpath).split(os.pathsep):
64 myfile = os.path.join(path, filename)
65 if os.access(myfile, os.X_OK):
68 def correct_keyword(keyword):
69 """Correct spelling of a keyword using google's 'Did you mean' feature"""
70 req = urllib2.Request('http://www.google.com/search?%s' % urllib.urlencode({
71 'q': keyword.encode('utf-8'),
74 req.add_header('User-Agent', 'Mikas-Keyword-Corrector/1.0 :-)')
75 resp = urllib2.urlopen(req)
76 match = _correction_re.search(resp.read())
77 return match and match.group(1) or keyword
79 # would be nice to support multiple keywords at once,
80 # needs work in _correction_re though:
82 # for argument in sys.argv[1:]:
83 # return ' '.join(arg for arg in sys.argv[1:])
86 def get_x_selection():
88 proc = subprocess.Popen(['xsel', ], stdout=subprocess.PIPE)
89 x_selection = proc.stdout.read()
94 def set_x_selection(keyword):
95 """Set X selection to the given keyword"""
96 proc = subprocess.Popen(['xsel', '-i'], stdin=subprocess.PIPE)
97 proc.stdin.write(keyword)
101 def default_cb(n, action):
102 assert action == "default"
103 print "You clicked the default action"
107 def notify(new_keyword, old_keyword):
110 if pynotify.init("google_correct"):
111 if new_keyword is not old_keyword:
112 n = pynotify.Notification("New keyword for \"%s\":" % old_keyword, new_keyword)
114 n = pynotify.Notification("google_correct result:", "No new keyword for \"%s\" found" % old_keyword)
119 return 0 # don't print anything because someone might use the output :)
121 if __name__ == '__main__':
122 if '--help' in sys.argv or '-h' in sys.argv:
127 # print it to stdout:
128 old_keyword = sys.argv[1]
129 new_keyword = correct_keyword(old_keyword)
131 notify(new_keyword, old_keyword)
132 # or if you prefer to put it directly to X selection:
133 #set_x_selection(correct_keyword(sys.argv[1]))
136 old_keyword = get_x_selection()
137 new_keyword = correct_keyword(old_keyword)
139 set_x_selection(new_keyword)
140 notify(new_keyword, old_keyword)
142 sys.exit("Sorry, xsel not found. Exiting.")
144 ## END OF FILE #################################################################
145 # vim: ft=python tw=100 ai et