Status: | Merged |
---|---|
Merged at revision: | 442 |
Proposed branch: | lp:~mvo/gdebi/add-linitan |
Merge into: | lp:gdebi |
Diff against target: |
921 lines (+242/-107) (has conflicts) 4 files modified
GDebi/GDebi.py (+109/-45) GDebi/GDebiCommon.py (+9/-8) data/gdebi.ui (+61/-54) tests/test_gdebi_gtk_lintian.py (+63/-0) Text conflict in GDebi/GDebi.py |
To merge this branch: | bzr merge lp:~mvo/gdebi/add-linitan |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
gdebi-developers | Pending | ||
Review via email: mp+128427@code.launchpad.net |
Commit message
Description of the change
This branch adds a "lintian" tab to the main notebook that show the
lintian status of the deb in question
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 'GDebi/GDebi.py' |
2 | --- GDebi/GDebi.py 2012-10-05 10:32:37 +0000 |
3 | +++ GDebi/GDebi.py 2012-10-08 06:56:32 +0000 |
4 | @@ -52,7 +52,7 @@ |
5 | from gettext import gettext as _ |
6 | |
7 | # the timeout when the termial is expanded if no activity from dpkg |
8 | -# is happening |
9 | +# is happening |
10 | GDEBI_TERMINAL_TIMEOUT=4*60.0 |
11 | |
12 | # HACK - there are two ubuntu specific patches, one for VTE, one |
13 | @@ -67,7 +67,7 @@ |
14 | class GDebi(SimpleGtkbuilderApp, GDebiCommon): |
15 | |
16 | def __init__(self, datadir, options, file=""): |
17 | - GDebiCommon.__init__(self,datadir,options,file) |
18 | + GDebiCommon.__init__(self,datadir, options, file) |
19 | localesApp="gdebi" |
20 | localesDir="/usr/share/locale" |
21 | |
22 | @@ -79,13 +79,13 @@ |
23 | logo=icons.load_icon("gnome-mime-application-x-deb", 48, 0) |
24 | if logo != "": |
25 | Gtk.Window.set_default_icon_list([logo]) |
26 | - except Exception, e: |
27 | + except Exception as e: |
28 | print "Error loading logo" |
29 | pass |
30 | |
31 | # create terminal |
32 | self.vte_terminal = Vte.Terminal() |
33 | - # FIXME: this sucks but without it the terminal window is only |
34 | + # FIXME: this sucks but without it the terminal window is only |
35 | # 1 line height |
36 | self.vte_terminal.set_size_request(80*10, 25*10) |
37 | menu = Gtk.Menu() |
38 | @@ -124,7 +124,7 @@ |
39 | self.show_alert(Gtk.MessageType.ERROR, self.error_header, self.error_body) |
40 | sys.exit(1) |
41 | self.statusbar_main.push(self.context, "") |
42 | - |
43 | + |
44 | # setup the details treeview |
45 | self.details_list = Gtk.ListStore(GObject.TYPE_STRING) |
46 | column = Gtk.TreeViewColumn("") |
47 | @@ -145,6 +145,7 @@ |
48 | self.synaptic_config = apt_pkg.Configuration() |
49 | |
50 | if file != "" and os.path.exists(file): |
51 | +<<<<<<< TREE |
52 | self.open(file) |
53 | self.window_main.set_sensitive(True) |
54 | |
55 | @@ -158,6 +159,15 @@ |
56 | Gtk.main_iteration() |
57 | else: |
58 | win.set_cursor(None) |
59 | +======= |
60 | + self.window_main.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH)) |
61 | + while Gtk.events_pending(): |
62 | + Gtk.main_iteration() |
63 | + self.open(file) |
64 | + self.window_main.get_window().set_cursor(None) |
65 | + |
66 | + self.window_main.set_sensitive(True) |
67 | +>>>>>>> MERGE-SOURCE |
68 | |
69 | def gio_progress_callback(self, bytes_read, bytes_total, data): |
70 | self.progressbar_download.set_fraction(bytes_read/float(bytes_total)) |
71 | @@ -173,7 +183,7 @@ |
72 | if (gio_file.get_uri_scheme() == "file"): |
73 | return file |
74 | if (os.getuid()==0): |
75 | - self.show_alert(Gtk.MessageType.ERROR, |
76 | + self.show_alert(Gtk.MessageType.ERROR, |
77 | _("Can not download as root"), |
78 | _("Remote packages can not be downloaded when " |
79 | "running as root. Please try again as a " |
80 | @@ -194,7 +204,7 @@ |
81 | file = gio_dest.get_path() |
82 | self.dialog_gio_download.hide() |
83 | except Exception, e: |
84 | - self.show_alert(Gtk.MessageType.ERROR, |
85 | + self.show_alert(Gtk.MessageType.ERROR, |
86 | _("Download failed"), |
87 | _("Downloading the package failed: " |
88 | "file '%s' '%s'") % (file, e)) |
89 | @@ -213,7 +223,7 @@ |
90 | elif path.startswith('file:'): # xffm |
91 | path = path[5:] # 5 is len('file:') |
92 | return path |
93 | - |
94 | + |
95 | def on_menuitem_quit_activate(self, widget): |
96 | try: |
97 | Gtk.main_quit() |
98 | @@ -230,20 +240,31 @@ |
99 | path = self._get_file_path_from_dnd_dropped_uri(uri) |
100 | #print 'path to open', path |
101 | if path.endswith(".deb"): |
102 | +<<<<<<< TREE |
103 | +======= |
104 | + self.window_main.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH)) |
105 | + while Gtk.events_pending(): |
106 | + Gtk.main_iteration() |
107 | +>>>>>>> MERGE-SOURCE |
108 | self.open(path) |
109 | |
110 | +<<<<<<< TREE |
111 | def open(self, file, downloaded=False): |
112 | self._show_busy_cursor(True) |
113 | res = GDebiCommon.open(self, file, downloaded) |
114 | self._show_busy_cursor(False) |
115 | +======= |
116 | + def open(self, filename, downloaded=False): |
117 | + res = GDebiCommon.open(self, filename, downloaded) |
118 | +>>>>>>> MERGE-SOURCE |
119 | if res == False: |
120 | self.show_alert(Gtk.MessageType.ERROR, self.error_header, self.error_body) |
121 | return False |
122 | - |
123 | + |
124 | self.statusbar_main.push(self.context, "") |
125 | |
126 | # set window title |
127 | - self.window_main.set_title(_("Package Installer - %s") % |
128 | + self.window_main.set_title(_("Package Installer - %s") % |
129 | self._deb.pkgname) |
130 | |
131 | # set name and ungrey some widgets |
132 | @@ -315,6 +336,11 @@ |
133 | # and the file content textview |
134 | font_desc = Pango.FontDescription('monospace') |
135 | self.textview_file_content.modify_font(font_desc) |
136 | + self.textview_lintian_output.modify_font(font_desc) |
137 | + |
138 | + # run lintian async |
139 | + if self._options and self._options.non_interactive is False: |
140 | + self._run_lintian(filename) |
141 | |
142 | # check the deps |
143 | if not self._deb.check(): |
144 | @@ -322,7 +348,7 @@ |
145 | "<span foreground=\"red\" weight=\"bold\">"+ |
146 | _("Error: ") + |
147 | #glib.markup_escape_text(self._deb._failure_string) + |
148 | - self._deb._failure_string + |
149 | + self._deb._failure_string + |
150 | "</span>") |
151 | self.button_install.set_label(_("_Install Package")) |
152 | |
153 | @@ -376,7 +402,7 @@ |
154 | self.button_details.hide() |
155 | else: |
156 | self.button_details.show() |
157 | - |
158 | + |
159 | self.label_status.set_markup(self.deps) |
160 | #img = Gtk.Image() |
161 | #img.set_from_stock(Gtk.STOCK_APPLY,Gtk.IconSize.BUTTON) |
162 | @@ -386,6 +412,44 @@ |
163 | self.button_install.grab_default() |
164 | self.button_remove.hide() |
165 | |
166 | + def _run_lintian(self, filename): |
167 | + buf = self.textview_lintian_output.get_buffer() |
168 | + if not os.path.exists("/usr/bin/lintian"): |
169 | + buf.set_text( |
170 | + _("No lintian available.\n" |
171 | + "Please install using sudo apt-get install lintian")) |
172 | + return |
173 | + buf.set_text(_("Running lintian...")) |
174 | + self._lintian_output = "" |
175 | + self._lintian_exit_status = None |
176 | + cmd = ["/usr/bin/lintian", filename] |
177 | + (pid, stdin, stdout, stderr) = GLib.spawn_async( |
178 | + cmd, flags=GObject.SPAWN_DO_NOT_REAP_CHILD, |
179 | + standard_output=True, standard_error=True) |
180 | + for fd in [stdout, stderr]: |
181 | + channel = GLib.IOChannel(filedes=fd) |
182 | + channel.set_flags(GLib.IOFlags.NONBLOCK) |
183 | + channel.add_watch(GLib.IOCondition.IN, self._on_lintian_output) |
184 | + GObject.child_watch_add( |
185 | + pid, self._on_lintian_finished) |
186 | + |
187 | + def _on_lintian_finished(self, pid, condition): |
188 | + exit_status = os.WEXITSTATUS(condition) |
189 | + self._lintian_exit_status = exit_status |
190 | + text = _("\nLintian finished with exit status %s") % exit_status |
191 | + self._lintian_output += text |
192 | + buf = self.textview_lintian_output.get_buffer() |
193 | + buf.set_text(self._lintian_output) |
194 | + |
195 | + def _on_lintian_output(self, gio_file, condition): |
196 | + if condition & GLib.IOCondition.IN: |
197 | + content = gio_file.read() |
198 | + if content: |
199 | + self._lintian_output += content |
200 | + buf = self.textview_lintian_output.get_buffer() |
201 | + buf.set_text(self._lintian_output) |
202 | + return True |
203 | + |
204 | def on_treeview_files_cursor_changed(self, treeview): |
205 | " the selection in the files list chanaged " |
206 | model = treeview.get_model() |
207 | @@ -437,9 +501,9 @@ |
208 | # build dialog |
209 | self.window_main.set_sensitive(False) |
210 | fs = Gtk.FileChooserDialog(parent=self.window_main, |
211 | - buttons=(Gtk.STOCK_CANCEL, |
212 | - Gtk.ResponseType.CANCEL, |
213 | - Gtk.STOCK_OPEN, |
214 | + buttons=(Gtk.STOCK_CANCEL, |
215 | + Gtk.ResponseType.CANCEL, |
216 | + Gtk.STOCK_OPEN, |
217 | Gtk.ResponseType.OK), |
218 | action=Gtk.FileChooserAction.OPEN, |
219 | title=_("Open Software Package")) |
220 | @@ -466,7 +530,7 @@ |
221 | self.window_main.set_sensitive(True) |
222 | |
223 | def on_copy_activate(self, widget): |
224 | - clipboard = Gtk.Clipboard.get(Gdk.atom_intern('CLIPBOARD', True)) |
225 | + clipboard = Gtk.Clipboard.get(Gdk.atom_intern('CLIPBOARD', True)) |
226 | buf = self.textview_description.get_buffer() |
227 | if buf.get_has_selection(): |
228 | buf.copy_clipboard(clipboard) |
229 | @@ -535,7 +599,7 @@ |
230 | scrolled = Gtk.ScrolledWindow() |
231 | textview = Gtk.TextView() |
232 | textview.set_cursor_visible(False) |
233 | - textview.set_editable(False) |
234 | + textview.set_editable(False) |
235 | buf = textview.get_buffer() |
236 | buf.set_text("\n".join(self.unauthenticated)) |
237 | scrolled.add(textview) |
238 | @@ -584,13 +648,13 @@ |
239 | self.statusbar_main.push(self.context, msgstring) |
240 | self.show_alert(Gtk.MessageType.ERROR, self.error_header, self.error_body) |
241 | return False |
242 | - |
243 | + |
244 | # lock for install |
245 | self.window_main.set_sensitive(False) |
246 | self.button_deb_install_close.set_sensitive(False) |
247 | # clear terminal |
248 | #self.vte_terminal.feed(str(0x1b)+"[2J") |
249 | - |
250 | + |
251 | # Get whether we auto close from synaptic's config file and |
252 | # update the toggle button as neccessary |
253 | config = apt_pkg.Configuration() |
254 | @@ -602,7 +666,7 @@ |
255 | config["Synaptic::closeZvt"] = "false" |
256 | self.synaptic_config = config.subtree("Synaptic") |
257 | self.checkbutton_autoclose.set_active(self.synaptic_config.find_b("closeZvt")) |
258 | - |
259 | + |
260 | self.dialog_deb_install.set_transient_for(self.window_main) |
261 | self.dialog_deb_install.show_all() |
262 | |
263 | @@ -638,13 +702,13 @@ |
264 | if not res: |
265 | self.show_alert(Gtk.MessageType.ERROR, header, body, msg, |
266 | parent=self.dialog_deb_install) |
267 | - |
268 | + |
269 | self.label_install_status.set_markup("<span foreground=\"red\" weight=\"bold\">%s</span>" % header) |
270 | self.button_deb_install_close.set_sensitive(True) |
271 | self.button_deb_install_close.grab_default() |
272 | self.statusbar_main.push(self.context,_("Failed to install package file")) |
273 | - return |
274 | - |
275 | + return |
276 | + |
277 | # install the package itself |
278 | self.dialog_deb_install.set_title(self.window_main.get_title()) |
279 | if install: |
280 | @@ -683,10 +747,10 @@ |
281 | self.label_install_status.set_markup("<i>"+_("Package '%s' was removed") % os.path.basename(self._deb.pkgname)+"</i>") |
282 | else: |
283 | if install: |
284 | - self.label_install_status.set_markup("<b>"+_("Failed to install package '%s'") % |
285 | + self.label_install_status.set_markup("<b>"+_("Failed to install package '%s'") % |
286 | os.path.basename(self._deb.filename)+"</b>") |
287 | else: |
288 | - self.label_install_status.set_markup("<b>"+_("Failed to remove package '%s'") % |
289 | + self.label_install_status.set_markup("<b>"+_("Failed to remove package '%s'") % |
290 | os.path.basename(self._deb.pkgname)+"</b>") |
291 | self.expander_install.set_expanded(True) |
292 | if install: |
293 | @@ -718,7 +782,7 @@ |
294 | |
295 | def on_button_remove_clicked(self, widget): |
296 | self.dpkg_action(widget, False) |
297 | - |
298 | + |
299 | def on_button_deb_install_close_clicked(self, widget): |
300 | # Set the autoclose option when we close |
301 | autoclose = self.checkbutton_autoclose.get_active() |
302 | @@ -731,17 +795,17 @@ |
303 | self._gio_cancellable.cancel() |
304 | self.dialog_deb_install.hide() |
305 | self.window_main.set_sensitive(True) |
306 | - |
307 | + |
308 | def on_checkbutton_autoclose_clicked(self, widget): |
309 | if self.action_completed: |
310 | - self.on_button_deb_install_close_clicked(None) |
311 | + self.on_button_deb_install_close_clicked(None) |
312 | |
313 | def on_window_main_delete_event(self, *args): |
314 | if self.window_main.get_property("sensitive"): |
315 | if Gtk.main_level() > 0: |
316 | Gtk.main_quit() |
317 | return False |
318 | - else: |
319 | + else: |
320 | return True |
321 | |
322 | def show_alert(self, type, header, body=None, details=None, parent=None): |
323 | @@ -754,26 +818,26 @@ |
324 | if not body == None: |
325 | message = "%s\n\n%s" % (message, body) |
326 | self.label_hig.set_markup(message) |
327 | - |
328 | + |
329 | if not details == None: |
330 | buffer = self.textview_hig.get_buffer() |
331 | buffer.set_text(str(details)) |
332 | self.expander_hig.set_expanded(False) |
333 | self.expander_hig.show() |
334 | - |
335 | + |
336 | if type == Gtk.MessageType.ERROR: |
337 | self.image_hig.set_property("stock", "gtk-dialog-error") |
338 | elif type == Gtk.MessageType.WARNING: |
339 | self.image_hig.set_property("stock", "gtk-dialog-warning") |
340 | elif type == Gtk.MessageType.INFO: |
341 | self.image_hig.set_property("stock", "gtk-dialog-info") |
342 | - |
343 | + |
344 | res = self.dialog_hig.run() |
345 | self.dialog_hig.hide() |
346 | if res == Gtk.ResponseType.CLOSE: |
347 | return True |
348 | return False |
349 | - |
350 | + |
351 | def write_synaptic_config_file(self, config, path): |
352 | if not os.path.exists(path): |
353 | return |
354 | @@ -791,7 +855,7 @@ |
355 | |
356 | def menu_action(self, widget, terminal): |
357 | terminal.copy_clipboard() |
358 | - |
359 | + |
360 | # embedded classes |
361 | class DpkgActionProgress(object): |
362 | def __init__(self, debfile, status, progress, term, expander, install=True): |
363 | @@ -838,7 +902,7 @@ |
364 | |
365 | # the command |
366 | argv = ["/usr/bin/dpkg", "--auto-deconfigure"] |
367 | - # ubuntu supports VTE_PTY_KEEP_FD, see |
368 | + # ubuntu supports VTE_PTY_KEEP_FD, see |
369 | # https://bugzilla.gnome.org/320128 for the upstream bug |
370 | if UBUNTU: |
371 | argv += ["--status-fd", "%s"%writefd] |
372 | @@ -857,8 +921,8 @@ |
373 | self.term.connect("child-exited", finish_dpkg, lock) |
374 | (res, pid) =self.term.fork_command_full( |
375 | Vte.PtyFlags.DEFAULT, |
376 | - "/", |
377 | - argv, |
378 | + "/", |
379 | + argv, |
380 | env, |
381 | GLib.SpawnFlags.LEAVE_DESCRIPTORS_OPEN, |
382 | # FIXME: add setup_func that closes all fds excpet for writefd |
383 | @@ -895,11 +959,11 @@ |
384 | Gtk.main_iteration() |
385 | time.sleep(0.2) |
386 | # if the terminal has not reacted for some time, do something |
387 | - if (not self.term_expander.get_expanded() and |
388 | + if (not self.term_expander.get_expanded() and |
389 | (self.time_last_update + GDEBI_TERMINAL_TIMEOUT) < time.time()): |
390 | self.term_expander.set_expanded(True) |
391 | self.progress.set_fraction(1.0) |
392 | - |
393 | + |
394 | class InstallProgressAdapter(InstallProgress): |
395 | def __init__(self,progress,term,label,term_expander): |
396 | InstallProgress.__init__(self) |
397 | @@ -941,7 +1005,7 @@ |
398 | InstallProgress.update_interface(self) |
399 | while Gtk.events_pending(): |
400 | Gtk.main_iteration() |
401 | - if (not self.term_expander.get_expanded() and |
402 | + if (not self.term_expander.get_expanded() and |
403 | (self.time_last_update + GDEBI_TERMINAL_TIMEOUT) < time.time()): |
404 | self.term_expander.set_expanded(True) |
405 | # sleep just long enough to not create a busy loop |
406 | @@ -965,7 +1029,7 @@ |
407 | while not self.finished: |
408 | self.update_interface() |
409 | return self.apt_status |
410 | - |
411 | + |
412 | class FetchProgressAdapter(apt.progress.base.AcquireProgress): |
413 | def __init__(self,progress,action,main): |
414 | super(GDebi.FetchProgressAdapter, self).__init__() |
415 | @@ -1017,7 +1081,7 @@ |
416 | Gtk.main_iteration() |
417 | def done(self): |
418 | self.progressbar.hide() |
419 | - |
420 | + |
421 | if __name__ == "__main__": |
422 | app = GDebi("data/",None) |
423 | |
424 | @@ -1033,16 +1097,16 @@ |
425 | apt_pkg.pkgsystem_lock() |
426 | app.dialog_deb_install.set_transient_for(app.window_main) |
427 | app.dialog_deb_install.show_all() |
428 | - |
429 | + |
430 | # install the dependecnies |
431 | fprogress = app.FetchProgressAdapter(app.progressbar_install, |
432 | app.label_action, |
433 | app.dialog_deb_install) |
434 | - iprogress = app.InstallProgressAdapter(app.progressbar_install, |
435 | + iprogress = app.InstallProgressAdapter(app.progressbar_install, |
436 | app.vte_terminal, |
437 | app.label_action, |
438 | app.expander_install) |
439 | res = app._cache.commit(fprogress,iprogress) |
440 | print "commit retured: %s" % res |
441 | - |
442 | + |
443 | Gtk.main() |
444 | |
445 | === modified file 'GDebi/GDebiCommon.py' |
446 | --- GDebi/GDebiCommon.py 2012-09-12 21:28:17 +0000 |
447 | +++ GDebi/GDebiCommon.py 2012-10-08 06:56:32 +0000 |
448 | @@ -49,6 +49,7 @@ |
449 | return unicode(str, 'latin1') |
450 | |
451 | class GDebiCommon(object): |
452 | + |
453 | # cprogress may be different in child classes |
454 | def __init__(self, datadir, options, file=""): |
455 | self.cprogress = None |
456 | @@ -64,14 +65,14 @@ |
457 | def openCache(self): |
458 | self._cache = Cache(self.cprogress) |
459 | if self._cache._depcache.broken_count > 0: |
460 | - self.error_header = _("Broken dependencies") |
461 | - self.error_body = _("Your system has broken dependencies. " |
462 | - "This application can not continue until " |
463 | - "this is fixed. " |
464 | - "To fix it run 'gksudo synaptic' or " |
465 | - "'sudo apt-get install -f' " |
466 | - "in a terminal window.") |
467 | - return False |
468 | + self.error_header = _("Broken dependencies") |
469 | + self.error_body = _("Your system has broken dependencies. " |
470 | + "This application can not continue until " |
471 | + "this is fixed. " |
472 | + "To fix it run 'gksudo synaptic' or " |
473 | + "'sudo apt-get install -f' " |
474 | + "in a terminal window.") |
475 | + return False |
476 | return True |
477 | |
478 | def open(self, file, downloaded=False): |
479 | |
480 | === modified file 'data/gdebi.ui' |
481 | --- data/gdebi.ui 2012-09-13 21:32:07 +0000 |
482 | +++ data/gdebi.ui 2012-10-08 06:56:32 +0000 |
483 | @@ -1,6 +1,6 @@ |
484 | <?xml version="1.0" encoding="UTF-8"?> |
485 | <interface> |
486 | - <requires lib="gtk+" version="2.16"/> |
487 | + <!-- interface-requires gtk+ 3.0 --> |
488 | <object class="GtkAccelGroup" id="accelgroup1"/> |
489 | <object class="GtkAboutDialog" id="dialog_about"> |
490 | <property name="can_focus">False</property> |
491 | @@ -69,7 +69,6 @@ |
492 | <property name="can_focus">True</property> |
493 | <property name="can_default">True</property> |
494 | <property name="receives_default">False</property> |
495 | - <property name="use_action_appearance">False</property> |
496 | <property name="use_stock">True</property> |
497 | <signal name="clicked" handler="on_button_deb_install_close_clicked" swapped="no"/> |
498 | </object> |
499 | @@ -180,8 +179,8 @@ |
500 | <property name="visible">True</property> |
501 | <property name="can_focus">True</property> |
502 | <property name="receives_default">False</property> |
503 | - <property name="use_action_appearance">False</property> |
504 | <property name="use_underline">True</property> |
505 | + <property name="xalign">0.5</property> |
506 | <property name="draw_indicator">True</property> |
507 | <signal name="clicked" handler="on_checkbutton_autoclose_clicked" swapped="no"/> |
508 | </object> |
509 | @@ -230,7 +229,6 @@ |
510 | <property name="can_focus">True</property> |
511 | <property name="can_default">True</property> |
512 | <property name="receives_default">False</property> |
513 | - <property name="use_action_appearance">False</property> |
514 | <property name="use_stock">True</property> |
515 | </object> |
516 | <packing> |
517 | @@ -328,7 +326,6 @@ |
518 | <property name="can_focus">True</property> |
519 | <property name="can_default">True</property> |
520 | <property name="receives_default">True</property> |
521 | - <property name="use_action_appearance">False</property> |
522 | <property name="use_stock">True</property> |
523 | </object> |
524 | <packing> |
525 | @@ -439,7 +436,6 @@ |
526 | <property name="can_focus">True</property> |
527 | <property name="can_default">True</property> |
528 | <property name="receives_default">False</property> |
529 | - <property name="use_action_appearance">False</property> |
530 | <property name="use_stock">True</property> |
531 | </object> |
532 | <packing> |
533 | @@ -589,7 +585,6 @@ |
534 | <object class="GtkMenuItem" id="menuitem1"> |
535 | <property name="visible">True</property> |
536 | <property name="can_focus">False</property> |
537 | - <property name="use_action_appearance">False</property> |
538 | <property name="label" translatable="yes">_File</property> |
539 | <property name="use_underline">True</property> |
540 | <child type="submenu"> |
541 | @@ -600,7 +595,6 @@ |
542 | <property name="label" translatable="yes">_Open…</property> |
543 | <property name="visible">True</property> |
544 | <property name="can_focus">False</property> |
545 | - <property name="use_action_appearance">False</property> |
546 | <property name="use_underline">True</property> |
547 | <property name="image">image1</property> |
548 | <property name="use_stock">False</property> |
549 | @@ -614,7 +608,6 @@ |
550 | <property name="label" translatable="yes">_Refresh</property> |
551 | <property name="visible">True</property> |
552 | <property name="can_focus">False</property> |
553 | - <property name="use_action_appearance">False</property> |
554 | <property name="use_underline">True</property> |
555 | <property name="image">image2</property> |
556 | <property name="use_stock">False</property> |
557 | @@ -634,7 +627,6 @@ |
558 | <property name="label">gtk-quit</property> |
559 | <property name="visible">True</property> |
560 | <property name="can_focus">False</property> |
561 | - <property name="use_action_appearance">False</property> |
562 | <property name="use_underline">True</property> |
563 | <property name="use_stock">True</property> |
564 | <property name="accel_group">accelgroup1</property> |
565 | @@ -649,7 +641,6 @@ |
566 | <object class="GtkMenuItem" id="menuitem3"> |
567 | <property name="visible">True</property> |
568 | <property name="can_focus">False</property> |
569 | - <property name="use_action_appearance">False</property> |
570 | <property name="label" translatable="yes">_Edit</property> |
571 | <property name="use_underline">True</property> |
572 | <child type="submenu"> |
573 | @@ -660,7 +651,6 @@ |
574 | <property name="label">gtk-copy</property> |
575 | <property name="visible">True</property> |
576 | <property name="can_focus">False</property> |
577 | - <property name="use_action_appearance">False</property> |
578 | <property name="use_underline">True</property> |
579 | <property name="use_stock">True</property> |
580 | <property name="accel_group">accelgroup1</property> |
581 | @@ -675,7 +665,6 @@ |
582 | <object class="GtkMenuItem" id="menuitem4"> |
583 | <property name="visible">True</property> |
584 | <property name="can_focus">False</property> |
585 | - <property name="use_action_appearance">False</property> |
586 | <property name="label" translatable="yes">_Help</property> |
587 | <property name="use_underline">True</property> |
588 | <child type="submenu"> |
589 | @@ -686,7 +675,6 @@ |
590 | <property name="label">gtk-about</property> |
591 | <property name="visible">True</property> |
592 | <property name="can_focus">False</property> |
593 | - <property name="use_action_appearance">False</property> |
594 | <property name="use_underline">True</property> |
595 | <property name="use_stock">True</property> |
596 | <property name="accel_group">accelgroup1</property> |
597 | @@ -727,7 +715,7 @@ |
598 | </object> |
599 | <packing> |
600 | <property name="x_options">GTK_FILL</property> |
601 | - <property name="y_options"></property> |
602 | + <property name="y_options"/> |
603 | </packing> |
604 | </child> |
605 | <child> |
606 | @@ -737,14 +725,12 @@ |
607 | <property name="xalign">0</property> |
608 | <property name="label" translatable="yes"><b><big> </big></b></property> |
609 | <property name="use_markup">True</property> |
610 | - <property name="selectable">False</property> |
611 | - <property name="sensitive">True</property> |
612 | </object> |
613 | <packing> |
614 | <property name="left_attach">1</property> |
615 | <property name="right_attach">2</property> |
616 | <property name="x_options">GTK_FILL</property> |
617 | - <property name="y_options"></property> |
618 | + <property name="y_options"/> |
619 | </packing> |
620 | </child> |
621 | <child> |
622 | @@ -758,8 +744,6 @@ |
623 | <property name="xalign">0</property> |
624 | <property name="yalign">0</property> |
625 | <property name="wrap">True</property> |
626 | - <property name="selectable">False</property> |
627 | - <property name="sensitive">True</property> |
628 | </object> |
629 | <packing> |
630 | <property name="expand">True</property> |
631 | @@ -777,7 +761,6 @@ |
632 | <property name="label" translatable="yes">_Details</property> |
633 | <property name="can_focus">True</property> |
634 | <property name="receives_default">True</property> |
635 | - <property name="use_action_appearance">False</property> |
636 | <property name="use_underline">True</property> |
637 | <signal name="clicked" handler="on_button_details_clicked" swapped="no"/> |
638 | </object> |
639 | @@ -804,7 +787,7 @@ |
640 | <property name="top_attach">2</property> |
641 | <property name="bottom_attach">3</property> |
642 | <property name="x_options">GTK_FILL</property> |
643 | - <property name="y_options"></property> |
644 | + <property name="y_options"/> |
645 | </packing> |
646 | </child> |
647 | <child> |
648 | @@ -832,7 +815,7 @@ |
649 | <property name="top_attach">1</property> |
650 | <property name="bottom_attach">2</property> |
651 | <property name="x_options">GTK_FILL</property> |
652 | - <property name="y_options"></property> |
653 | + <property name="y_options"/> |
654 | </packing> |
655 | </child> |
656 | <child> |
657 | @@ -846,7 +829,7 @@ |
658 | <property name="right_attach">2</property> |
659 | <property name="top_attach">1</property> |
660 | <property name="bottom_attach">2</property> |
661 | - <property name="y_options"></property> |
662 | + <property name="y_options"/> |
663 | </packing> |
664 | </child> |
665 | </object> |
666 | @@ -869,7 +852,6 @@ |
667 | <property name="can_focus">True</property> |
668 | <property name="can_default">True</property> |
669 | <property name="receives_default">False</property> |
670 | - <property name="use_action_appearance">False</property> |
671 | <property name="use_underline">True</property> |
672 | <signal name="clicked" handler="on_button_install_clicked" swapped="no"/> |
673 | </object> |
674 | @@ -880,13 +862,28 @@ |
675 | </packing> |
676 | </child> |
677 | <child> |
678 | + <object class="GtkButton" id="button_remove"> |
679 | + <property name="label" translatable="yes">_Remove Package</property> |
680 | + <property name="sensitive">False</property> |
681 | + <property name="can_focus">True</property> |
682 | + <property name="can_default">True</property> |
683 | + <property name="receives_default">False</property> |
684 | + <property name="use_underline">True</property> |
685 | + <signal name="clicked" handler="on_button_remove_clicked" swapped="no"/> |
686 | + </object> |
687 | + <packing> |
688 | + <property name="expand">False</property> |
689 | + <property name="fill">False</property> |
690 | + <property name="position">1</property> |
691 | + </packing> |
692 | + </child> |
693 | + <child> |
694 | <object class="GtkButton" id="button_download"> |
695 | <property name="label" translatable="yes">_Download Package</property> |
696 | <property name="sensitive">False</property> |
697 | <property name="can_focus">True</property> |
698 | <property name="can_default">True</property> |
699 | <property name="receives_default">False</property> |
700 | - <property name="use_action_appearance">False</property> |
701 | <property name="use_underline">True</property> |
702 | <signal name="clicked" handler="on_button_download_clicked" swapped="no"/> |
703 | </object> |
704 | @@ -897,24 +894,6 @@ |
705 | </packing> |
706 | </child> |
707 | <child> |
708 | - <object class="GtkButton" id="button_remove"> |
709 | - <property name="label" translatable="yes">_Remove Package</property> |
710 | - <property name="visible">False</property> |
711 | - <property name="sensitive">False</property> |
712 | - <property name="can_focus">True</property> |
713 | - <property name="can_default">True</property> |
714 | - <property name="receives_default">False</property> |
715 | - <property name="use_action_appearance">False</property> |
716 | - <property name="use_underline">True</property> |
717 | - <signal name="clicked" handler="on_button_remove_clicked" swapped="no"/> |
718 | - </object> |
719 | - <packing> |
720 | - <property name="expand">False</property> |
721 | - <property name="fill">False</property> |
722 | - <property name="position">1</property> |
723 | - </packing> |
724 | - </child> |
725 | - <child> |
726 | <placeholder/> |
727 | </child> |
728 | </object> |
729 | @@ -987,7 +966,7 @@ |
730 | </object> |
731 | <packing> |
732 | <property name="x_options">GTK_FILL</property> |
733 | - <property name="y_options"></property> |
734 | + <property name="y_options"/> |
735 | </packing> |
736 | </child> |
737 | <child> |
738 | @@ -1002,7 +981,7 @@ |
739 | <property name="top_attach">1</property> |
740 | <property name="bottom_attach">2</property> |
741 | <property name="x_options">GTK_FILL</property> |
742 | - <property name="y_options"></property> |
743 | + <property name="y_options"/> |
744 | </packing> |
745 | </child> |
746 | <child> |
747 | @@ -1017,7 +996,7 @@ |
748 | <property name="top_attach">2</property> |
749 | <property name="bottom_attach">3</property> |
750 | <property name="x_options">GTK_FILL</property> |
751 | - <property name="y_options"></property> |
752 | + <property name="y_options"/> |
753 | </packing> |
754 | </child> |
755 | <child> |
756 | @@ -1032,7 +1011,7 @@ |
757 | <property name="top_attach">3</property> |
758 | <property name="bottom_attach">4</property> |
759 | <property name="x_options">GTK_FILL</property> |
760 | - <property name="y_options"></property> |
761 | + <property name="y_options"/> |
762 | </packing> |
763 | </child> |
764 | <child> |
765 | @@ -1047,7 +1026,7 @@ |
766 | <property name="top_attach">4</property> |
767 | <property name="bottom_attach">5</property> |
768 | <property name="x_options">GTK_FILL</property> |
769 | - <property name="y_options"></property> |
770 | + <property name="y_options"/> |
771 | </packing> |
772 | </child> |
773 | <child> |
774 | @@ -1063,7 +1042,7 @@ |
775 | <property name="top_attach">1</property> |
776 | <property name="bottom_attach">2</property> |
777 | <property name="x_options">GTK_FILL</property> |
778 | - <property name="y_options"></property> |
779 | + <property name="y_options"/> |
780 | </packing> |
781 | </child> |
782 | <child> |
783 | @@ -1079,7 +1058,7 @@ |
784 | <property name="top_attach">2</property> |
785 | <property name="bottom_attach">3</property> |
786 | <property name="x_options">GTK_FILL</property> |
787 | - <property name="y_options"></property> |
788 | + <property name="y_options"/> |
789 | </packing> |
790 | </child> |
791 | <child> |
792 | @@ -1095,7 +1074,7 @@ |
793 | <property name="top_attach">3</property> |
794 | <property name="bottom_attach">4</property> |
795 | <property name="x_options">GTK_FILL</property> |
796 | - <property name="y_options"></property> |
797 | + <property name="y_options"/> |
798 | </packing> |
799 | </child> |
800 | <child> |
801 | @@ -1109,7 +1088,7 @@ |
802 | <property name="left_attach">1</property> |
803 | <property name="right_attach">2</property> |
804 | <property name="x_options">GTK_FILL</property> |
805 | - <property name="y_options"></property> |
806 | + <property name="y_options"/> |
807 | </packing> |
808 | </child> |
809 | <child> |
810 | @@ -1124,7 +1103,7 @@ |
811 | <property name="right_attach">2</property> |
812 | <property name="top_attach">4</property> |
813 | <property name="bottom_attach">5</property> |
814 | - <property name="y_options"></property> |
815 | + <property name="y_options"/> |
816 | </packing> |
817 | </child> |
818 | </object> |
819 | @@ -1216,6 +1195,34 @@ |
820 | <property name="tab_fill">False</property> |
821 | </packing> |
822 | </child> |
823 | + <child> |
824 | + <object class="GtkScrolledWindow" id="scrolledwindow3"> |
825 | + <property name="visible">True</property> |
826 | + <property name="can_focus">True</property> |
827 | + <property name="shadow_type">in</property> |
828 | + <child> |
829 | + <object class="GtkTextView" id="textview_lintian_output"> |
830 | + <property name="visible">True</property> |
831 | + <property name="can_focus">True</property> |
832 | + <property name="editable">False</property> |
833 | + </object> |
834 | + </child> |
835 | + </object> |
836 | + <packing> |
837 | + <property name="position">3</property> |
838 | + </packing> |
839 | + </child> |
840 | + <child type="tab"> |
841 | + <object class="GtkLabel" id="label_lintian"> |
842 | + <property name="visible">True</property> |
843 | + <property name="can_focus">False</property> |
844 | + <property name="label" translatable="yes">Lintian output</property> |
845 | + </object> |
846 | + <packing> |
847 | + <property name="position">3</property> |
848 | + <property name="tab_fill">False</property> |
849 | + </packing> |
850 | + </child> |
851 | </object> |
852 | <packing> |
853 | <property name="expand">True</property> |
854 | |
855 | === added file 'tests/test_gdebi_gtk_lintian.py' |
856 | --- tests/test_gdebi_gtk_lintian.py 1970-01-01 00:00:00 +0000 |
857 | +++ tests/test_gdebi_gtk_lintian.py 2012-10-08 06:56:32 +0000 |
858 | @@ -0,0 +1,63 @@ |
859 | +#!/usr/bin/python |
860 | + |
861 | +import os |
862 | +import time |
863 | +import unittest |
864 | + |
865 | +from gi.repository import GObject |
866 | +from mock import patch |
867 | + |
868 | +from GDebi.GDebi import GDebi |
869 | +from GDebi.GDebiCommon import GDebiCommon |
870 | + |
871 | +EXPECTED_LINTIAN_OUTPUT = """E: error-package: file-in-etc-not-marked-as-conffile etc/foo |
872 | +E: error-package: control-file-has-bad-owner postinst egon/egon != root/root |
873 | +E: error-package: no-copyright-file |
874 | +E: error-package: package-has-no-description |
875 | +E: error-package: no-maintainer-field |
876 | +W: error-package: no-section-field |
877 | +W: error-package: no-priority-field |
878 | +E: error-package: wrong-file-owner-uid-or-gid etc/ 1000/1000 |
879 | +E: error-package: wrong-file-owner-uid-or-gid etc/foo 1000/1000 |
880 | +W: error-package: maintainer-script-ignores-errors postinst |
881 | + |
882 | +Lintian finished with exit status 1""" |
883 | + |
884 | + |
885 | +def do_events(): |
886 | + context = GObject.main_context_default() |
887 | + while context.pending(): |
888 | + context.iteration() |
889 | + |
890 | + |
891 | +class GDebiGtkTestCase(unittest.TestCase): |
892 | + |
893 | + def setUp(self): |
894 | + self.testsdir = os.path.dirname(__file__) |
895 | + self.datadir = os.path.join(self.testsdir, "..", "data") |
896 | + self.options = None |
897 | + |
898 | + # we don't need a cache for this test so patch it out |
899 | + @patch.object(GDebiCommon, "openCache") |
900 | + def test_lintian(self, mock_open_cache): |
901 | + gdebi = GDebi(self.datadir, self.options) |
902 | + gdebi._run_lintian( |
903 | + os.path.join(self.testsdir, "error-package_1.0_all.deb")) |
904 | + # wait for lintian to finish |
905 | + for i in range(25): |
906 | + time.sleep(0.2) |
907 | + do_events() |
908 | + if gdebi._lintian_exit_status is not None: |
909 | + break |
910 | + else: |
911 | + self.fail("lintian did not finish") |
912 | + # compare the results |
913 | + buf = gdebi.textview_lintian_output.get_buffer() |
914 | + start = buf.get_start_iter() |
915 | + end = buf.get_end_iter() |
916 | + lintian_output = buf.get_text(start, end, False) |
917 | + self.assertEqual(lintian_output.strip(), EXPECTED_LINTIAN_OUTPUT) |
918 | + |
919 | + |
920 | +if __name__ == "__main__": |
921 | + unittest.main() |