Earlier, I used Zenity in a shell script to create a simple application to search in firefox ( Convenient regular shell script --web search dialog firefox-search.sh ), but this time it is converted to Python I will introduce the ported one. I made it for studying Gtk.
The overall concept is the same as when it was created with a shell script, but this time we have improved it so that it automatically completes the characters typed by utilizing the history.
Gtk.EntryCompletion
It can be easily implemented by using Gtk.EntryCompletion of gi.repository.
gtk.EntryCompletion: 16.4. EntryCompletion Objects:
However, I found it on Github because it can't translate for each space-separated word.
https://gist.github.com/evoL/1650115
Based on, I changed the rule so that the conversion is performed for each word separated by a space. Thank you evoL. By the way, the 50th line of the above site
# add the matching word current_text = "%s %s" % (current_text, model[iter][0])
Needs to be deleted. If there is this, the keyword that is completed by hitting halfway will be input twice.
(If you type "ubu" and select "ubuntu", "ubuntu ubuntu" will be entered.)
Also, this time, in order to make it more like an application, I tried to divide the files and manage the settings in separate files. As the whole composition
It can be used in various browsers by rewriting config.py here, and you can easily change or add the site specified as an option. \ _ \ _ Init \ _ \ _. Py is just a file needed to handle it as a module, and this time it is empty. It seems better to process the version check here.
Also, I recently learned how to use Git easily, so I gave the code to GitHub.
http://github.com/ssh0/web_search It is OK to clone and fork.
When you run websearch.py,
A simple entry box like this appears, and when you enter characters, it behaves like the beginning of an article. If you press the Enter key when the input is completed, the search results will be displayed in a new tab in the browser specified in config.py.
In the future, I would like to add a function that predicts and displays related words from the degree of relevance of words, like a general web search bar. Also, since typos are severe (one of the reasons I made this one), I would like to have a function such as deleting the mistakes. There is also a way to borrow the search engine of Google teacher as it is. Also, it seems that shell functions can be easily implemented. Is it a file search as a usage? You can do the same with the Unity lens, which is the desktop environment of Ubuntu, but it becomes heavy, so it is currently turned off. If it's as simple as running locate, it may be lighter and more comfortable to incorporate it here.
Anyway, the day has come when my search history, which was not useful until now, is useful.
Also, I got the feeling that Gtk could make something. I want to touch various things in the future.
Finally, expose the code. As for the explanation, you can understand what you are doing by looking at the comments. Then refer to the official references listed above. I would appreciate any advice or tsukkomi.
websearch.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
# written by ssh0, September 2014
#
# NOTE: bug: This code doesn't run correctly when the browser hasn't run.
from gi.repository import Gtk
import os
import commands
import sys
import websearch.config as config
import websearch.prediction as prediction
logfile = config.logfile
class Window(Gtk.Window):
def __init__(self):
self.window = Gtk.Window.__init__(self, title="search")
# list data for completion from logfile
lists = []
with open(logfile) as f:
for s in f.readlines():
lists += unicode(s, 'utf-8').split()[1:]
lists = set(lists)
liststore = Gtk.ListStore(str)
for match in lists:
liststore.append([match])
self.entry = prediction.EntryMultiCompletion()
self.entry.completion.set_model(liststore)
self.entry.completion.set_text_column(0)
self.entry.completion.set_popup_completion(popup_completion=True)
self.entry.connect("activate", self.enter_callback)
self.add(self.entry)
def enter_callback(self, event):
# get text from entry widget
search_term = self.entry.get_text().split()
# if text is None, do nothing
if len(search_term) == 0:
return 0
# in config.py, site must be dictionary that
# key is option argument and value is website's address
site = config.site
# find option
option= search_term[0]
if option in site:
goto = site[option]
del search_term[0]
if len(search_term) == 0:
return 0
# if there is no option, go to default site
else:
goto = site['default-search']
# search term are joined mostly with '+'
if len(search_term) > 1:
t = ' '.join(search_term)
else:
t = search_term[0]
# save the log to logfile
date = commands.getoutput('date +%F_%T')
log = date + ' ' + t + '\n'
with open(logfile, 'a') as l:
l.writelines(log)
# go to website
base = config.browser['default']
goto = goto % t
os.system(base + '"' + goto + '"')
sys.exit()
def main():
win = Window()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
if __name__ == '__main__':
main()
config.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
# written by ssh0, September 2014
logfile = "/home/ssh0/Dropbox/log.txt"
# choose the default browser by comment out
# or you can edit to any browser
browser = {"default":
"firefox -new-tab "
# "chromium-browser -new-tab "
# "google-chrome -new-tab "
# "opera -newtab "
,
}
site = {
# default:Google search
"default-search": r"https://www.google.co.jp/#q=%s",
# "w": Wikipedia
"-w": r"https:ja.wikipedia.org/wiki/%s",
# "n":niconico video
"-n": r"http://www.nicovideo.jp/search/%s",
# "p":Google image search
#"-p": r"https://www.google.com/search?q=%s&um=1&ie=UTF-8&hl=ja&tbm=isch&source=og&sa=N&tab=wi",
# "y":Search on Youtube
"-y": r"http://www.youtube.com/results?search_query=%s&sm=3",
# "rt"Yahoo real-time search
"-rt": r"http://realtime.search.yahoo.co.jp/search?p=%s&ei=UTF-8",
# "sc"Google Scholar Search
"-sc": r"http://scholar.google.co.jp/scholar?q=%s&hl=ja&as_sdt=0,5",
# "-t":translation
"-t": r"http://ejje.weblio.jp/content/%s"
}
prediction.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
# written by ssh0, September 2014
#reference: https://gist.github.com/evoL/1650115
from gi.repository import Gtk
import config
logfile = config.logfile
class EntryMultiCompletion(Gtk.Entry):
def __init__(self):
Gtk.Entry.__init__(self)
self.completion = Gtk.EntryCompletion()
# customize the matching function to match multiple space
# separated words
self.completion.set_match_func(self.match_func, None)
# handle the match-selected signal, raised when a completion
# is selected from popup
self.completion.connect('match-selected', self.on_completion_match)
self.set_completion(self.completion)
def match_func(self, completion, key_string, iter, data):
model = self.completion.get_model()
modelstr = model[iter][0]
# check if the user has typed in a space char,
# get the last word and check if it matches something
if ' ' in key_string:
last_word = key_string.split()[-1]
return modelstr.startswith(last_word)
# we have only one word typed
return modelstr.startswith(key_string)
def on_completion_match(self, completion, model, iter):
current_text = self.get_text()
# if more than a word has been typed, we throw away the
# last one because we want to replace it with the matching word
# note: the user may have typed only a part of the entire word
# and so this step is necessary
if ' ' in current_text:
current_text = ' '.join(current_text.split()[:-1])
print current_text
current_text = '%s %s' % (current_text, model[iter][0])
print current_text
else:
current_text = model[iter][0]
print current_text
# set back the whole text
self.set_text(current_text)
# move the cursor at the end
self.set_position(-1)
# stop the event propagation
return True
2014/09/24: In websearch.py, if "," etc. are included, it will not work properly, so I added double quotation marks to both ends of the address. With this, the necessary character conversion is performed on the browser side.
Recommended Posts