Merge lp:~ilidrissi.amine/software-center/zeitgeist-unused-applications into lp:software-center

Proposed by Mohamed Amine Ilidrissi
Status: Rejected
Rejected by: Michael Vogt
Proposed branch: lp:~ilidrissi.amine/software-center/zeitgeist-unused-applications
Merge into: lp:software-center
Diff against target: 192 lines (+107/-4)
5 files modified
debian/changelog (+4/-1)
softwarecenter/apt/aptcache.py (+6/-0)
softwarecenter/backend/zeitgeist_simple.py (+28/-2)
softwarecenter/db/database.py (+10/-0)
softwarecenter/view/catview_gtk.py (+59/-1)
To merge this branch: bzr merge lp:~ilidrissi.amine/software-center/zeitgeist-unused-applications
Reviewer Review Type Date Requested Status
Matthew Paul Thomas Disapprove
Review via email: mp+39236@code.launchpad.net

Description of the change

This branch adds support for unused applications via Zeitgeist.
Design feedback is welcome.

To post a comment you must log in.
Revision history for this message
Matthew Paul Thomas (mpt) wrote :

Consider the case of a disk recovery utility. Ideally you will use this rarely, once every few years. That does not mean USC should constantly be nagging you to uninstall it. :-)

I think more useful would be a way to show -- in the "Installed Software" list -- frequency of use, or date last used, or both, and to sort by those columns.

review: Disapprove

Unmerged revisions

1267. By Mohamed Amine Ilidrissi

Code now checks if the app is installed and not a core application (i.e doesn't remove pkgs in IMPORTANT_METAPACKAGES)

1266. By Mohamed Amine Ilidrissi

merge with trunk

1265. By Mohamed Amine Ilidrissi

Added support for removing unused applications via Zeitgeist

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2010-10-19 20:48:05 +0000
3+++ debian/changelog 2010-10-24 22:41:36 +0000
4@@ -13,7 +13,10 @@
5 * softwarecenter/backend/config.py:
6 - don't crash on a corrupted config file (LP: #662414)
7
8- -- Gary Lasker <gary.lasker@canonical.com> Tue, 19 Oct 2010 16:41:40 -0400
9+ [ Mohamed Amine IL Idrissi ]
10+ * Added support for unused application via Zeitgeist
11+
12+ -- Mohamed Amine IL Idrissi <ilidrissiamine@gmail.com> Sun, 24 Oct 2010 22:04:38 +0000
13
14 software-center (3.1.0) natty; urgency=low
15
16
17=== modified file 'softwarecenter/apt/aptcache.py'
18--- softwarecenter/apt/aptcache.py 2010-09-14 20:07:34 +0000
19+++ softwarecenter/apt/aptcache.py 2010-10-24 22:41:36 +0000
20@@ -471,6 +471,12 @@
21 addons_sug = filter(_addons_filter_slow, addons_sug)
22
23 return (addons_rec, addons_sug)
24+
25+ def pkg_is_important(self, pkg, distro):
26+ for m in distro.IMPORTANT_METAPACKAGES:
27+ if m in self.get_depends(pkg):
28+ return True
29+ return False
30
31 if __name__ == "__main__":
32 c = AptCache()
33
34=== modified file 'softwarecenter/backend/zeitgeist_simple.py'
35--- softwarecenter/backend/zeitgeist_simple.py 2010-10-12 08:56:06 +0000
36+++ softwarecenter/backend/zeitgeist_simple.py 2010-10-24 22:41:36 +0000
37@@ -23,7 +23,7 @@
38
39 try:
40 from zeitgeist.client import ZeitgeistClient
41- from zeitgeist.datamodel import Event, Interpretation, ResultType
42+ from zeitgeist.datamodel import Event, Interpretation, ResultType, TimeRange
43 except ImportError:
44 LOG.exception("zeitgeist import failed")
45 ZEITGEIST_AVAILABLE = False
46@@ -89,12 +89,38 @@
47 self.zg_client.find_events_for_template(
48 [], _callback, num_events=1000,
49 result_type=ResultType.MostRecentEvents)
50+
51+ def get_unused_applications(self, callback, timerange=None):
52+ """ Get applications that weren't used for a specific timerange
53+ (defaults to 1 month) and call "callback" with a list of
54+ applications as an argument
55+ """
56+
57+ def _callback(events):
58+ if timerange is not None:
59+ timestamp = int(time.time() - timerange)
60+ else:
61+ timestamp = int(time.time() - (86400000*30)) # one month
62+
63+ unused_apps = []
64+ for e in events:
65+ if int(e.timestamp) < timestamp:
66+ unused_apps.append(e.actor)
67+
68+ callback(unused_apps)
69+
70+ self.zg_client.find_events_for_template(None, _callback,
71+ timerange=TimeRange.always(), num_events=0,
72+ result_type=ResultType.MostRecentActor)
73+
74
75 class SoftwareCenterZeitgeistDummy():
76 def get_usage_counter(self, application, callback, timerange=None):
77 callback(0)
78 def get_popular_mimetypes(self, callback):
79 callback([])
80+ def get_unused_applications(self, callback, timerange=None):
81+ callback([])
82
83 # singleton
84 if ZEITGEIST_AVAILABLE:
85@@ -119,7 +145,7 @@
86 def _callback_popular(mimetypes):
87 print "test _callback: "
88 for tuple in mimetypes:
89- print tuple
90+ print tuple
91 zeitgeist_singleton.get_popular_mimetypes(_callback_popular)
92
93 import gtk
94
95=== modified file 'softwarecenter/db/database.py'
96--- softwarecenter/db/database.py 2010-10-12 08:37:12 +0000
97+++ softwarecenter/db/database.py 2010-10-24 22:41:36 +0000
98@@ -239,6 +239,16 @@
99 if len(apps) == num:
100 break
101 return apps
102+
103+ def get_application_from_desktop_file(self, desktop_file):
104+ enquire = xapian.Enquire(self.xapiandb)
105+ query = xapian.Query("AP%s" % desktop_file[14:-8])
106+ enquire.set_query(query)
107+ matches = enquire.get_mset(0, 100)
108+ for match in matches:
109+ doc = match.get_document()
110+ app = Application(self.get_appname(doc), self.get_pkgname(doc))
111+ return app
112
113 def get_summary(self, doc):
114 """ get human readable summary of the given document """
115
116=== modified file 'softwarecenter/view/catview_gtk.py'
117--- softwarecenter/view/catview_gtk.py 2010-10-12 10:30:11 +0000
118+++ softwarecenter/view/catview_gtk.py 2010-10-24 22:41:36 +0000
119@@ -326,6 +326,7 @@
120 self._append_departments()
121 self._append_featured_and_new()
122 self._append_recommendations()
123+ self._append_unused_applications()
124 return
125
126 def _append_recommendations(self):
127@@ -389,7 +390,64 @@
128
129 zeitgeist_singleton.get_popular_mimetypes(_popular_mimetypes_callback)
130
131-
132+ def _append_unused_applications(self):
133+ def _show_unused_apps_widget(query, r_apps):
134+ # build UI
135+ self.hbox = gtk.HBox()
136+ unused = gettext.ngettext("There is",
137+ "There are",
138+ len(r_apps))
139+ self.hbox.pack_start(gtk.Label(unused), False, False)
140+ label = gettext.ngettext("%(len)i unused applications",
141+ "%(len)i unused applications",
142+ len(r_apps)) % { 'len' : len(r_apps) }
143+ linkbutton = mkit.HLinkButton(label)
144+ linkbutton.set_underline(True)
145+ linkbutton.set_subdued(True)
146+ self.hbox.pack_start(linkbutton, False, False)
147+ self.hbox.pack_start(gtk.Label("you can remove."), False, False)
148+ self.vbox.pack_start(self.hbox, False, False)
149+ self.vbox.reorder_child(self.hbox, -1)
150+ # build fake category
151+ name = gobject.markup_escape_text(_("Unused applications"))
152+ rec_btn = CategoryButton(name, "category-unused", self.icons)
153+ rec_cat = Category("Unused applications", _("Unused Applications"),
154+ "category-unused", query, sortmode=SORT_BY_SEARCH_RANKING)
155+ rec_btn.connect('clicked', self._on_category_clicked, rec_cat)
156+ self.departments.append(rec_btn)
157+
158+ linkbutton.connect('clicked', self._on_category_clicked, rec_cat)
159+
160+ self.show_all()
161+
162+ def _unused_applications_callback(unused):
163+ def _find_applications(names):
164+ apps = []
165+ for name in names:
166+ app = self.db.get_application_from_desktop_file(name)
167+ if app is not None and \
168+ app.get_details(self.db).pkg_state == PKG_STATE_INSTALLED and \
169+ not self.cache.pkg_is_important(app.get_details(self.db).pkg, get_distro()):
170+ apps.append(app)
171+
172+ results = []
173+ for app in apps:
174+ results.append("AP" + app.pkgname)
175+ return results
176+
177+ def _make_query(r_apps):
178+ if len(r_apps) > 0:
179+ return xapian.Query(xapian.Query.OP_OR, r_apps)
180+ return None
181+
182+ # get the unused apps
183+ r_apps =_find_applications(unused)
184+ if r_apps:
185+ # build the widget
186+ _show_unused_apps_widget(_make_query(r_apps), r_apps)
187+
188+ zeitgeist_singleton.get_unused_applications(_unused_applications_callback)
189+
190 def _append_featured_and_new(self):
191 # carousel hbox
192 self.hbox_inner = gtk.HBox(spacing=mkit.SPACING_MED)

Subscribers

People subscribed via source and target branches