Merge lp:~elachuni/software-center/pep8-test-part16 into lp:software-center
- pep8-test-part16
- Merge into trunk
Proposed by
Anthony Lenton
Status: | Merged |
---|---|
Merged at revision: | 2862 |
Proposed branch: | lp:~elachuni/software-center/pep8-test-part16 |
Merge into: | lp:software-center |
Prerequisite: | lp:~elachuni/software-center/pep8-test-part15 |
Diff against target: |
1252 lines (+267/-159) 6 files modified
softwarecenter/db/history_impl/apthistory.py (+22/-19) softwarecenter/db/history_impl/packagekit.py (+11/-7) softwarecenter/db/pkginfo.py (+57/-18) softwarecenter/db/update.py (+164/-104) softwarecenter/db/utils.py (+7/-4) test/test_pep8.py (+6/-7) |
To merge this branch: | bzr merge lp:~elachuni/software-center/pep8-test-part16 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
software-store-developers | Pending | ||
Review via email: mp+97568@code.launchpad.net |
Commit message
Description of the change
Made several files under softwarecenter/db/ pass the pep8 test.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'softwarecenter/db/history_impl/apthistory.py' | |||
2 | --- softwarecenter/db/history_impl/apthistory.py 2011-12-02 14:30:56 +0000 | |||
3 | +++ softwarecenter/db/history_impl/apthistory.py 2012-03-15 04:06:19 +0000 | |||
4 | @@ -33,7 +33,7 @@ | |||
5 | 33 | 33 | ||
6 | 34 | try: | 34 | try: |
7 | 35 | import cPickle as pickle | 35 | import cPickle as pickle |
9 | 36 | pickle # pyflakes | 36 | pickle # pyflakes |
10 | 37 | except ImportError: | 37 | except ImportError: |
11 | 38 | import pickle | 38 | import pickle |
12 | 39 | 39 | ||
13 | @@ -43,20 +43,22 @@ | |||
14 | 43 | from softwarecenter.utils import ExecutionTime | 43 | from softwarecenter.utils import ExecutionTime |
15 | 44 | from softwarecenter.db.history import Transaction, PackageHistory | 44 | from softwarecenter.db.history import Transaction, PackageHistory |
16 | 45 | 45 | ||
17 | 46 | |||
18 | 46 | def ascii_lower(key): | 47 | def ascii_lower(key): |
19 | 47 | ascii_trans_table = string.maketrans(string.ascii_uppercase, | 48 | ascii_trans_table = string.maketrans(string.ascii_uppercase, |
20 | 48 | string.ascii_lowercase) | 49 | string.ascii_lowercase) |
21 | 49 | return key.translate(ascii_trans_table) | 50 | return key.translate(ascii_trans_table) |
22 | 50 | 51 | ||
23 | 52 | |||
24 | 51 | class AptTransaction(Transaction): | 53 | class AptTransaction(Transaction): |
26 | 52 | PKGACTIONS=["Install", "Upgrade", "Downgrade", "Remove", "Purge"] | 54 | PKGACTIONS = ["Install", "Upgrade", "Downgrade", "Remove", "Purge"] |
27 | 53 | 55 | ||
28 | 54 | def __init__(self, sec): | 56 | def __init__(self, sec): |
29 | 55 | self.start_date = datetime.strptime(sec["Start-Date"], | 57 | self.start_date = datetime.strptime(sec["Start-Date"], |
30 | 56 | "%Y-%m-%d %H:%M:%S") | 58 | "%Y-%m-%d %H:%M:%S") |
31 | 57 | # set the object attributes "install", "upgrade", "downgrade", | 59 | # set the object attributes "install", "upgrade", "downgrade", |
32 | 58 | # "remove", "purge", error | 60 | # "remove", "purge", error |
34 | 59 | for k in self.PKGACTIONS+["Error"]: | 61 | for k in self.PKGACTIONS + ["Error"]: |
35 | 60 | # we use ascii_lower for issues described in LP: #581207 | 62 | # we use ascii_lower for issues described in LP: #581207 |
36 | 61 | attr = ascii_lower(k) | 63 | attr = ascii_lower(k) |
37 | 62 | if k in sec: | 64 | if k in sec: |
38 | @@ -68,13 +70,14 @@ | |||
39 | 68 | @staticmethod | 70 | @staticmethod |
40 | 69 | def _fixup_history_item(s): | 71 | def _fixup_history_item(s): |
41 | 70 | """ strip history item string and add missing ")" if needed """ | 72 | """ strip history item string and add missing ")" if needed """ |
43 | 71 | s=s.strip() | 73 | s = s.strip() |
44 | 72 | # remove the infomation about the architecture | 74 | # remove the infomation about the architecture |
45 | 73 | s = re.sub(":\w+", "", s) | 75 | s = re.sub(":\w+", "", s) |
46 | 74 | if "(" in s and not s.endswith(")"): | 76 | if "(" in s and not s.endswith(")"): |
48 | 75 | s+=")" | 77 | s += ")" |
49 | 76 | return s | 78 | return s |
50 | 77 | 79 | ||
51 | 80 | |||
52 | 78 | class AptHistory(PackageHistory): | 81 | class AptHistory(PackageHistory): |
53 | 79 | 82 | ||
54 | 80 | def __init__(self, use_cache=True): | 83 | def __init__(self, use_cache=True): |
55 | @@ -95,6 +98,7 @@ | |||
56 | 95 | @property | 98 | @property |
57 | 96 | def transactions(self): | 99 | def transactions(self): |
58 | 97 | return self._transactions | 100 | return self._transactions |
59 | 101 | |||
60 | 98 | @property | 102 | @property |
61 | 99 | def history_ready(self): | 103 | def history_ready(self): |
62 | 100 | return self._history_ready | 104 | return self._history_ready |
63 | @@ -114,7 +118,7 @@ | |||
64 | 114 | cachetime = os.path.getmtime(p) | 118 | cachetime = os.path.getmtime(p) |
65 | 115 | except: | 119 | except: |
66 | 116 | LOG.exception("failed to load cache") | 120 | LOG.exception("failed to load cache") |
68 | 117 | for history_gz_file in sorted(glob.glob(self.history_file+".*.gz"), | 121 | for history_gz_file in sorted(glob.glob(self.history_file + ".*.gz"), |
69 | 118 | cmp=self._mtime_cmp): | 122 | cmp=self._mtime_cmp): |
70 | 119 | if os.path.getmtime(history_gz_file) < cachetime: | 123 | if os.path.getmtime(history_gz_file) < cachetime: |
71 | 120 | LOG.debug("skipping already cached '%s'" % history_gz_file) | 124 | LOG.debug("skipping already cached '%s'" % history_gz_file) |
72 | @@ -124,8 +128,8 @@ | |||
73 | 124 | if use_cache: | 128 | if use_cache: |
74 | 125 | pickle.dump(self._transactions, open(p, "w")) | 129 | pickle.dump(self._transactions, open(p, "w")) |
75 | 126 | self._history_ready = True | 130 | self._history_ready = True |
78 | 127 | 131 | ||
79 | 128 | def _scan(self, history_file, rescan = False): | 132 | def _scan(self, history_file, rescan=False): |
80 | 129 | LOG.debug("_scan: '%s' (%s)" % (history_file, rescan)) | 133 | LOG.debug("_scan: '%s' (%s)" % (history_file, rescan)) |
81 | 130 | try: | 134 | try: |
82 | 131 | tagfile = apt_pkg.TagFile(open(history_file)) | 135 | tagfile = apt_pkg.TagFile(open(history_file)) |
83 | @@ -136,7 +140,7 @@ | |||
84 | 136 | # keep the UI alive | 140 | # keep the UI alive |
85 | 137 | while self.main_context.pending(): | 141 | while self.main_context.pending(): |
86 | 138 | self.main_context.iteration() | 142 | self.main_context.iteration() |
88 | 139 | # ignore records with | 143 | # ignore records with |
89 | 140 | try: | 144 | try: |
90 | 141 | trans = AptTransaction(stanza) | 145 | trans = AptTransaction(stanza) |
91 | 142 | except (KeyError, ValueError): | 146 | except (KeyError, ValueError): |
92 | @@ -151,16 +155,16 @@ | |||
93 | 151 | # so we could (and should) do a binary search | 155 | # so we could (and should) do a binary search |
94 | 152 | if not trans in self._transactions: | 156 | if not trans in self._transactions: |
95 | 153 | self._transactions.insert(0, trans) | 157 | self._transactions.insert(0, trans) |
97 | 154 | 158 | ||
98 | 155 | def _on_apt_history_changed(self, monitor, afile, other_file, event): | 159 | def _on_apt_history_changed(self, monitor, afile, other_file, event): |
101 | 156 | if event == Gio.FileMonitorEvent.CHANGES_DONE_HINT: | 160 | if event == Gio.FileMonitorEvent.CHANGES_DONE_HINT: |
102 | 157 | self._scan(self.history_file, rescan = True) | 161 | self._scan(self.history_file, rescan=True) |
103 | 158 | if self.update_callback: | 162 | if self.update_callback: |
104 | 159 | self.update_callback() | 163 | self.update_callback() |
109 | 160 | 164 | ||
110 | 161 | def set_on_update(self,update_callback): | 165 | def set_on_update(self, update_callback): |
111 | 162 | self.update_callback=update_callback | 166 | self.update_callback = update_callback |
112 | 163 | 167 | ||
113 | 164 | def get_installed_date(self, pkg_name): | 168 | def get_installed_date(self, pkg_name): |
114 | 165 | installed_date = None | 169 | installed_date = None |
115 | 166 | for trans in self._transactions: | 170 | for trans in self._transactions: |
116 | @@ -169,7 +173,7 @@ | |||
117 | 169 | installed_date = trans.start_date | 173 | installed_date = trans.start_date |
118 | 170 | return installed_date | 174 | return installed_date |
119 | 171 | return installed_date | 175 | return installed_date |
121 | 172 | 176 | ||
122 | 173 | def _find_in_terminal_log(self, date, term_file): | 177 | def _find_in_terminal_log(self, date, term_file): |
123 | 174 | found = False | 178 | found = False |
124 | 175 | term_lines = [] | 179 | term_lines = [] |
125 | @@ -191,9 +195,8 @@ | |||
126 | 191 | term_lines = self._find_in_terminal_log(date, open(term)) | 195 | term_lines = self._find_in_terminal_log(date, open(term)) |
127 | 192 | # now search the older history | 196 | # now search the older history |
128 | 193 | if not term_lines: | 197 | if not term_lines: |
130 | 194 | for f in glob.glob(term+".*.gz"): | 198 | for f in glob.glob(term + ".*.gz"): |
131 | 195 | term_lines = self._find_in_terminal_log(date, gzip.open(f)) | 199 | term_lines = self._find_in_terminal_log(date, gzip.open(f)) |
132 | 196 | if term_lines: | 200 | if term_lines: |
133 | 197 | return term_lines | 201 | return term_lines |
134 | 198 | return term_lines | 202 | return term_lines |
135 | 199 | |||
136 | 200 | 203 | ||
137 | === modified file 'softwarecenter/db/history_impl/packagekit.py' | |||
138 | --- softwarecenter/db/history_impl/packagekit.py 2011-12-02 14:30:56 +0000 | |||
139 | +++ softwarecenter/db/history_impl/packagekit.py 2012-03-15 04:06:19 +0000 | |||
140 | @@ -22,6 +22,7 @@ | |||
141 | 22 | 22 | ||
142 | 23 | LOG = logging.getLogger(__name__) | 23 | LOG = logging.getLogger(__name__) |
143 | 24 | 24 | ||
144 | 25 | |||
145 | 25 | class PackagekitTransaction(Transaction): | 26 | class PackagekitTransaction(Transaction): |
146 | 26 | def __init__(self, pktrans): | 27 | def __init__(self, pktrans): |
147 | 27 | self.start_date = datetime.strptime(pktrans.props.timespec, | 28 | self.start_date = datetime.strptime(pktrans.props.timespec, |
148 | @@ -31,7 +32,8 @@ | |||
149 | 31 | self.upgrade = [] | 32 | self.upgrade = [] |
150 | 32 | self.downgrade = [] | 33 | self.downgrade = [] |
151 | 33 | self.remove = [] | 34 | self.remove = [] |
153 | 34 | self.purge = [] # can't happen with a Packagekit backend (is mapped to remove) | 35 | self.purge = [] # can't happen with a Packagekit backend (is mapped |
154 | 36 | # to remove) | ||
155 | 35 | 37 | ||
156 | 36 | # parse transaction data | 38 | # parse transaction data |
157 | 37 | lines = pktrans.props.data.split('\n') | 39 | lines = pktrans.props.data.split('\n') |
158 | @@ -51,13 +53,15 @@ | |||
159 | 51 | elif action == 'removing': | 53 | elif action == 'removing': |
160 | 52 | self.remove.append(package_name) | 54 | self.remove.append(package_name) |
161 | 53 | else: | 55 | else: |
163 | 54 | # ignore other actions (include cleanup, downloading and untrusted) | 56 | # ignore other actions (include cleanup, downloading and |
164 | 57 | # untrusted) | ||
165 | 55 | continue | 58 | continue |
166 | 56 | except: | 59 | except: |
167 | 57 | LOG.warn("malformed line emitted by PackageKit, was %s" % line) | 60 | LOG.warn("malformed line emitted by PackageKit, was %s" % line) |
168 | 58 | 61 | ||
169 | 62 | |||
170 | 59 | class PackagekitHistory(PackageHistory): | 63 | class PackagekitHistory(PackageHistory): |
172 | 60 | """ Represents the history of the transactions """ | 64 | """ Represents the history of the transactions """ |
173 | 61 | 65 | ||
174 | 62 | def __init__(self, use_cache=True): | 66 | def __init__(self, use_cache=True): |
175 | 63 | self._use_cache = use_cache | 67 | self._use_cache = use_cache |
176 | @@ -66,9 +70,9 @@ | |||
177 | 66 | 70 | ||
178 | 67 | self._client = PackageKitGlib.Client() | 71 | self._client = PackageKitGlib.Client() |
179 | 68 | self._client.get_old_transactions_async(0, | 72 | self._client.get_old_transactions_async(0, |
183 | 69 | None, # cancellable | 73 | None, # cancellable |
184 | 70 | lambda *args, **kwargs: None, None, # progress callback | 74 | lambda *args, **kwargs: None, None, # progress callback |
185 | 71 | self._transactions_received, None) | 75 | self._transactions_received, None) |
186 | 72 | 76 | ||
187 | 73 | @property | 77 | @property |
188 | 74 | def history_ready(self): | 78 | def history_ready(self): |
189 | @@ -86,7 +90,7 @@ | |||
190 | 86 | 90 | ||
191 | 87 | def get_installed_date(self, pkg_name): | 91 | def get_installed_date(self, pkg_name): |
192 | 88 | """Return the date that the given package name got instaled """ | 92 | """Return the date that the given package name got instaled """ |
194 | 89 | return None | 93 | pass |
195 | 90 | 94 | ||
196 | 91 | def _transactions_received(self, client, async_result, user_data): | 95 | def _transactions_received(self, client, async_result, user_data): |
197 | 92 | try: | 96 | try: |
198 | 93 | 97 | ||
199 | === modified file 'softwarecenter/db/pkginfo.py' | |||
200 | --- softwarecenter/db/pkginfo.py 2012-02-14 09:51:45 +0000 | |||
201 | +++ softwarecenter/db/pkginfo.py 2012-03-15 04:06:19 +0000 | |||
202 | @@ -18,28 +18,36 @@ | |||
203 | 18 | 18 | ||
204 | 19 | from gi.repository import GObject | 19 | from gi.repository import GObject |
205 | 20 | 20 | ||
206 | 21 | |||
207 | 21 | class _Version: | 22 | class _Version: |
208 | 22 | @property | 23 | @property |
209 | 23 | def description(self): | 24 | def description(self): |
210 | 24 | pass | 25 | pass |
211 | 26 | |||
212 | 25 | @property | 27 | @property |
213 | 26 | def downloadable(self): | 28 | def downloadable(self): |
214 | 27 | pass | 29 | pass |
215 | 30 | |||
216 | 28 | @property | 31 | @property |
217 | 29 | def summary(self): | 32 | def summary(self): |
218 | 30 | pass | 33 | pass |
219 | 34 | |||
220 | 31 | @property | 35 | @property |
221 | 32 | def size(self): | 36 | def size(self): |
222 | 33 | return self.pkginfo.get_size(self.name) | 37 | return self.pkginfo.get_size(self.name) |
223 | 38 | |||
224 | 34 | @property | 39 | @property |
225 | 35 | def installed_size(self): | 40 | def installed_size(self): |
226 | 36 | return 0 | 41 | return 0 |
227 | 42 | |||
228 | 37 | @property | 43 | @property |
229 | 38 | def version(self): | 44 | def version(self): |
230 | 39 | pass | 45 | pass |
231 | 46 | |||
232 | 40 | @property | 47 | @property |
233 | 41 | def origins(self): | 48 | def origins(self): |
234 | 42 | return [] | 49 | return [] |
235 | 50 | |||
236 | 43 | @property | 51 | @property |
237 | 44 | def not_automatic(self): | 52 | def not_automatic(self): |
238 | 45 | """ should not be installed/upgraded automatically, the user needs | 53 | """ should not be installed/upgraded automatically, the user needs |
239 | @@ -47,22 +55,26 @@ | |||
240 | 47 | """ | 55 | """ |
241 | 48 | return False | 56 | return False |
242 | 49 | 57 | ||
243 | 58 | |||
244 | 50 | class _Package: | 59 | class _Package: |
245 | 51 | def __init__(self, name, pkginfo): | 60 | def __init__(self, name, pkginfo): |
246 | 52 | self.name = name | 61 | self.name = name |
247 | 53 | self.pkginfo = pkginfo | 62 | self.pkginfo = pkginfo |
248 | 63 | |||
249 | 54 | def __str__(self): | 64 | def __str__(self): |
251 | 55 | return repr(self).replace('<', '<pkgname=%s ' % self.name) | 65 | return repr(self).replace('<', '<pkgname=%s ' % self.name) |
252 | 66 | |||
253 | 56 | @property | 67 | @property |
254 | 57 | def installed(self): | 68 | def installed(self): |
255 | 58 | """ returns a _Version object """ | 69 | """ returns a _Version object """ |
259 | 59 | if not self.pkginfo.is_installed(self.name): | 70 | if self.pkginfo.is_installed(self.name): |
260 | 60 | return None | 71 | return self.pkginfo.get_installed(self.name) |
261 | 61 | return self.pkginfo.get_installed(self.name) | 72 | |
262 | 62 | @property | 73 | @property |
263 | 63 | def candidate(self): | 74 | def candidate(self): |
264 | 64 | """ returns a _Version object """ | 75 | """ returns a _Version object """ |
265 | 65 | return self.pkginfo.get_candidate(self.name) | 76 | return self.pkginfo.get_candidate(self.name) |
266 | 77 | |||
267 | 66 | @property | 78 | @property |
268 | 67 | def versions(self): | 79 | def versions(self): |
269 | 68 | """ a list of available versions (as _Version) to install """ | 80 | """ a list of available versions (as _Version) to install """ |
270 | @@ -71,18 +83,23 @@ | |||
271 | 71 | @property | 83 | @property |
272 | 72 | def is_installed(self): | 84 | def is_installed(self): |
273 | 73 | return self.pkginfo.is_installed(self.name) | 85 | return self.pkginfo.is_installed(self.name) |
274 | 86 | |||
275 | 74 | @property | 87 | @property |
276 | 75 | def is_upgradable(self): | 88 | def is_upgradable(self): |
277 | 76 | return self.pkginfo.is_upgradable(self.name) | 89 | return self.pkginfo.is_upgradable(self.name) |
278 | 90 | |||
279 | 77 | @property | 91 | @property |
280 | 78 | def section(self): | 92 | def section(self): |
281 | 79 | return self.pkginfo.get_section(self.name) | 93 | return self.pkginfo.get_section(self.name) |
282 | 94 | |||
283 | 80 | @property | 95 | @property |
284 | 81 | def website(self): | 96 | def website(self): |
285 | 82 | return self.pkginfo.get_website(self.name) | 97 | return self.pkginfo.get_website(self.name) |
286 | 98 | |||
287 | 83 | @property | 99 | @property |
288 | 84 | def installed_files(self): | 100 | def installed_files(self): |
289 | 85 | return self.pkginfo.get_installed_files(self.name) | 101 | return self.pkginfo.get_installed_files(self.name) |
290 | 102 | |||
291 | 86 | @property | 103 | @property |
292 | 87 | def description(self): | 104 | def description(self): |
293 | 88 | return self.pkginfo.get_description(self.name) | 105 | return self.pkginfo.get_description(self.name) |
294 | @@ -91,22 +108,24 @@ | |||
295 | 91 | def license(self): | 108 | def license(self): |
296 | 92 | return self.pkginfo.get_license(self.name) | 109 | return self.pkginfo.get_license(self.name) |
297 | 93 | 110 | ||
298 | 111 | |||
299 | 94 | class PackageInfo(GObject.GObject): | 112 | class PackageInfo(GObject.GObject): |
300 | 95 | """ abstract interface for the packageinfo information """ | 113 | """ abstract interface for the packageinfo information """ |
301 | 96 | 114 | ||
311 | 97 | __gsignals__ = {'cache-ready': (GObject.SIGNAL_RUN_FIRST, | 115 | __gsignals__ = {'cache-ready': (GObject.SIGNAL_RUN_FIRST, |
312 | 98 | GObject.TYPE_NONE, | 116 | GObject.TYPE_NONE, |
313 | 99 | ()), | 117 | ()), |
314 | 100 | 'cache-invalid':(GObject.SIGNAL_RUN_FIRST, | 118 | 'cache-invalid': (GObject.SIGNAL_RUN_FIRST, |
315 | 101 | GObject.TYPE_NONE, | 119 | GObject.TYPE_NONE, |
316 | 102 | ()), | 120 | ()), |
317 | 103 | 'cache-broken':(GObject.SIGNAL_RUN_FIRST, | 121 | 'cache-broken': (GObject.SIGNAL_RUN_FIRST, |
318 | 104 | GObject.TYPE_NONE, | 122 | GObject.TYPE_NONE, |
319 | 105 | ()), | 123 | ()), |
320 | 106 | } | 124 | } |
321 | 107 | 125 | ||
322 | 108 | def __getitem__(self, k): | 126 | def __getitem__(self, k): |
323 | 109 | return _Package(k, self) | 127 | return _Package(k, self) |
324 | 128 | |||
325 | 110 | def __contains__(self, pkgname): | 129 | def __contains__(self, pkgname): |
326 | 111 | return False | 130 | return False |
327 | 112 | 131 | ||
328 | @@ -114,10 +133,12 @@ | |||
329 | 114 | def version_compare(v1, v2): | 133 | def version_compare(v1, v2): |
330 | 115 | """ compare two versions """ | 134 | """ compare two versions """ |
331 | 116 | return cmp(v1, v2) | 135 | return cmp(v1, v2) |
332 | 136 | |||
333 | 117 | @staticmethod | 137 | @staticmethod |
334 | 118 | def upstream_version_compare(v1, v2): | 138 | def upstream_version_compare(v1, v2): |
335 | 119 | """ compare two versions, but ignore the distro specific revisions """ | 139 | """ compare two versions, but ignore the distro specific revisions """ |
336 | 120 | return cmp(v1, v2) | 140 | return cmp(v1, v2) |
337 | 141 | |||
338 | 121 | @staticmethod | 142 | @staticmethod |
339 | 122 | def upstream_version(v): | 143 | def upstream_version(v): |
340 | 123 | """ Return the "upstream" version number of the given version """ | 144 | """ Return the "upstream" version number of the given version """ |
341 | @@ -125,34 +146,47 @@ | |||
342 | 125 | 146 | ||
343 | 126 | def is_installed(self, pkgname): | 147 | def is_installed(self, pkgname): |
344 | 127 | pass | 148 | pass |
345 | 149 | |||
346 | 128 | def is_available(self, pkgname): | 150 | def is_available(self, pkgname): |
347 | 129 | pass | 151 | pass |
348 | 152 | |||
349 | 130 | def get_installed(self, pkgname): | 153 | def get_installed(self, pkgname): |
350 | 131 | pass | 154 | pass |
351 | 155 | |||
352 | 132 | def get_candidate(self, pkgname): | 156 | def get_candidate(self, pkgname): |
353 | 133 | pass | 157 | pass |
354 | 158 | |||
355 | 134 | def get_versions(self, pkgname): | 159 | def get_versions(self, pkgname): |
356 | 135 | return [] | 160 | return [] |
357 | 136 | 161 | ||
358 | 137 | def get_section(self, pkgname): | 162 | def get_section(self, pkgname): |
359 | 138 | pass | 163 | pass |
360 | 164 | |||
361 | 139 | def get_summary(self, pkgname): | 165 | def get_summary(self, pkgname): |
362 | 140 | pass | 166 | pass |
363 | 167 | |||
364 | 141 | def get_description(self, pkgname): | 168 | def get_description(self, pkgname): |
365 | 142 | pass | 169 | pass |
366 | 170 | |||
367 | 143 | def get_website(self, pkgname): | 171 | def get_website(self, pkgname): |
368 | 144 | pass | 172 | pass |
369 | 173 | |||
370 | 145 | def get_installed_files(self, pkgname): | 174 | def get_installed_files(self, pkgname): |
371 | 146 | return [] | 175 | return [] |
372 | 176 | |||
373 | 147 | def get_size(self, pkgname): | 177 | def get_size(self, pkgname): |
374 | 148 | return -1 | 178 | return -1 |
375 | 179 | |||
376 | 149 | def get_installed_size(self, pkgname): | 180 | def get_installed_size(self, pkgname): |
377 | 150 | return -1 | 181 | return -1 |
378 | 182 | |||
379 | 151 | def get_origins(self, pkgname): | 183 | def get_origins(self, pkgname): |
380 | 152 | return [] | 184 | return [] |
381 | 185 | |||
382 | 153 | def get_origin(self, pkgname): | 186 | def get_origin(self, pkgname): |
383 | 154 | """ :return: unique origin as string """ | 187 | """ :return: unique origin as string """ |
384 | 155 | return '' | 188 | return '' |
385 | 189 | |||
386 | 156 | def get_addons(self, pkgname, ignore_installed=False): | 190 | def get_addons(self, pkgname, ignore_installed=False): |
387 | 157 | """ :return: a tuple of pkgnames (recommends, suggests) """ | 191 | """ :return: a tuple of pkgnames (recommends, suggests) """ |
388 | 158 | return ([], []) | 192 | return ([], []) |
389 | @@ -167,27 +201,30 @@ | |||
390 | 167 | which will be removed if the package is installed.""" | 201 | which will be removed if the package is installed.""" |
391 | 168 | return [] | 202 | return [] |
392 | 169 | 203 | ||
394 | 170 | def get_total_size_on_install(self, pkgname, | 204 | def get_total_size_on_install(self, pkgname, |
395 | 171 | addons_install=None, addons_remove=None, | 205 | addons_install=None, addons_remove=None, |
396 | 172 | archive_suite=None): | 206 | archive_suite=None): |
397 | 173 | """ Returns a tuple (download_size, installed_size) | 207 | """ Returns a tuple (download_size, installed_size) |
398 | 174 | with disk size in KB calculated for pkgname installation | 208 | with disk size in KB calculated for pkgname installation |
400 | 175 | plus addons change and a (optional) archive_suite that the | 209 | plus addons change and a (optional) archive_suite that the |
401 | 176 | package comes from | 210 | package comes from |
402 | 177 | """ | 211 | """ |
403 | 178 | return (0, 0) | 212 | return (0, 0) |
404 | 179 | 213 | ||
405 | 180 | def open(self): | 214 | def open(self): |
407 | 181 | """ | 215 | """ |
408 | 182 | (re)open the cache, this sends cache-invalid, cache-ready signals | 216 | (re)open the cache, this sends cache-invalid, cache-ready signals |
409 | 183 | """ | 217 | """ |
410 | 184 | pass | 218 | pass |
411 | 219 | |||
412 | 185 | @property | 220 | @property |
413 | 186 | def ready(self): | 221 | def ready(self): |
414 | 187 | pass | 222 | pass |
415 | 188 | 223 | ||
416 | 189 | # singleton | 224 | # singleton |
417 | 190 | pkginfo = None | 225 | pkginfo = None |
418 | 226 | |||
419 | 227 | |||
420 | 191 | def get_pkg_info(): | 228 | def get_pkg_info(): |
421 | 192 | global pkginfo | 229 | global pkginfo |
422 | 193 | if pkginfo is None: | 230 | if pkginfo is None: |
423 | @@ -196,6 +233,8 @@ | |||
424 | 196 | from softwarecenter.db.pkginfo_impl.aptcache import AptCache | 233 | from softwarecenter.db.pkginfo_impl.aptcache import AptCache |
425 | 197 | pkginfo = AptCache() | 234 | pkginfo = AptCache() |
426 | 198 | else: | 235 | else: |
429 | 199 | from softwarecenter.db.pkginfo_impl.packagekit import PackagekitInfo | 236 | from softwarecenter.db.pkginfo_impl.packagekit import ( |
430 | 200 | pkginfo = PackagekitInfo() | 237 | PackagekitInfo, |
431 | 238 | ) | ||
432 | 239 | pkginfo = PackagekitInfo() | ||
433 | 201 | return pkginfo | 240 | return pkginfo |
434 | 202 | 241 | ||
435 | === modified file 'softwarecenter/db/update.py' | |||
436 | --- softwarecenter/db/update.py 2012-02-28 22:35:19 +0000 | |||
437 | +++ softwarecenter/db/update.py 2012-03-15 04:06:19 +0000 | |||
438 | @@ -36,15 +36,15 @@ | |||
439 | 36 | # py3 compat | 36 | # py3 compat |
440 | 37 | try: | 37 | try: |
441 | 38 | from configparser import RawConfigParser, NoOptionError | 38 | from configparser import RawConfigParser, NoOptionError |
444 | 39 | RawConfigParser # pyflakes | 39 | RawConfigParser # pyflakes |
445 | 40 | NoOptionError # pyflakes | 40 | NoOptionError # pyflakes |
446 | 41 | except ImportError: | 41 | except ImportError: |
447 | 42 | from ConfigParser import RawConfigParser, NoOptionError | 42 | from ConfigParser import RawConfigParser, NoOptionError |
448 | 43 | 43 | ||
449 | 44 | # py3 compat | 44 | # py3 compat |
450 | 45 | try: | 45 | try: |
451 | 46 | import cPickle as pickle | 46 | import cPickle as pickle |
453 | 47 | pickle # pyflakes | 47 | pickle # pyflakes |
454 | 48 | except ImportError: | 48 | except ImportError: |
455 | 49 | import pickle | 49 | import pickle |
456 | 50 | 50 | ||
457 | @@ -101,6 +101,7 @@ | |||
458 | 101 | # Enable Xapian's CJK tokenizer (see LP: #745243) | 101 | # Enable Xapian's CJK tokenizer (see LP: #745243) |
459 | 102 | os.environ['XAPIAN_CJK_NGRAM'] = '1' | 102 | os.environ['XAPIAN_CJK_NGRAM'] = '1' |
460 | 103 | 103 | ||
461 | 104 | |||
462 | 104 | class AppInfoParserBase(object): | 105 | class AppInfoParserBase(object): |
463 | 105 | """ base class for reading AppInfo meta-data """ | 106 | """ base class for reading AppInfo meta-data """ |
464 | 106 | 107 | ||
465 | @@ -108,8 +109,10 @@ | |||
466 | 108 | 109 | ||
467 | 109 | def get_desktop(self, key, translated=True): | 110 | def get_desktop(self, key, translated=True): |
468 | 110 | """ get a AppInfo entry for the given key """ | 111 | """ get a AppInfo entry for the given key """ |
469 | 112 | |||
470 | 111 | def has_option_desktop(self, key): | 113 | def has_option_desktop(self, key): |
471 | 112 | """ return True if there is a given AppInfo info """ | 114 | """ return True if there is a given AppInfo info """ |
472 | 115 | |||
473 | 113 | def _get_desktop_list(self, key, split_str=";"): | 116 | def _get_desktop_list(self, key, split_str=";"): |
474 | 114 | result = [] | 117 | result = [] |
475 | 115 | try: | 118 | try: |
476 | @@ -120,6 +123,7 @@ | |||
477 | 120 | except (NoOptionError, KeyError): | 123 | except (NoOptionError, KeyError): |
478 | 121 | pass | 124 | pass |
479 | 122 | return result | 125 | return result |
480 | 126 | |||
481 | 123 | def _apply_mapping(self, key): | 127 | def _apply_mapping(self, key): |
482 | 124 | # strip away bogus prefixes | 128 | # strip away bogus prefixes |
483 | 125 | if key.startswith("X-AppInstall-"): | 129 | if key.startswith("X-AppInstall-"): |
484 | @@ -127,12 +131,15 @@ | |||
485 | 127 | if key in self.MAPPING: | 131 | if key in self.MAPPING: |
486 | 128 | return self.MAPPING[key] | 132 | return self.MAPPING[key] |
487 | 129 | return key | 133 | return key |
488 | 134 | |||
489 | 130 | def get_desktop_categories(self): | 135 | def get_desktop_categories(self): |
490 | 131 | return self._get_desktop_list("Categories") | 136 | return self._get_desktop_list("Categories") |
491 | 137 | |||
492 | 132 | def get_desktop_mimetypes(self): | 138 | def get_desktop_mimetypes(self): |
493 | 133 | if not self.has_option_desktop("MimeType"): | 139 | if not self.has_option_desktop("MimeType"): |
494 | 134 | return [] | 140 | return [] |
495 | 135 | return self._get_desktop_list("MimeType") | 141 | return self._get_desktop_list("MimeType") |
496 | 142 | |||
497 | 136 | @property | 143 | @property |
498 | 137 | def desktopf(self): | 144 | def desktopf(self): |
499 | 138 | """ return the file that the AppInfo comes from """ | 145 | """ return the file that the AppInfo comes from """ |
500 | @@ -142,29 +149,29 @@ | |||
501 | 142 | """ map the data we get from the software-center-agent """ | 149 | """ map the data we get from the software-center-agent """ |
502 | 143 | 150 | ||
503 | 144 | # map from requested key to sca_application attribute | 151 | # map from requested key to sca_application attribute |
523 | 145 | MAPPING = { 'Name' : 'name', | 152 | MAPPING = {'Name': 'name', |
524 | 146 | 'Price' : 'price', | 153 | 'Price': 'price', |
525 | 147 | 'Package' : 'package_name', | 154 | 'Package': 'package_name', |
526 | 148 | 'Categories' : 'categories', | 155 | 'Categories': 'categories', |
527 | 149 | 'Channel' : 'channel', | 156 | 'Channel': 'channel', |
528 | 150 | 'Signing-Key-Id' : 'signing_key_id', | 157 | 'Signing-Key-Id': 'signing_key_id', |
529 | 151 | 'License' : 'license', | 158 | 'License': 'license', |
530 | 152 | 'Date-Published' : 'date_published', | 159 | 'Date-Published': 'date_published', |
531 | 153 | 'PPA' : 'archive_id', | 160 | 'PPA': 'archive_id', |
532 | 154 | 'Screenshot-Url' : 'screenshot_url', | 161 | 'Screenshot-Url': 'screenshot_url', |
533 | 155 | 'Thumbnail-Url' : 'thumbnail_url', | 162 | 'Thumbnail-Url': 'thumbnail_url', |
534 | 156 | 'Video-Url' : 'video_embedded_html_url', | 163 | 'Video-Url': 'video_embedded_html_url', |
535 | 157 | 'Icon-Url' : 'icon_url', | 164 | 'Icon-Url': 'icon_url', |
536 | 158 | 'Support-Url' : 'support_url', | 165 | 'Support-Url': 'support_url', |
537 | 159 | 'Description' : 'Description', | 166 | 'Description': 'Description', |
538 | 160 | 'Comment' : 'Comment', | 167 | 'Comment': 'Comment', |
539 | 161 | 'Version' : 'version', | 168 | 'Version': 'version', |
540 | 162 | 'Supported-Distros': 'series', | 169 | 'Supported-Distros': 'series', |
541 | 163 | # tags are special, see _apply_exception | 170 | # tags are special, see _apply_exception |
542 | 164 | } | 171 | } |
543 | 165 | 172 | ||
544 | 166 | # map from requested key to a static data element | 173 | # map from requested key to a static data element |
546 | 167 | STATIC_DATA = { 'Type' : 'Application', | 174 | STATIC_DATA = {'Type': 'Application', |
547 | 168 | } | 175 | } |
548 | 169 | 176 | ||
549 | 170 | def __init__(self, sca_application): | 177 | def __init__(self, sca_application): |
550 | @@ -179,19 +186,23 @@ | |||
551 | 179 | # we no longer keep thumbnail versions of screenshots on the server | 186 | # we no longer keep thumbnail versions of screenshots on the server |
552 | 180 | if (hasattr(self.sca_application, "screenshot_url") and | 187 | if (hasattr(self.sca_application, "screenshot_url") and |
553 | 181 | not hasattr(self.sca_application, "thumbnail_url")): | 188 | not hasattr(self.sca_application, "thumbnail_url")): |
555 | 182 | self.sca_application.thumbnail_url = self.sca_application.screenshot_url | 189 | self.sca_application.thumbnail_url = \ |
556 | 190 | self.sca_application.screenshot_url | ||
557 | 183 | if hasattr(self.sca_application, "description"): | 191 | if hasattr(self.sca_application, "description"): |
559 | 184 | self.sca_application.Comment = self.sca_application.description.split("\n")[0].strip() | 192 | comment = self.sca_application.description.split("\n")[0].strip() |
560 | 193 | self.sca_application.Comment = comment | ||
561 | 185 | self.sca_application.Description = "\n".join( | 194 | self.sca_application.Description = "\n".join( |
562 | 186 | self.sca_application.description.split("\n")[1:]).strip() | 195 | self.sca_application.description.split("\n")[1:]).strip() |
563 | 187 | 196 | ||
564 | 188 | # debtags is send as a list, but we need it as a comma seperated string | 197 | # debtags is send as a list, but we need it as a comma seperated string |
566 | 189 | self.sca_application.Tags = ",".join(getattr(self.sca_application, "debtags", [])) | 198 | self.sca_application.Tags = ",".join(getattr(self.sca_application, |
567 | 199 | "debtags", [])) | ||
568 | 190 | 200 | ||
569 | 191 | # we only support a single video currently :/ | 201 | # we only support a single video currently :/ |
570 | 192 | if hasattr(self.sca_application, "video_embedded_html_urls"): | 202 | if hasattr(self.sca_application, "video_embedded_html_urls"): |
571 | 193 | if self.sca_application.video_embedded_html_urls: | 203 | if self.sca_application.video_embedded_html_urls: |
573 | 194 | self.sca_application.video_embedded_html_url = self.sca_application.video_embedded_html_urls[0] | 204 | video_url = self.sca_application.video_embedded_html_urls[0] |
574 | 205 | self.sca_application.video_embedded_html_url = video_url | ||
575 | 195 | 206 | ||
576 | 196 | # XXX 2012-01-16 bug=917109 | 207 | # XXX 2012-01-16 bug=917109 |
577 | 197 | # We can remove these work-arounds once the above bug is fixed on | 208 | # We can remove these work-arounds once the above bug is fixed on |
578 | @@ -199,7 +210,8 @@ | |||
579 | 199 | # to make the parser happy. Note: available_apps api call includes | 210 | # to make the parser happy. Note: available_apps api call includes |
580 | 200 | # these already, it's just the apps with subscriptions_for_me which | 211 | # these already, it's just the apps with subscriptions_for_me which |
581 | 201 | # don't currently. | 212 | # don't currently. |
583 | 202 | self.sca_application.channel = AVAILABLE_FOR_PURCHASE_MAGIC_CHANNEL_NAME | 213 | self.sca_application.channel = \ |
584 | 214 | AVAILABLE_FOR_PURCHASE_MAGIC_CHANNEL_NAME | ||
585 | 203 | if not hasattr(self.sca_application, 'categories'): | 215 | if not hasattr(self.sca_application, 'categories'): |
586 | 204 | self.sca_application.categories = "" | 216 | self.sca_application.categories = "" |
587 | 205 | 217 | ||
588 | @@ -207,16 +219,16 @@ | |||
589 | 207 | # attribute appropriately so that the channel-adding magic works | 219 | # attribute appropriately so that the channel-adding magic works |
590 | 208 | if hasattr(self.sca_application, "archive_root"): | 220 | if hasattr(self.sca_application, "archive_root"): |
591 | 209 | u = urlparse(self.sca_application.archive_root) | 221 | u = urlparse(self.sca_application.archive_root) |
593 | 210 | if u.scheme == "http" and u.netloc == "archive.canonical.com": | 222 | if u.scheme == "http" and u.netloc == "archive.canonical.com": |
594 | 211 | distroseries = get_distro().get_codename() | 223 | distroseries = get_distro().get_codename() |
595 | 212 | self.sca_application.channel = "%s-partner" % distroseries | 224 | self.sca_application.channel = "%s-partner" % distroseries |
597 | 213 | if u.scheme == "http" and u.netloc == "extras.ubuntu.com": | 225 | if u.scheme == "http" and u.netloc == "extras.ubuntu.com": |
598 | 214 | self.sca_application.channel = "ubuntu-extras" | 226 | self.sca_application.channel = "ubuntu-extras" |
600 | 215 | 227 | ||
601 | 216 | # support multiple screenshots | 228 | # support multiple screenshots |
602 | 217 | if hasattr(self.sca_application, "screenshot_urls"): | 229 | if hasattr(self.sca_application, "screenshot_urls"): |
603 | 218 | # ensure to html-quote "," as this is also our seperator | 230 | # ensure to html-quote "," as this is also our seperator |
605 | 219 | s = ",".join([url.replace(",", "%2C") | 231 | s = ",".join([url.replace(",", "%2C") |
606 | 220 | for url in self.sca_application.screenshot_urls]) | 232 | for url in self.sca_application.screenshot_urls]) |
607 | 221 | self.sca_application.screenshot_url = s | 233 | self.sca_application.screenshot_url = s |
608 | 222 | 234 | ||
609 | @@ -227,7 +239,8 @@ | |||
610 | 227 | 239 | ||
611 | 228 | def get_desktop_categories(self): | 240 | def get_desktop_categories(self): |
612 | 229 | try: | 241 | try: |
614 | 230 | return ['DEPARTMENT:' + self.sca_application.department[-1]] + self._get_desktop_list("Categories") | 242 | return (['DEPARTMENT:' + self.sca_application.department[-1]] + |
615 | 243 | self._get_desktop_list("Categories")) | ||
616 | 231 | except: | 244 | except: |
617 | 232 | return self._get_desktop_list("Categories") | 245 | return self._get_desktop_list("Categories") |
618 | 233 | 246 | ||
619 | @@ -251,17 +264,17 @@ | |||
620 | 251 | PistonResponseObject.from_dict(sca_subscription.application)) | 264 | PistonResponseObject.from_dict(sca_subscription.application)) |
621 | 252 | 265 | ||
622 | 253 | SUBSCRIPTION_MAPPING = { | 266 | SUBSCRIPTION_MAPPING = { |
624 | 254 | # this key can be used to get the original deb_line that the | 267 | # this key can be used to get the original deb_line that the |
625 | 255 | # server returns, it will be at the distroseries that was current | 268 | # server returns, it will be at the distroseries that was current |
626 | 256 | # at purchase time | 269 | # at purchase time |
628 | 257 | 'Deb-Line-Orig' : 'deb_line', | 270 | 'Deb-Line-Orig': 'deb_line', |
629 | 258 | # this is what s-c will always use, the deb_line updated to the | 271 | # this is what s-c will always use, the deb_line updated to the |
630 | 259 | # current distroseries, note that you should ensure that the app | 272 | # current distroseries, note that you should ensure that the app |
631 | 260 | # is not in state: PkgStates.PURCHASED_BUT_NOT_AVAILABLE_FOR_SERIES | 273 | # is not in state: PkgStates.PURCHASED_BUT_NOT_AVAILABLE_FOR_SERIES |
636 | 261 | 'Deb-Line' : 'deb_line', | 274 | 'Deb-Line': 'deb_line', |
637 | 262 | 'Purchased-Date' : 'purchase_date', | 275 | 'Purchased-Date': 'purchase_date', |
638 | 263 | 'License-Key' : 'license_key', | 276 | 'License-Key': 'license_key', |
639 | 264 | 'License-Key-Path' : 'license_key_path', | 277 | 'License-Key-Path': 'license_key_path', |
640 | 265 | } | 278 | } |
641 | 266 | 279 | ||
642 | 267 | MAPPING = dict( | 280 | MAPPING = dict( |
643 | @@ -313,47 +326,52 @@ | |||
644 | 313 | 326 | ||
645 | 314 | class JsonTagSectionParser(AppInfoParserBase): | 327 | class JsonTagSectionParser(AppInfoParserBase): |
646 | 315 | 328 | ||
652 | 316 | MAPPING = { 'Name' : 'application_name', | 329 | MAPPING = {'Name': 'application_name', |
653 | 317 | 'Comment' : 'description', | 330 | 'Comment': 'description', |
654 | 318 | 'Price' : 'price', | 331 | 'Price': 'price', |
655 | 319 | 'Package' : 'package_name', | 332 | 'Package': 'package_name', |
656 | 320 | 'Categories' : 'categories', | 333 | 'Categories': 'categories', |
657 | 321 | } | 334 | } |
658 | 322 | 335 | ||
659 | 323 | def __init__(self, tag_section, url): | 336 | def __init__(self, tag_section, url): |
660 | 324 | self.tag_section = tag_section | 337 | self.tag_section = tag_section |
661 | 325 | self.url = url | 338 | self.url = url |
662 | 339 | |||
663 | 326 | def get_desktop(self, key, translated=True): | 340 | def get_desktop(self, key, translated=True): |
664 | 327 | return self.tag_section[self._apply_mapping(key)] | 341 | return self.tag_section[self._apply_mapping(key)] |
665 | 342 | |||
666 | 328 | def has_option_desktop(self, key): | 343 | def has_option_desktop(self, key): |
667 | 329 | return self._apply_mapping(key) in self.tag_section | 344 | return self._apply_mapping(key) in self.tag_section |
668 | 345 | |||
669 | 330 | @property | 346 | @property |
670 | 331 | def desktopf(self): | 347 | def desktopf(self): |
671 | 332 | return self.url | 348 | return self.url |
672 | 333 | 349 | ||
673 | 350 | |||
674 | 334 | class AppStreamXMLParser(AppInfoParserBase): | 351 | class AppStreamXMLParser(AppInfoParserBase): |
675 | 335 | 352 | ||
683 | 336 | MAPPING = { 'Name' : 'name', | 353 | MAPPING = {'Name': 'name', |
684 | 337 | 'Comment' : 'summary', | 354 | 'Comment': 'summary', |
685 | 338 | 'Package' : 'pkgname', | 355 | 'Package': 'pkgname', |
686 | 339 | 'Categories' : 'appcategories', | 356 | 'Categories': 'appcategories', |
687 | 340 | 'Keywords' : 'keywords', | 357 | 'Keywords': 'keywords', |
688 | 341 | 'MimeType' : 'mimetypes', | 358 | 'MimeType': 'mimetypes', |
689 | 342 | 'Icon' : 'icon', | 359 | 'Icon': 'icon', |
690 | 343 | } | 360 | } |
691 | 344 | 361 | ||
695 | 345 | LISTS = { "appcategories" : "appcategory", | 362 | LISTS = {"appcategories": "appcategory", |
696 | 346 | "keywords" : "keyword", | 363 | "keywords": "keyword", |
697 | 347 | "mimetypes" : "mimetype", | 364 | "mimetypes": "mimetype", |
698 | 348 | } | 365 | } |
699 | 349 | 366 | ||
700 | 350 | # map from requested key to a static data element | 367 | # map from requested key to a static data element |
702 | 351 | STATIC_DATA = { 'Type' : 'Application', | 368 | STATIC_DATA = {'Type': 'Application', |
703 | 352 | } | 369 | } |
704 | 353 | 370 | ||
705 | 354 | def __init__(self, appinfo_xml, xmlfile): | 371 | def __init__(self, appinfo_xml, xmlfile): |
706 | 355 | self.appinfo_xml = appinfo_xml | 372 | self.appinfo_xml = appinfo_xml |
707 | 356 | self.xmlfile = xmlfile | 373 | self.xmlfile = xmlfile |
708 | 374 | |||
709 | 357 | def get_desktop(self, key, translated=True): | 375 | def get_desktop(self, key, translated=True): |
710 | 358 | if key in self.STATIC_DATA: | 376 | if key in self.STATIC_DATA: |
711 | 359 | return self.STATIC_DATA[key] | 377 | return self.STATIC_DATA[key] |
712 | @@ -362,14 +380,18 @@ | |||
713 | 362 | return self._parse_with_lists(key) | 380 | return self._parse_with_lists(key) |
714 | 363 | else: | 381 | else: |
715 | 364 | return self._parse_value(key, translated) | 382 | return self._parse_value(key, translated) |
716 | 383 | |||
717 | 365 | def get_desktop_categories(self): | 384 | def get_desktop_categories(self): |
718 | 366 | return self._get_desktop_list("Categories", split_str=',') | 385 | return self._get_desktop_list("Categories", split_str=',') |
719 | 386 | |||
720 | 367 | def get_desktop_mimetypes(self): | 387 | def get_desktop_mimetypes(self): |
721 | 368 | if not self.has_option_desktop("MimeType"): | 388 | if not self.has_option_desktop("MimeType"): |
722 | 369 | return [] | 389 | return [] |
723 | 370 | return self._get_desktop_list("MimeType", split_str=',') | 390 | return self._get_desktop_list("MimeType", split_str=',') |
724 | 391 | |||
725 | 371 | def _parse_value(self, key, translated): | 392 | def _parse_value(self, key, translated): |
727 | 372 | locale = getdefaultlocale(('LANGUAGE','LANG','LC_CTYPE','LC_ALL'))[0] | 393 | locale = getdefaultlocale(('LANGUAGE', 'LANG', 'LC_CTYPE', |
728 | 394 | 'LC_ALL'))[0] | ||
729 | 373 | for child in self.appinfo_xml.iter(key): | 395 | for child in self.appinfo_xml.iter(key): |
730 | 374 | if translated: | 396 | if translated: |
731 | 375 | if child.get("lang") == locale: | 397 | if child.get("lang") == locale: |
732 | @@ -381,28 +403,31 @@ | |||
733 | 381 | return child.text | 403 | return child.text |
734 | 382 | if translated: | 404 | if translated: |
735 | 383 | return self._parse_value(key, False) | 405 | return self._parse_value(key, False) |
738 | 384 | else: | 406 | |
737 | 385 | return None | ||
739 | 386 | def _parse_with_lists(self, key): | 407 | def _parse_with_lists(self, key): |
741 | 387 | l=[] | 408 | l = [] |
742 | 388 | for listroot in self.appinfo_xml.iter(key): | 409 | for listroot in self.appinfo_xml.iter(key): |
743 | 389 | for child in listroot.iter(self.LISTS[key]): | 410 | for child in listroot.iter(self.LISTS[key]): |
744 | 390 | l.append(child.text) | 411 | l.append(child.text) |
745 | 391 | return ",".join(l) | 412 | return ",".join(l) |
746 | 413 | |||
747 | 392 | def has_option_desktop(self, key): | 414 | def has_option_desktop(self, key): |
748 | 393 | if key in self.STATIC_DATA: | 415 | if key in self.STATIC_DATA: |
749 | 394 | return True | 416 | return True |
750 | 395 | key = self._apply_mapping(key) | 417 | key = self._apply_mapping(key) |
751 | 396 | return not self.appinfo_xml.find(key) is None | 418 | return not self.appinfo_xml.find(key) is None |
752 | 419 | |||
753 | 397 | @property | 420 | @property |
754 | 398 | def desktopf(self): | 421 | def desktopf(self): |
755 | 399 | subelm = self.appinfo_xml.find("id") | 422 | subelm = self.appinfo_xml.find("id") |
756 | 400 | return subelm.text | 423 | return subelm.text |
757 | 401 | 424 | ||
758 | 425 | |||
759 | 402 | class DesktopTagSectionParser(AppInfoParserBase): | 426 | class DesktopTagSectionParser(AppInfoParserBase): |
760 | 403 | def __init__(self, tag_section, tagfile): | 427 | def __init__(self, tag_section, tagfile): |
761 | 404 | self.tag_section = tag_section | 428 | self.tag_section = tag_section |
762 | 405 | self.tagfile = tagfile | 429 | self.tagfile = tagfile |
763 | 430 | |||
764 | 406 | def get_desktop(self, key, translated=True): | 431 | def get_desktop(self, key, translated=True): |
765 | 407 | # strip away bogus prefixes | 432 | # strip away bogus prefixes |
766 | 408 | if key.startswith("X-AppInstall-"): | 433 | if key.startswith("X-AppInstall-"): |
767 | @@ -422,7 +447,8 @@ | |||
768 | 422 | # then try the i18n version of the key (in [de_DE] or | 447 | # then try the i18n version of the key (in [de_DE] or |
769 | 423 | # [de]) but ignore errors and return the untranslated one then | 448 | # [de]) but ignore errors and return the untranslated one then |
770 | 424 | try: | 449 | try: |
772 | 425 | locale = getdefaultlocale(('LANGUAGE','LANG','LC_CTYPE','LC_ALL'))[0] | 450 | locale = getdefaultlocale(('LANGUAGE', 'LANG', 'LC_CTYPE', |
773 | 451 | 'LC_ALL'))[0] | ||
774 | 426 | if locale: | 452 | if locale: |
775 | 427 | if self.has_option_desktop("%s-%s" % (key, locale)): | 453 | if self.has_option_desktop("%s-%s" % (key, locale)): |
776 | 428 | return self.tag_section["%s-%s" % (key, locale)] | 454 | return self.tag_section["%s-%s" % (key, locale)] |
777 | @@ -434,18 +460,22 @@ | |||
778 | 434 | pass | 460 | pass |
779 | 435 | # and then the untranslated field | 461 | # and then the untranslated field |
780 | 436 | return self.tag_section[key] | 462 | return self.tag_section[key] |
781 | 463 | |||
782 | 437 | def has_option_desktop(self, key): | 464 | def has_option_desktop(self, key): |
783 | 438 | # strip away bogus prefixes | 465 | # strip away bogus prefixes |
784 | 439 | if key.startswith("X-AppInstall-"): | 466 | if key.startswith("X-AppInstall-"): |
785 | 440 | key = key[len("X-AppInstall-"):] | 467 | key = key[len("X-AppInstall-"):] |
786 | 441 | return key in self.tag_section | 468 | return key in self.tag_section |
787 | 469 | |||
788 | 442 | @property | 470 | @property |
789 | 443 | def desktopf(self): | 471 | def desktopf(self): |
790 | 444 | return self.tagfile | 472 | return self.tagfile |
791 | 445 | 473 | ||
792 | 474 | |||
793 | 446 | class DesktopConfigParser(RawConfigParser, AppInfoParserBase): | 475 | class DesktopConfigParser(RawConfigParser, AppInfoParserBase): |
794 | 447 | " thin wrapper that is tailored for xdg Desktop files " | 476 | " thin wrapper that is tailored for xdg Desktop files " |
795 | 448 | DE = "Desktop Entry" | 477 | DE = "Desktop Entry" |
796 | 478 | |||
797 | 449 | def get_desktop(self, key, translated=True): | 479 | def get_desktop(self, key, translated=True): |
798 | 450 | " get generic option under 'Desktop Entry'" | 480 | " get generic option under 'Desktop Entry'" |
799 | 451 | # never translate the pkgname | 481 | # never translate the pkgname |
800 | @@ -471,28 +501,34 @@ | |||
801 | 471 | # then try the i18n version of the key (in [de_DE] or | 501 | # then try the i18n version of the key (in [de_DE] or |
802 | 472 | # [de]) but ignore errors and return the untranslated one then | 502 | # [de]) but ignore errors and return the untranslated one then |
803 | 473 | try: | 503 | try: |
805 | 474 | locale = getdefaultlocale(('LANGUAGE','LANG','LC_CTYPE','LC_ALL'))[0] | 504 | locale = getdefaultlocale(('LANGUAGE', 'LANG', 'LC_CTYPE', |
806 | 505 | 'LC_ALL'))[0] | ||
807 | 475 | if locale: | 506 | if locale: |
808 | 476 | if self.has_option_desktop("%s[%s]" % (key, locale)): | 507 | if self.has_option_desktop("%s[%s]" % (key, locale)): |
809 | 477 | return self.get(self.DE, "%s[%s]" % (key, locale)) | 508 | return self.get(self.DE, "%s[%s]" % (key, locale)) |
810 | 478 | if "_" in locale: | 509 | if "_" in locale: |
811 | 479 | locale_short = locale.split("_")[0] | 510 | locale_short = locale.split("_")[0] |
812 | 480 | if self.has_option_desktop("%s[%s]" % (key, locale_short)): | 511 | if self.has_option_desktop("%s[%s]" % (key, locale_short)): |
814 | 481 | return self.get(self.DE, "%s[%s]" % (key, locale_short)) | 512 | return self.get(self.DE, "%s[%s]" % |
815 | 513 | (key, locale_short)) | ||
816 | 482 | except ValueError: | 514 | except ValueError: |
817 | 483 | pass | 515 | pass |
818 | 484 | # and then the untranslated field | 516 | # and then the untranslated field |
819 | 485 | return self.get(self.DE, key) | 517 | return self.get(self.DE, key) |
820 | 518 | |||
821 | 486 | def has_option_desktop(self, key): | 519 | def has_option_desktop(self, key): |
822 | 487 | " test if there is the option under 'Desktop Entry'" | 520 | " test if there is the option under 'Desktop Entry'" |
823 | 488 | return self.has_option(self.DE, key) | 521 | return self.has_option(self.DE, key) |
824 | 522 | |||
825 | 489 | def read(self, filename): | 523 | def read(self, filename): |
826 | 490 | self._filename = filename | 524 | self._filename = filename |
827 | 491 | RawConfigParser.read(self, filename) | 525 | RawConfigParser.read(self, filename) |
828 | 526 | |||
829 | 492 | @property | 527 | @property |
830 | 493 | def desktopf(self): | 528 | def desktopf(self): |
831 | 494 | return self._filename | 529 | return self._filename |
832 | 495 | 530 | ||
833 | 531 | |||
834 | 496 | def ascii_upper(key): | 532 | def ascii_upper(key): |
835 | 497 | """Translate an ASCII string to uppercase | 533 | """Translate an ASCII string to uppercase |
836 | 498 | in a locale-independent manner.""" | 534 | in a locale-independent manner.""" |
837 | @@ -500,13 +536,15 @@ | |||
838 | 500 | string.ascii_uppercase) | 536 | string.ascii_uppercase) |
839 | 501 | return key.translate(ascii_trans_table) | 537 | return key.translate(ascii_trans_table) |
840 | 502 | 538 | ||
841 | 539 | |||
842 | 503 | def index_name(doc, name, term_generator): | 540 | def index_name(doc, name, term_generator): |
843 | 504 | """ index the name of the application """ | 541 | """ index the name of the application """ |
844 | 505 | doc.add_value(XapianValues.APPNAME, name) | 542 | doc.add_value(XapianValues.APPNAME, name) |
846 | 506 | doc.add_term("AA"+name) | 543 | doc.add_term("AA" + name) |
847 | 507 | w = globals()["WEIGHT_DESKTOP_NAME"] | 544 | w = globals()["WEIGHT_DESKTOP_NAME"] |
848 | 508 | term_generator.index_text_without_positions(name, w) | 545 | term_generator.index_text_without_positions(name, w) |
849 | 509 | 546 | ||
850 | 547 | |||
851 | 510 | def update(db, cache, datadir=None): | 548 | def update(db, cache, datadir=None): |
852 | 511 | if not datadir: | 549 | if not datadir: |
853 | 512 | datadir = softwarecenter.paths.APP_INSTALL_DESKTOP_PATH | 550 | datadir = softwarecenter.paths.APP_INSTALL_DESKTOP_PATH |
854 | @@ -514,7 +552,9 @@ | |||
855 | 514 | update_from_var_lib_apt_lists(db, cache) | 552 | update_from_var_lib_apt_lists(db, cache) |
856 | 515 | # add db global meta-data | 553 | # add db global meta-data |
857 | 516 | LOG.debug("adding popcon_max_desktop '%s'" % popcon_max) | 554 | LOG.debug("adding popcon_max_desktop '%s'" % popcon_max) |
859 | 517 | db.set_metadata("popcon_max_desktop", xapian.sortable_serialise(float(popcon_max))) | 555 | db.set_metadata("popcon_max_desktop", |
860 | 556 | xapian.sortable_serialise(float(popcon_max))) | ||
861 | 557 | |||
862 | 518 | 558 | ||
863 | 519 | def update_from_json_string(db, cache, json_string, origin): | 559 | def update_from_json_string(db, cache, json_string, origin): |
864 | 520 | """ index from a json string, should include origin url (free form string) | 560 | """ index from a json string, should include origin url (free form string) |
865 | @@ -524,6 +564,7 @@ | |||
866 | 524 | index_app_info_from_parser(parser, db, cache) | 564 | index_app_info_from_parser(parser, db, cache) |
867 | 525 | return True | 565 | return True |
868 | 526 | 566 | ||
869 | 567 | |||
870 | 527 | def update_from_var_lib_apt_lists(db, cache, listsdir=None): | 568 | def update_from_var_lib_apt_lists(db, cache, listsdir=None): |
871 | 528 | """ index the files in /var/lib/apt/lists/*AppInfo """ | 569 | """ index the files in /var/lib/apt/lists/*AppInfo """ |
872 | 529 | try: | 570 | try: |
873 | @@ -544,18 +585,21 @@ | |||
874 | 544 | index_app_info_from_parser(parser, db, cache) | 585 | index_app_info_from_parser(parser, db, cache) |
875 | 545 | return True | 586 | return True |
876 | 546 | 587 | ||
877 | 588 | |||
878 | 547 | def update_from_single_appstream_file(db, cache, filename): | 589 | def update_from_single_appstream_file(db, cache, filename): |
879 | 548 | from lxml import etree | 590 | from lxml import etree |
880 | 549 | 591 | ||
881 | 550 | tree = etree.parse(open(filename)) | 592 | tree = etree.parse(open(filename)) |
882 | 551 | root = tree.getroot() | 593 | root = tree.getroot() |
883 | 552 | if not root.tag == "applications": | 594 | if not root.tag == "applications": |
885 | 553 | LOG.error("failed to read '%s' expected Applications root tag" % filename) | 595 | LOG.error("failed to read '%s' expected Applications root tag" % |
886 | 596 | filename) | ||
887 | 554 | return | 597 | return |
888 | 555 | for appinfo in root.iter("application"): | 598 | for appinfo in root.iter("application"): |
889 | 556 | parser = AppStreamXMLParser(appinfo, filename) | 599 | parser = AppStreamXMLParser(appinfo, filename) |
890 | 557 | index_app_info_from_parser(parser, db, cache) | 600 | index_app_info_from_parser(parser, db, cache) |
891 | 558 | 601 | ||
892 | 602 | |||
893 | 559 | def update_from_appstream_xml(db, cache, xmldir=None): | 603 | def update_from_appstream_xml(db, cache, xmldir=None): |
894 | 560 | if not xmldir: | 604 | if not xmldir: |
895 | 561 | xmldir = softwarecenter.paths.APPSTREAM_XML_PATH | 605 | xmldir = softwarecenter.paths.APPSTREAM_XML_PATH |
896 | @@ -573,12 +617,13 @@ | |||
897 | 573 | update_from_single_appstream_file(db, cache, appstream_xml) | 617 | update_from_single_appstream_file(db, cache, appstream_xml) |
898 | 574 | return True | 618 | return True |
899 | 575 | 619 | ||
900 | 620 | |||
901 | 576 | def update_from_app_install_data(db, cache, datadir=None): | 621 | def update_from_app_install_data(db, cache, datadir=None): |
902 | 577 | """ index the desktop files in $datadir/desktop/*.desktop """ | 622 | """ index the desktop files in $datadir/desktop/*.desktop """ |
903 | 578 | if not datadir: | 623 | if not datadir: |
904 | 579 | datadir = softwarecenter.paths.APP_INSTALL_DESKTOP_PATH | 624 | datadir = softwarecenter.paths.APP_INSTALL_DESKTOP_PATH |
905 | 580 | context = GObject.main_context_default() | 625 | context = GObject.main_context_default() |
907 | 581 | for desktopf in glob(datadir+"/*.desktop"): | 626 | for desktopf in glob(datadir + "/*.desktop"): |
908 | 582 | LOG.debug("processing %s" % desktopf) | 627 | LOG.debug("processing %s" % desktopf) |
909 | 583 | # process events | 628 | # process events |
910 | 584 | while context.pending(): | 629 | while context.pending(): |
911 | @@ -599,7 +644,9 @@ | |||
912 | 599 | LOG.warning(warning_text) | 644 | LOG.warning(warning_text) |
913 | 600 | return True | 645 | return True |
914 | 601 | 646 | ||
916 | 602 | def add_from_purchased_but_needs_reinstall_data(purchased_but_may_need_reinstall_list, db, cache): | 647 | |
917 | 648 | def add_from_purchased_but_needs_reinstall_data( | ||
918 | 649 | purchased_but_may_need_reinstall_list, db, cache): | ||
919 | 603 | """Add application that have been purchased but may require a reinstall | 650 | """Add application that have been purchased but may require a reinstall |
920 | 604 | 651 | ||
921 | 605 | This adds a inmemory database to the main db with the special | 652 | This adds a inmemory database to the main db with the special |
922 | @@ -632,9 +679,10 @@ | |||
923 | 632 | # add new in memory db to the main db | 679 | # add new in memory db to the main db |
924 | 633 | db.add_database(db_purchased) | 680 | db.add_database(db_purchased) |
925 | 634 | # return a query | 681 | # return a query |
927 | 635 | query = xapian.Query("AH"+PURCHASED_NEEDS_REINSTALL_MAGIC_CHANNEL_NAME) | 682 | query = xapian.Query("AH" + PURCHASED_NEEDS_REINSTALL_MAGIC_CHANNEL_NAME) |
928 | 636 | return query | 683 | return query |
929 | 637 | 684 | ||
930 | 685 | |||
931 | 638 | def update_from_software_center_agent(db, cache, ignore_cache=False, | 686 | def update_from_software_center_agent(db, cache, ignore_cache=False, |
932 | 639 | include_sca_qa=False): | 687 | include_sca_qa=False): |
933 | 640 | """ update index based on the software-center-agent data """ | 688 | """ update index based on the software-center-agent data """ |
934 | @@ -644,6 +692,7 @@ | |||
935 | 644 | sca.available = available | 692 | sca.available = available |
936 | 645 | sca.good_data = True | 693 | sca.good_data = True |
937 | 646 | loop.quit() | 694 | loop.quit() |
938 | 695 | |||
939 | 647 | def _error_cb(sca, error): | 696 | def _error_cb(sca, error): |
940 | 648 | LOG.warn("error: %s" % error) | 697 | LOG.warn("error: %s" % error) |
941 | 649 | sca.available = [] | 698 | sca.available = [] |
942 | @@ -690,10 +739,12 @@ | |||
943 | 690 | # app name is the data | 739 | # app name is the data |
944 | 691 | if parser.has_option_desktop("X-Ubuntu-Software-Center-Name"): | 740 | if parser.has_option_desktop("X-Ubuntu-Software-Center-Name"): |
945 | 692 | name = parser.get_desktop("X-Ubuntu-Software-Center-Name") | 741 | name = parser.get_desktop("X-Ubuntu-Software-Center-Name") |
947 | 693 | untranslated_name = parser.get_desktop("X-Ubuntu-Software-Center-Name", translated=False) | 742 | untranslated_name = parser.get_desktop("X-Ubuntu-Software-Center-Name", |
948 | 743 | translated=False) | ||
949 | 694 | elif parser.has_option_desktop("X-GNOME-FullName"): | 744 | elif parser.has_option_desktop("X-GNOME-FullName"): |
950 | 695 | name = parser.get_desktop("X-GNOME-FullName") | 745 | name = parser.get_desktop("X-GNOME-FullName") |
952 | 696 | untranslated_name = parser.get_desktop("X-GNOME-FullName", translated=False) | 746 | untranslated_name = parser.get_desktop("X-GNOME-FullName", |
953 | 747 | translated=False) | ||
954 | 697 | else: | 748 | else: |
955 | 698 | name = parser.get_desktop("Name") | 749 | name = parser.get_desktop("Name") |
956 | 699 | untranslated_name = parser.get_desktop("Name", translated=False) | 750 | untranslated_name = parser.get_desktop("Name", translated=False) |
957 | @@ -713,16 +764,18 @@ | |||
958 | 713 | arches = parser.get_desktop("X-AppInstall-Architectures") | 764 | arches = parser.get_desktop("X-AppInstall-Architectures") |
959 | 714 | doc.add_value(XapianValues.ARCHIVE_ARCH, arches) | 765 | doc.add_value(XapianValues.ARCHIVE_ARCH, arches) |
960 | 715 | native_archs = get_current_arch() in arches.split(',') | 766 | native_archs = get_current_arch() in arches.split(',') |
963 | 716 | foreign_archs = list(set(arches.split(',')) & set(get_foreign_architectures())) | 767 | foreign_archs = list(set(arches.split(',')) & |
964 | 717 | if not (native_archs or foreign_archs): return | 768 | set(get_foreign_architectures())) |
965 | 769 | if not (native_archs or foreign_archs): | ||
966 | 770 | return | ||
967 | 718 | if not native_archs and foreign_archs: | 771 | if not native_archs and foreign_archs: |
968 | 719 | pkgname_extension = ':' + foreign_archs[0] | 772 | pkgname_extension = ':' + foreign_archs[0] |
969 | 720 | # package name | 773 | # package name |
970 | 721 | pkgname = parser.get_desktop("X-AppInstall-Package") + pkgname_extension | 774 | pkgname = parser.get_desktop("X-AppInstall-Package") + pkgname_extension |
972 | 722 | doc.add_term("AP"+pkgname) | 775 | doc.add_term("AP" + pkgname) |
973 | 723 | if '-' in pkgname: | 776 | if '-' in pkgname: |
974 | 724 | # we need this to work around xapian oddness | 777 | # we need this to work around xapian oddness |
976 | 725 | doc.add_term(pkgname.replace('-','_')) | 778 | doc.add_term(pkgname.replace('-', '_')) |
977 | 726 | doc.add_value(XapianValues.PKGNAME, pkgname) | 779 | doc.add_value(XapianValues.PKGNAME, pkgname) |
978 | 727 | doc.add_value(XapianValues.DESKTOP_FILE, parser.desktopf) | 780 | doc.add_value(XapianValues.DESKTOP_FILE, parser.desktopf) |
979 | 728 | # display name | 781 | # display name |
980 | @@ -731,21 +784,21 @@ | |||
981 | 731 | # cataloged_times | 784 | # cataloged_times |
982 | 732 | if "catalogedtime" in axi_values: | 785 | if "catalogedtime" in axi_values: |
983 | 733 | if pkgname in cataloged_times: | 786 | if pkgname in cataloged_times: |
985 | 734 | doc.add_value(axi_values["catalogedtime"], | 787 | doc.add_value(axi_values["catalogedtime"], |
986 | 735 | xapian.sortable_serialise(cataloged_times[pkgname])) | 788 | xapian.sortable_serialise(cataloged_times[pkgname])) |
987 | 736 | # pocket (main, restricted, ...) | 789 | # pocket (main, restricted, ...) |
988 | 737 | if parser.has_option_desktop("X-AppInstall-Section"): | 790 | if parser.has_option_desktop("X-AppInstall-Section"): |
989 | 738 | archive_section = parser.get_desktop("X-AppInstall-Section") | 791 | archive_section = parser.get_desktop("X-AppInstall-Section") |
991 | 739 | doc.add_term("AS"+archive_section) | 792 | doc.add_term("AS" + archive_section) |
992 | 740 | doc.add_value(XapianValues.ARCHIVE_SECTION, archive_section) | 793 | doc.add_value(XapianValues.ARCHIVE_SECTION, archive_section) |
993 | 741 | # section (mail, base, ..) | 794 | # section (mail, base, ..) |
994 | 742 | if pkgname in cache and cache[pkgname].candidate: | 795 | if pkgname in cache and cache[pkgname].candidate: |
995 | 743 | section = cache[pkgname].section | 796 | section = cache[pkgname].section |
997 | 744 | doc.add_term("AE"+section) | 797 | doc.add_term("AE" + section) |
998 | 745 | # channel (third party stuff) | 798 | # channel (third party stuff) |
999 | 746 | if parser.has_option_desktop("X-AppInstall-Channel"): | 799 | if parser.has_option_desktop("X-AppInstall-Channel"): |
1000 | 747 | archive_channel = parser.get_desktop("X-AppInstall-Channel") | 800 | archive_channel = parser.get_desktop("X-AppInstall-Channel") |
1002 | 748 | doc.add_term("AH"+archive_channel) | 801 | doc.add_term("AH" + archive_channel) |
1003 | 749 | doc.add_value(XapianValues.ARCHIVE_CHANNEL, archive_channel) | 802 | doc.add_value(XapianValues.ARCHIVE_CHANNEL, archive_channel) |
1004 | 750 | # signing key (third party) | 803 | # signing key (third party) |
1005 | 751 | if parser.has_option_desktop("X-AppInstall-Signing-Key-Id"): | 804 | if parser.has_option_desktop("X-AppInstall-Signing-Key-Id"): |
1006 | @@ -758,7 +811,7 @@ | |||
1007 | 758 | # date published | 811 | # date published |
1008 | 759 | if parser.has_option_desktop("X-AppInstall-Date-Published"): | 812 | if parser.has_option_desktop("X-AppInstall-Date-Published"): |
1009 | 760 | date_published = parser.get_desktop("X-AppInstall-Date-Published") | 813 | date_published = parser.get_desktop("X-AppInstall-Date-Published") |
1011 | 761 | if (date_published and | 814 | if (date_published and |
1012 | 762 | re.match("\d+-\d+-\d+ \d+:\d+:\d+", date_published)): | 815 | re.match("\d+-\d+-\d+ \d+:\d+:\d+", date_published)): |
1013 | 763 | # strip the subseconds from the end of the published date string | 816 | # strip the subseconds from the end of the published date string |
1014 | 764 | date_published = str(date_published).split(".")[0] | 817 | date_published = str(date_published).split(".")[0] |
1015 | @@ -772,7 +825,7 @@ | |||
1016 | 772 | date_published_sec = time.mktime( | 825 | date_published_sec = time.mktime( |
1017 | 773 | time.strptime(date_published, | 826 | time.strptime(date_published, |
1018 | 774 | "%Y-%m-%d %H:%M:%S")) | 827 | "%Y-%m-%d %H:%M:%S")) |
1020 | 775 | doc.add_value(axi_values["catalogedtime"], | 828 | doc.add_value(axi_values["catalogedtime"], |
1021 | 776 | xapian.sortable_serialise(date_published_sec)) | 829 | xapian.sortable_serialise(date_published_sec)) |
1022 | 777 | # purchased date | 830 | # purchased date |
1023 | 778 | if parser.has_option_desktop("X-AppInstall-Purchased-Date"): | 831 | if parser.has_option_desktop("X-AppInstall-Purchased-Date"): |
1024 | @@ -798,7 +851,7 @@ | |||
1025 | 798 | doc.add_value(XapianValues.ARCHIVE_PPA, archive_ppa) | 851 | doc.add_value(XapianValues.ARCHIVE_PPA, archive_ppa) |
1026 | 799 | # add archive origin data here so that its available even if | 852 | # add archive origin data here so that its available even if |
1027 | 800 | # the PPA is not (yet) enabled | 853 | # the PPA is not (yet) enabled |
1029 | 801 | doc.add_term("XOO"+"lp-ppa-%s" % archive_ppa.replace("/", "-")) | 854 | doc.add_term("XOO" + "lp-ppa-%s" % archive_ppa.replace("/", "-")) |
1030 | 802 | # screenshot (for third party) | 855 | # screenshot (for third party) |
1031 | 803 | if parser.has_option_desktop("X-AppInstall-Screenshot-Url"): | 856 | if parser.has_option_desktop("X-AppInstall-Screenshot-Url"): |
1032 | 804 | url = parser.get_desktop("X-AppInstall-Screenshot-Url") | 857 | url = parser.get_desktop("X-AppInstall-Screenshot-Url") |
1033 | @@ -836,15 +889,15 @@ | |||
1034 | 836 | doc.add_value(XapianValues.ICON, icon) | 889 | doc.add_value(XapianValues.ICON, icon) |
1035 | 837 | # write out categories | 890 | # write out categories |
1036 | 838 | for cat in parser.get_desktop_categories(): | 891 | for cat in parser.get_desktop_categories(): |
1038 | 839 | doc.add_term("AC"+cat.lower()) | 892 | doc.add_term("AC" + cat.lower()) |
1039 | 840 | categories_string = ";".join(parser.get_desktop_categories()) | 893 | categories_string = ";".join(parser.get_desktop_categories()) |
1040 | 841 | doc.add_value(XapianValues.CATEGORIES, categories_string) | 894 | doc.add_value(XapianValues.CATEGORIES, categories_string) |
1041 | 842 | for mime in parser.get_desktop_mimetypes(): | 895 | for mime in parser.get_desktop_mimetypes(): |
1043 | 843 | doc.add_term("AM"+mime.lower()) | 896 | doc.add_term("AM" + mime.lower()) |
1044 | 844 | # get type (to distinguish between apps and packages | 897 | # get type (to distinguish between apps and packages |
1045 | 845 | if parser.has_option_desktop("Type"): | 898 | if parser.has_option_desktop("Type"): |
1046 | 846 | type = parser.get_desktop("Type") | 899 | type = parser.get_desktop("Type") |
1048 | 847 | doc.add_term("AT"+type.lower()) | 900 | doc.add_term("AT" + type.lower()) |
1049 | 848 | # check gettext domain | 901 | # check gettext domain |
1050 | 849 | if parser.has_option_desktop("X-Ubuntu-Gettext-Domain"): | 902 | if parser.has_option_desktop("X-Ubuntu-Gettext-Domain"): |
1051 | 850 | domain = parser.get_desktop("X-Ubuntu-Gettext-Domain") | 903 | domain = parser.get_desktop("X-Ubuntu-Gettext-Domain") |
1052 | @@ -867,14 +920,14 @@ | |||
1053 | 867 | tags = parser.get_desktop("X-AppInstall-Tags") | 920 | tags = parser.get_desktop("X-AppInstall-Tags") |
1054 | 868 | if tags: | 921 | if tags: |
1055 | 869 | for tag in tags.split(","): | 922 | for tag in tags.split(","): |
1057 | 870 | doc.add_term("XT"+tag.strip()) | 923 | doc.add_term("XT" + tag.strip()) |
1058 | 871 | # ENFORCE region blacklist by not registering the app at all | 924 | # ENFORCE region blacklist by not registering the app at all |
1059 | 872 | region = get_region_cached() | 925 | region = get_region_cached() |
1060 | 873 | if region: | 926 | if region: |
1061 | 874 | countrycode = region["countrycode"].lower() | 927 | countrycode = region["countrycode"].lower() |
1062 | 875 | if "%s%s" % (REGION_BLACKLIST_TAG, countrycode) in tags: | 928 | if "%s%s" % (REGION_BLACKLIST_TAG, countrycode) in tags: |
1063 | 876 | LOG.info("skipping region restricted app: '%s'" % name) | 929 | LOG.info("skipping region restricted app: '%s'" % name) |
1065 | 877 | return None | 930 | return |
1066 | 878 | 931 | ||
1067 | 879 | # popcon | 932 | # popcon |
1068 | 880 | # FIXME: popularity not only based on popcon but also | 933 | # FIXME: popularity not only based on popcon but also |
1069 | @@ -882,7 +935,7 @@ | |||
1070 | 882 | if parser.has_option_desktop("X-AppInstall-Popcon"): | 935 | if parser.has_option_desktop("X-AppInstall-Popcon"): |
1071 | 883 | popcon = float(parser.get_desktop("X-AppInstall-Popcon")) | 936 | popcon = float(parser.get_desktop("X-AppInstall-Popcon")) |
1072 | 884 | # sort_by_value uses string compare, so we need to pad here | 937 | # sort_by_value uses string compare, so we need to pad here |
1074 | 885 | doc.add_value(XapianValues.POPCON, | 938 | doc.add_value(XapianValues.POPCON, |
1075 | 886 | xapian.sortable_serialise(popcon)) | 939 | xapian.sortable_serialise(popcon)) |
1076 | 887 | global popcon_max | 940 | global popcon_max |
1077 | 888 | popcon_max = max(popcon_max, popcon) | 941 | popcon_max = max(popcon_max, popcon) |
1078 | @@ -922,7 +975,7 @@ | |||
1079 | 922 | doc = make_doc_from_parser(parser, cache) | 975 | doc = make_doc_from_parser(parser, cache) |
1080 | 923 | if not doc: | 976 | if not doc: |
1081 | 924 | LOG.debug("make_doc_from_parser() returned '%s', ignoring" % doc) | 977 | LOG.debug("make_doc_from_parser() returned '%s', ignoring" % doc) |
1083 | 925 | return | 978 | return |
1084 | 926 | term_generator.set_document(doc) | 979 | term_generator.set_document(doc) |
1085 | 927 | name = doc.get_data() | 980 | name = doc.get_data() |
1086 | 928 | 981 | ||
1087 | @@ -935,10 +988,11 @@ | |||
1088 | 935 | 988 | ||
1089 | 936 | pkgname = doc.get_value(XapianValues.PKGNAME) | 989 | pkgname = doc.get_value(XapianValues.PKGNAME) |
1090 | 937 | # add packagename as meta-data too | 990 | # add packagename as meta-data too |
1092 | 938 | term_generator.index_text_without_positions(pkgname, WEIGHT_APT_PKGNAME) | 991 | term_generator.index_text_without_positions(pkgname, |
1093 | 992 | WEIGHT_APT_PKGNAME) | ||
1094 | 939 | 993 | ||
1095 | 940 | # now add search data from the desktop file | 994 | # now add search data from the desktop file |
1097 | 941 | for key in ["GenericName","Comment", "X-AppInstall-Description"]: | 995 | for key in ["GenericName", "Comment", "X-AppInstall-Description"]: |
1098 | 942 | if not parser.has_option_desktop(key): | 996 | if not parser.has_option_desktop(key): |
1099 | 943 | continue | 997 | continue |
1100 | 944 | s = parser.get_desktop(key) | 998 | s = parser.get_desktop(key) |
1101 | @@ -954,15 +1008,17 @@ | |||
1102 | 954 | # add data from the apt cache | 1008 | # add data from the apt cache |
1103 | 955 | if pkgname in cache and cache[pkgname].candidate: | 1009 | if pkgname in cache and cache[pkgname].candidate: |
1104 | 956 | s = cache[pkgname].candidate.summary | 1010 | s = cache[pkgname].candidate.summary |
1106 | 957 | term_generator.index_text_without_positions(s, WEIGHT_APT_SUMMARY) | 1011 | term_generator.index_text_without_positions(s, |
1107 | 1012 | WEIGHT_APT_SUMMARY) | ||
1108 | 958 | s = cache[pkgname].candidate.description | 1013 | s = cache[pkgname].candidate.description |
1110 | 959 | term_generator.index_text_without_positions(s, WEIGHT_APT_DESCRIPTION) | 1014 | term_generator.index_text_without_positions(s, |
1111 | 1015 | WEIGHT_APT_DESCRIPTION) | ||
1112 | 960 | for origin in cache[pkgname].candidate.origins: | 1016 | for origin in cache[pkgname].candidate.origins: |
1118 | 961 | doc.add_term("XOA"+origin.archive) | 1017 | doc.add_term("XOA" + origin.archive) |
1119 | 962 | doc.add_term("XOC"+origin.component) | 1018 | doc.add_term("XOC" + origin.component) |
1120 | 963 | doc.add_term("XOL"+origin.label) | 1019 | doc.add_term("XOL" + origin.label) |
1121 | 964 | doc.add_term("XOO"+origin.origin) | 1020 | doc.add_term("XOO" + origin.origin) |
1122 | 965 | doc.add_term("XOS"+origin.site) | 1021 | doc.add_term("XOS" + origin.site) |
1123 | 966 | 1022 | ||
1124 | 967 | # add our keywords (with high priority) | 1023 | # add our keywords (with high priority) |
1125 | 968 | keywords = None | 1024 | keywords = None |
1126 | @@ -973,16 +1029,18 @@ | |||
1127 | 973 | if keywords: | 1029 | if keywords: |
1128 | 974 | for s in keywords.split(";"): | 1030 | for s in keywords.split(";"): |
1129 | 975 | if s: | 1031 | if s: |
1131 | 976 | term_generator.index_text_without_positions(s, WEIGHT_DESKTOP_KEYWORD) | 1032 | term_generator.index_text_without_positions(s, |
1132 | 1033 | WEIGHT_DESKTOP_KEYWORD) | ||
1133 | 977 | # now add it | 1034 | # now add it |
1134 | 978 | db.add_document(doc) | 1035 | db.add_document(doc) |
1135 | 979 | 1036 | ||
1136 | 1037 | |||
1137 | 980 | def rebuild_database(pathname, debian_sources=True, appstream_sources=False): | 1038 | def rebuild_database(pathname, debian_sources=True, appstream_sources=False): |
1138 | 981 | #cache = apt.Cache(memonly=True) | 1039 | #cache = apt.Cache(memonly=True) |
1139 | 982 | cache = get_pkg_info() | 1040 | cache = get_pkg_info() |
1140 | 983 | cache.open() | 1041 | cache.open() |
1143 | 984 | old_path = pathname+"_old" | 1042 | old_path = pathname + "_old" |
1144 | 985 | rebuild_path = pathname+"_rb" | 1043 | rebuild_path = pathname + "_rb" |
1145 | 986 | 1044 | ||
1146 | 987 | if not os.path.exists(rebuild_path): | 1045 | if not os.path.exists(rebuild_path): |
1147 | 988 | try: | 1046 | try: |
1148 | @@ -1000,7 +1058,8 @@ | |||
1149 | 1000 | 1058 | ||
1150 | 1001 | #check if old unrequired version of db still exists on filesystem | 1059 | #check if old unrequired version of db still exists on filesystem |
1151 | 1002 | if os.path.exists(old_path): | 1060 | if os.path.exists(old_path): |
1153 | 1003 | LOG.warn("Existing xapian old db was not previously cleaned: '%s'." % old_path) | 1061 | LOG.warn("Existing xapian old db was not previously cleaned: '%s'." % |
1154 | 1062 | old_path) | ||
1155 | 1004 | if os.access(old_path, os.W_OK): | 1063 | if os.access(old_path, os.W_OK): |
1156 | 1005 | #remove old unrequired db before beginning | 1064 | #remove old unrequired db before beginning |
1157 | 1006 | shutil.rmtree(old_path) | 1065 | shutil.rmtree(old_path) |
1158 | @@ -1009,7 +1068,6 @@ | |||
1159 | 1009 | LOG.warn("Please check you have the relevant permissions.") | 1068 | LOG.warn("Please check you have the relevant permissions.") |
1160 | 1010 | return False | 1069 | return False |
1161 | 1011 | 1070 | ||
1162 | 1012 | |||
1163 | 1013 | # write it | 1071 | # write it |
1164 | 1014 | db = xapian.WritableDatabase(rebuild_path, xapian.DB_CREATE_OR_OVERWRITE) | 1072 | db = xapian.WritableDatabase(rebuild_path, xapian.DB_CREATE_OR_OVERWRITE) |
1165 | 1015 | 1073 | ||
1166 | @@ -1017,7 +1075,8 @@ | |||
1167 | 1017 | update(db, cache) | 1075 | update(db, cache) |
1168 | 1018 | if appstream_sources: | 1076 | if appstream_sources: |
1169 | 1019 | if os.path.exists('./data/app-stream/appdata.xml'): | 1077 | if os.path.exists('./data/app-stream/appdata.xml'): |
1171 | 1020 | update_from_appstream_xml(db, cache, './data/app-stream/appdata.xml'); | 1078 | update_from_appstream_xml(db, cache, |
1172 | 1079 | './data/app-stream/appdata.xml') | ||
1173 | 1021 | else: | 1080 | else: |
1174 | 1022 | update_from_appstream_xml(db, cache) | 1081 | update_from_appstream_xml(db, cache) |
1175 | 1023 | 1082 | ||
1176 | @@ -1038,5 +1097,6 @@ | |||
1177 | 1038 | shutil.rmtree(old_path) | 1097 | shutil.rmtree(old_path) |
1178 | 1039 | return True | 1098 | return True |
1179 | 1040 | except: | 1099 | except: |
1181 | 1041 | LOG.warn("Cannot copy refreshed database to correct location: '%s'." % pathname) | 1100 | LOG.warn("Cannot copy refreshed database to correct location: '%s'." % |
1182 | 1101 | pathname) | ||
1183 | 1042 | return False | 1102 | return False |
1184 | 1043 | 1103 | ||
1185 | === modified file 'softwarecenter/db/utils.py' | |||
1186 | --- softwarecenter/db/utils.py 2012-02-17 14:23:58 +0000 | |||
1187 | +++ softwarecenter/db/utils.py 2012-03-15 04:06:19 +0000 | |||
1188 | @@ -18,18 +18,20 @@ | |||
1189 | 18 | 18 | ||
1190 | 19 | import xapian | 19 | import xapian |
1191 | 20 | 20 | ||
1192 | 21 | |||
1193 | 21 | def get_query_for_pkgnames(pkgnames): | 22 | def get_query_for_pkgnames(pkgnames): |
1194 | 22 | """ return a xapian query that matches exactly the list of pkgnames """ | 23 | """ return a xapian query that matches exactly the list of pkgnames """ |
1195 | 23 | query = xapian.Query() | 24 | query = xapian.Query() |
1196 | 24 | for pkgname in pkgnames: | 25 | for pkgname in pkgnames: |
1197 | 25 | query = xapian.Query(xapian.Query.OP_OR, | 26 | query = xapian.Query(xapian.Query.OP_OR, |
1198 | 26 | query, | 27 | query, |
1200 | 27 | xapian.Query("XP"+pkgname)) | 28 | xapian.Query("XP" + pkgname)) |
1201 | 28 | query = xapian.Query(xapian.Query.OP_OR, | 29 | query = xapian.Query(xapian.Query.OP_OR, |
1202 | 29 | query, | 30 | query, |
1204 | 30 | xapian.Query("AP"+pkgname)) | 31 | xapian.Query("AP" + pkgname)) |
1205 | 31 | return query | 32 | return query |
1207 | 32 | 33 | ||
1208 | 34 | |||
1209 | 33 | def get_installed_apps_list(db): | 35 | def get_installed_apps_list(db): |
1210 | 34 | """ return a list of installed applications """ | 36 | """ return a list of installed applications """ |
1211 | 35 | apps = set() | 37 | apps = set() |
1212 | @@ -41,11 +43,12 @@ | |||
1213 | 41 | apps.add(db.get_application(doc)) | 43 | apps.add(db.get_application(doc)) |
1214 | 42 | return apps | 44 | return apps |
1215 | 43 | 45 | ||
1216 | 46 | |||
1217 | 44 | def get_installed_package_list(): | 47 | def get_installed_package_list(): |
1218 | 45 | """ return a set of all of the currently installed packages """ | 48 | """ return a set of all of the currently installed packages """ |
1219 | 46 | from softwarecenter.db.pkginfo import get_pkg_info | 49 | from softwarecenter.db.pkginfo import get_pkg_info |
1220 | 47 | installed_pkgs = set() | 50 | installed_pkgs = set() |
1222 | 48 | cache=get_pkg_info() | 51 | cache = get_pkg_info() |
1223 | 49 | for pkg in cache: | 52 | for pkg in cache: |
1224 | 50 | if pkg.is_installed: | 53 | if pkg.is_installed: |
1225 | 51 | installed_pkgs.add(pkg.name) | 54 | installed_pkgs.add(pkg.name) |
1226 | 52 | 55 | ||
1227 | === modified file 'test/test_pep8.py' | |||
1228 | --- test/test_pep8.py 2012-03-15 04:06:19 +0000 | |||
1229 | +++ test/test_pep8.py 2012-03-15 04:06:19 +0000 | |||
1230 | @@ -7,16 +7,15 @@ | |||
1231 | 7 | setup_test_env() | 7 | setup_test_env() |
1232 | 8 | 8 | ||
1233 | 9 | # Only test these two packages for now: | 9 | # Only test these two packages for now: |
1237 | 10 | import softwarecenter.db.pkginfo_impl | 10 | import softwarecenter.db |
1238 | 11 | import softwarecenter.ui.gtk3 | 11 | import softwarecenter.ui |
1236 | 12 | import softwarecenter.ui.qml | ||
1239 | 13 | 12 | ||
1240 | 14 | class PackagePep8TestCase(unittest.TestCase): | 13 | class PackagePep8TestCase(unittest.TestCase): |
1241 | 15 | maxDiff = None | 14 | maxDiff = None |
1246 | 16 | packages = [softwarecenter.ui.qml, | 15 | packages = [softwarecenter.ui, |
1247 | 17 | softwarecenter.ui.gtk3, | 16 | softwarecenter.db] |
1248 | 18 | softwarecenter.db.pkginfo_impl] | 17 | exclude = ['history.py', 'enquire.py', 'debfile.py', 'database.py', |
1249 | 19 | exclude = [] | 18 | 'categories.py', 'application.py', 'appfilter.py', '__init__.py'] |
1250 | 20 | 19 | ||
1251 | 21 | def message(self, text): | 20 | def message(self, text): |
1252 | 22 | self.errors.append(text) | 21 | self.errors.append(text) |