Merge lp:~mvo/software-center/de-duplication-multiple-pkgnames-lp1043159 into lp:software-center

Proposed by Michael Vogt
Status: Merged
Merged at revision: 3210
Proposed branch: lp:~mvo/software-center/de-duplication-multiple-pkgnames-lp1043159
Merge into: lp:software-center
Prerequisite: lp:~mvo/software-center/exact-match-duplication-lp891613
Diff against target: 230 lines (+57/-38)
6 files modified
softwarecenter/db/categories.py (+3/-4)
softwarecenter/db/database.py (+24/-3)
softwarecenter/db/enquire.py (+1/-1)
softwarecenter/db/utils.py (+0/-14)
softwarecenter/ui/gtk3/views/lobbyview.py (+1/-2)
tests/test_database.py (+28/-14)
To merge this branch: bzr merge lp:~mvo/software-center/de-duplication-multiple-pkgnames-lp1043159
Reviewer Review Type Date Requested Status
Gary Lasker (community) Approve
Review via email: mp+126937@code.launchpad.net

This proposal supersedes a proposal from 2012-09-28.

Description of the change

This branch ensures that duplicatied packages are eliminated from the
get_query_for_pkgnames() if there are multiple documents in the database.
This can happen when a pacakge is available via the apt-xapian-index and
also via the software-center-agent (e.g. packages from extras.ubuntu.com)

To post a comment you must log in.
Revision history for this message
Gary Lasker (gary-lasker) wrote :

Hi Michael, thanks for this branch. Please see my comment in MP https://code.launchpad.net/~mvo/software-center/exact-match-duplication-lp891613/+merge/126902 that describes a strange side-effect that I noticed. It occurs when this branch is merged also. Thanks!

Revision history for this message
Gary Lasker (gary-lasker) wrote :

Hi Michael, when running this branch I'm hitting two exceptions, one at startup as shown:

Traceback (most recent call last):
  File "/home/tremolux/Projects/quantal/software-center_de-duplication_multiple_pkgnames_lp1043159_tweak/software-center/softwarecenter/db/categories.py", line 188, in _recommend_me_result
    self.query = self.db.get_query_for_pkgnames(pkgs)
AttributeError: 'RecommendedForYouCategory' object has no attribute 'db'

And the other when viewing the app details view:

Traceback (most recent call last):
  File "/home/tremolux/Projects/quantal/software-center_de-duplication_multiple_pkgnames_lp1043159_tweak/software-center/softwarecenter/db/categories.py", line 230, in _recommend_app_result
    self.query = self.db.get_query_for_pkgnames(pkgs)
AttributeError: 'AppRecommendationsCategory' object has no attribute 'db'

It seems we are just missing passing the db into a couple of classes. I made a small branch that should take care of these issues, and also updates the unit tests per the changes. Please check it over and feel free to use it if it looks right to you:

  lp:~gary-lasker/software-center/de-duplication-multiple-pkgnames-lp1043159-tweak

I will approve the branch in any case, please feel free to merge with the needed fix (or I can do it tomorrow).

Many thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'softwarecenter/db/categories.py'
2--- softwarecenter/db/categories.py 2012-09-27 13:02:26 +0000
3+++ softwarecenter/db/categories.py 2012-09-28 11:48:24 +0000
4@@ -42,7 +42,6 @@
5 from softwarecenter.backend.recagent import RecommenderAgent
6 from softwarecenter.db.appfilter import AppFilter
7 from softwarecenter.db.enquire import AppEnquire
8-from softwarecenter.db.utils import get_query_for_pkgnames
9 from softwarecenter.region import get_region_cached
10 from softwarecenter.utils import utf8
11
12@@ -183,10 +182,10 @@
13 pkgs.append(item['package_name'])
14 if self.subcategory:
15 self.query = xapian.Query(xapian.Query.OP_AND,
16- get_query_for_pkgnames(pkgs),
17+ self.db.get_query_for_pkgnames(pkgs),
18 self.subcategory.query)
19 else:
20- self.query = get_query_for_pkgnames(pkgs)
21+ self.query = self.db.get_query_for_pkgnames(pkgs)
22 self.emit("needs-refresh")
23
24 def _recommender_agent_error(self, recommender_agent, msg):
25@@ -227,7 +226,7 @@
26 pkgs = []
27 for item in result_list['data']:
28 pkgs.append(item['package_name'])
29- self.query = get_query_for_pkgnames(pkgs)
30+ self.query = self.db.get_query_for_pkgnames(pkgs)
31 self.emit("needs-refresh")
32
33 def _recommender_agent_error(self, recommender_agent, msg):
34
35=== modified file 'softwarecenter/db/database.py'
36--- softwarecenter/db/database.py 2012-09-14 13:40:18 +0000
37+++ softwarecenter/db/database.py 2012-09-28 11:48:24 +0000
38@@ -24,13 +24,12 @@
39 import threading
40 import xapian
41 from softwarecenter.db.application import Application
42-from softwarecenter.db.utils import get_query_for_pkgnames
43 from softwarecenter.db.pkginfo import get_pkg_info
44 import softwarecenter.paths
45
46 from gi.repository import GObject, Gio
47
48-#from softwarecenter.utils import *
49+from softwarecenter.utils import ExecutionTime
50 from softwarecenter.enums import (
51 AVAILABLE_FOR_PURCHASE_MAGIC_CHANNEL_NAME,
52 PkgStates,
53@@ -302,6 +301,28 @@
54 assert popcon_max > 0
55 return popcon_max
56
57+ def get_query_for_pkgnames(self, pkgnames):
58+ """ return a xapian query that matches exactly the list of pkgnames """
59+ enquire = xapian.Enquire(self.xapiandb)
60+ query = xapian.Query()
61+ for pkgname in pkgnames:
62+ # even on the raspbery pi this query super quick (~0.003s)
63+ with ExecutionTime("de-dup query_for_pkgnames"):
64+ tmp_query = xapian.Query("AP" + pkgname)
65+ enquire.set_query(tmp_query)
66+ result = enquire.get_mset(0, 1)
67+ # see bug #1043159, we need to ensure that we de-duplicate
68+ # when there is a pkg and a app (e.g. from the s-c-agent) in the db
69+ if len(result) == 1:
70+ query = xapian.Query(xapian.Query.OP_OR,
71+ query,
72+ xapian.Query("AP" + pkgname))
73+ else:
74+ query = xapian.Query(xapian.Query.OP_OR,
75+ query,
76+ xapian.Query("XP" + pkgname))
77+ return query
78+
79 def get_query_list_from_search_entry(self, search_term,
80 category_query=None):
81 """ get xapian.Query from a search term string and a limit the
82@@ -343,7 +364,7 @@
83 search_term = search_term.strip()
84 # get a pkg query
85 if "," in search_term:
86- pkg_query = get_query_for_pkgnames(search_term.split(","))
87+ pkg_query = self.get_query_for_pkgnames(search_term.split(","))
88 else:
89 pkg_query = xapian.Query()
90 for term in search_term.split():
91
92=== modified file 'softwarecenter/db/enquire.py'
93--- softwarecenter/db/enquire.py 2012-09-28 11:48:24 +0000
94+++ softwarecenter/db/enquire.py 2012-09-28 11:48:24 +0000
95@@ -160,7 +160,7 @@
96 if exact_pkgname_query:
97 with ExecutionTime("de-duplication"):
98 q_app = xapian.Query(terms[0].replace("XP", "AP"))
99- nr_apps, nr_pkgs = self._get_estimate_nr_apps_and_nr_pkgs(
100+ nr_apps, nr_pkgs = self._get_estimate_nr_apps_and_nr_pkgs(
101 enquire, q_app, xfilter)
102 if nr_apps == 1:
103 q = q_app
104
105=== modified file 'softwarecenter/db/utils.py'
106--- softwarecenter/db/utils.py 2012-09-14 07:12:33 +0000
107+++ softwarecenter/db/utils.py 2012-09-28 11:48:24 +0000
108@@ -18,7 +18,6 @@
109
110 import logging
111 import os
112-import xapian
113
114 from gi.repository import GObject
115
116@@ -45,19 +44,6 @@
117 GObject.child_watch_add(pid, _on_update_software_center_agent_finished)
118
119
120-def get_query_for_pkgnames(pkgnames):
121- """ return a xapian query that matches exactly the list of pkgnames """
122- query = xapian.Query()
123- for pkgname in pkgnames:
124- query = xapian.Query(xapian.Query.OP_OR,
125- query,
126- xapian.Query("XP" + pkgname))
127- query = xapian.Query(xapian.Query.OP_OR,
128- query,
129- xapian.Query("AP" + pkgname))
130- return query
131-
132-
133 def get_installed_apps_list(db):
134 """ return a list of installed applications """
135 apps = set()
136
137=== modified file 'softwarecenter/ui/gtk3/views/lobbyview.py'
138--- softwarecenter/ui/gtk3/views/lobbyview.py 2012-09-24 09:49:23 +0000
139+++ softwarecenter/ui/gtk3/views/lobbyview.py 2012-09-28 11:48:24 +0000
140@@ -46,7 +46,6 @@
141 CategoriesParser,
142 get_category_by_name,
143 categories_sorted_by_name)
144-from softwarecenter.db.utils import get_query_for_pkgnames
145 from softwarecenter.distro import get_distro
146 from softwarecenter.backend.scagent import SoftwareCenterAgent
147 from softwarecenter.backend.reviews import get_review_loader
148@@ -131,7 +130,7 @@
149 app = Application("", pkgs[0])
150 self.emit("application-activated", app)
151 else:
152- query = get_query_for_pkgnames(pkgs)
153+ query = self.db.get_query_for_pkgnames(pkgs)
154 title = exhibit.title_translated
155 untranslated_name = exhibit.package_names
156 # create a temp query
157
158=== modified file 'tests/test_database.py'
159--- tests/test_database.py 2012-09-28 11:48:24 +0000
160+++ tests/test_database.py 2012-09-28 11:48:24 +0000
161@@ -45,8 +45,9 @@
162 get_installed_apps_list,
163 )
164 from softwarecenter.enums import (
165+ NonAppVisibility,
166+ PkgStates,
167 XapianValues,
168- PkgStates,
169 )
170 from softwarecenter.region import (
171 REGION_BLACKLIST_TAG,
172@@ -866,32 +867,45 @@
173 ]
174 """
175
176- def test_search_app_pkgname_duplication_lp891613(self):
177- # create a fake database to simualte a run of software-center-agent
178+ @classmethod
179+ def setUpClass(cls):
180 cache = get_pkg_info()
181 cache.open()
182 db = xapian.WritableDatabase(TEST_DB,
183 xapian.DB_CREATE_OR_OVERWRITE)
184- res = update_from_json_string(
185- db, cache, self.APP_INFO_JSON, origin="local")
186+ update_from_json_string(db, cache, cls.APP_INFO_JSON, origin="local")
187 db.close()
188- self.assertTrue(res)
189+
190+ def setUp(self):
191+ # create a fake database to simualte a run of software-center-agent
192 # create a StoreDatabase and add our other db
193- db = get_test_db()
194- db.add_database(xapian.Database(TEST_DB))
195- db.open(use_axi=True)
196- enquire = AppEnquire(db._aptcache, db)
197+ self.db = get_test_db()
198+ self.db.add_database(xapian.Database(TEST_DB))
199+ self.db.open(use_axi=True)
200+ self.enquire = AppEnquire(self.db._aptcache, self.db)
201+
202+ def test_search_app_pkgname_duplication_lp891613(self):
203 # simulate a pkg "apt" that is both in the agent and in the x-a-i db
204 search_term = "apt"
205- search_query = db.get_query_list_from_search_entry(search_term)
206- enquire.set_query(search_query, nonblocking_load=False)
207- self.assertTrue(len(enquire._matches) > 2)
208- for m in enquire._matches:
209+ search_query = self.db.get_query_list_from_search_entry(search_term)
210+ self.enquire.set_query(search_query, nonblocking_load=False)
211+ self.assertTrue(len(self.enquire._matches) > 2)
212+ for m in self.enquire._matches:
213 doc = m.document
214 # ensure that all hits are "apps" and do not come from a-x-i
215 self.assertNotEqual(
216 doc.get_value(XapianValues.PKGNAME), "")
217
218+ def test_search_custom_pkgs_list_lp1043159(self):
219+ # simulate a pkg "apt" that is both in the agent and in the x-a-i db
220+ pkgs = ["apt","gedit"]
221+ search_query = self.db.get_query_for_pkgnames(pkgs)
222+ self.enquire.set_query(search_query,
223+ # custom package lists are always in this mode
224+ nonapps_visible=NonAppVisibility.ALWAYS_VISIBLE,
225+ nonblocking_load=False)
226+ self.assertEqual(len(self.enquire._matches), 2)
227+
228
229 if __name__ == "__main__":
230 #import logging

Subscribers

People subscribed via source and target branches