~evfool/software-center/lp927426

« back to all changes in this revision

Viewing changes to view/appview.py

  • Committer: Michael Vogt
  • Date: 2009-07-27 14:49:44 UTC
  • Revision ID: michael.vogt@ubuntu.com-20090727144944-178z479wps3m907e
initial version of update-app-install based on xapian

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
 
 
3
import logging
 
4
import gtk
 
5
import gobject
 
6
import apt
 
7
import os
 
8
import xapian
 
9
import time
 
10
 
 
11
XAPIAN_DATA_ICON = 0
 
12
 
 
13
class ExecutionTime(object):
 
14
    """
 
15
    Helper that can be used in with statements to have a simple
 
16
    measure of the timming of a particular block of code, e.g.
 
17
    with ExecutinTime("db flush"):
 
18
        db.flush()
 
19
    """
 
20
    def __init__(self, info=""):
 
21
        self.info = info
 
22
    def __enter__(self):
 
23
        self.now = time.time()
 
24
    def __exit__(self, type, value, stack):
 
25
        print "%s: %s" % (self.info, time.time() - self.now)
 
26
 
 
27
class AppStore(gtk.GenericTreeModel):
 
28
 
 
29
    (COL_NAME, 
 
30
     COL_ICON,
 
31
     ) = range(2)
 
32
    column_type = (str, 
 
33
                   gtk.gdk.Pixbuf)
 
34
 
 
35
    def __init__(self, db, icons, search_term=""):
 
36
        gtk.GenericTreeModel.__init__(self)
 
37
        self.xapiandb = db
 
38
        self.icons = icons
 
39
        self.appnames = []
 
40
        if not search_term:
 
41
            for m in db.postlist(""):
 
42
                doc = db.get_document(m.docid)
 
43
                self.appnames.append(doc.get_data())
 
44
            self.appnames.sort()
 
45
        else:
 
46
            parser = xapian.QueryParser()
 
47
            user_query = parser.parse_query(search_term)
 
48
            #cat_query = xapian.Query("XCgame")
 
49
            #query = xapian.Query(xapian.Query.OP_AND, cat_query, user_query)
 
50
            enquire = xapian.Enquire(db)
 
51
            enquire.set_weighting_scheme(xapian.BoolWeight())
 
52
            enquire.set_query(user_query)
 
53
            matches = enquire.get_mset(0, 400)
 
54
            logging.debug("found ~%i matches" % matches.get_matches_estimated())
 
55
            for m in matches:
 
56
                doc = m[xapian.MSET_DOCUMENT]
 
57
                name = doc.get_data()
 
58
                self.appnames.append(name)
 
59
    def on_get_flags(self):
 
60
        return (gtk.TREE_MODEL_LIST_ONLY|
 
61
                gtk.TREE_MODEL_ITERS_PERSIST)
 
62
    def on_get_n_columns(self):
 
63
        return len(self.column_type)
 
64
    def on_get_column_type(self, index):
 
65
        return self.column_type[index]
 
66
    def on_get_iter(self, path):
 
67
        logging.debug("on_get_iter: %s" % path)
 
68
        index = path[0]
 
69
        return index
 
70
    def on_get_path(self, rowref):
 
71
        logging.debug("on_get_path: %s" % rowref)
 
72
        return rowref
 
73
    def on_get_value(self, rowref, column):
 
74
        #logging.debug("on_get_value: %s %s" % (rowref, column))
 
75
        if (not self.appnames or rowref > len(self.appnames)):
 
76
            return None
 
77
        appname = self.appnames[rowref]
 
78
        if column == self.COL_NAME:
 
79
            return appname
 
80
        elif column == self.COL_ICON:
 
81
            try:
 
82
                icon_name = ""
 
83
                for post in self.xapiandb.postlist("XA"+appname):
 
84
                    doc = db.get_document(post.docid)
 
85
                    icon_name = doc.get_value(XAPIAN_DATA_ICON)
 
86
                    icon_name = os.path.splitext(icon_name)[0]
 
87
                    break
 
88
                if icon_name:
 
89
                    icon = self.icons.load_icon(icon_name, 24,0)
 
90
                    return icon
 
91
            except Exception, e:
 
92
                if not str(e).endswith("not present in theme"):
 
93
                    logging.exception("get_icon")
 
94
        return None
 
95
    def on_iter_next(self, rowref):
 
96
        #logging.debug("on_iter_next: %s" % rowref)
 
97
        new_rowref = rowref + 1
 
98
        if new_rowref >= len(self.appnames):
 
99
            return None
 
100
        return new_rowref
 
101
    def on_iter_children(self, parent):
 
102
        if parent:
 
103
            return None
 
104
        return self.appnames[0]
 
105
    def on_iter_has_child(self, rowref):
 
106
        return False
 
107
    def on_iter_n_children(self, rowref):
 
108
        logging.debug("on_iter_n_children: %s (%i)" % (rowref, len(self.cache)))
 
109
        if rowref:
 
110
            return 0
 
111
        return len(self.appnames)
 
112
    def on_iter_nth_child(self, parent, n):
 
113
        logging.debug("on_iter_nth_child: %s %i" % (parent, n))
 
114
        if parent:
 
115
            return 0
 
116
        try:
 
117
            return self.appnames[n]
 
118
        except IndexError, e:
 
119
            return None
 
120
    def on_iter_parent(self, child):
 
121
        return None
 
122
 
 
123
def on_entry_changed(widget, data):
 
124
    new_text = widget.get_text()
 
125
    print "on_entry_changed: ", new_text
 
126
    #if len(new_text) < 3:
 
127
    #    return
 
128
    (db, view) = data
 
129
    view.set_model(AppStore(db, icons, new_text))
 
130
 
 
131
if __name__ == "__main__":
 
132
    logging.basicConfig(level=logging.DEBUG)
 
133
 
 
134
    # FIXME: use the apt-xapian-index database too as a additinal
 
135
    #        source (to avoid duplicating data)
 
136
    xapian_base_path = "/var/cache/app-install"
 
137
    pathname = os.path.join(xapian_base_path, "xapian")
 
138
    db = xapian.Database(pathname)
 
139
 
 
140
    # xapian is really cool!
 
141
    #docs = db.get_postlist("XPapt")
 
142
    #section = db.get_postlist("XSdevel")
 
143
 
 
144
    # additional icons come from app-install-data
 
145
    icons = gtk.icon_theme_get_default()
 
146
    icons.append_search_path("/usr/share/app-install/icons/")
 
147
 
 
148
    # now the store
 
149
    store = AppStore(db, icons)
 
150
 
 
151
    # gui
 
152
    scroll = gtk.ScrolledWindow()
 
153
 
 
154
    view = gtk.TreeView()
 
155
    view.set_model(store)
 
156
    view.set_fixed_height_mode(True)
 
157
 
 
158
    tp = gtk.CellRendererPixbuf()
 
159
    column = gtk.TreeViewColumn("Icon", tp, pixbuf=store.COL_ICON)
 
160
    column.set_fixed_width(32)
 
161
    column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
 
162
    view.append_column(column)
 
163
 
 
164
    tr = gtk.CellRendererText()
 
165
    column = gtk.TreeViewColumn("Name", tr, markup=store.COL_NAME)
 
166
    column.set_fixed_width(200)
 
167
    column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
 
168
    view.append_column(column)
 
169
 
 
170
    entry = gtk.Entry()
 
171
    entry.connect("changed", on_entry_changed, (db, view))
 
172
 
 
173
    box = gtk.VBox()
 
174
    box.pack_start(entry, expand=False)
 
175
    box.pack_start(scroll)
 
176
 
 
177
    win = gtk.Window()
 
178
    scroll.add(view)
 
179
    win.add(box)
 
180
    win.set_size_request(400,400)
 
181
    win.show_all()
 
182
 
 
183
    gtk.main()