Merge lp:~laney/software-center/webkit2 into lp:software-center

Proposed by Iain Lane
Status: Merged
Merged at revision: 3344
Proposed branch: lp:~laney/software-center/webkit2
Merge into: lp:software-center
Diff against target: 857 lines (+151/-293)
11 files modified
debian/control (+1/-1)
run-tests.sh (+2/-2)
softwarecenter/ui/gtk3/dialogs/dialog_tos.py (+15/-10)
softwarecenter/ui/gtk3/views/purchaseview.py (+22/-51)
softwarecenter/ui/gtk3/widgets/exhibits.py (+36/-36)
softwarecenter/ui/gtk3/widgets/videoplayer.py (+20/-79)
softwarecenter/ui/gtk3/widgets/webkit.py (+45/-67)
tests/gtk3/test_purchase.py (+0/-24)
tests/gtk3/test_webkit.py (+8/-18)
tests/gtk3/test_widgets.py (+1/-1)
tests/gtk3/windows.py (+1/-4)
To merge this branch: bzr merge lp:~laney/software-center/webkit2
Reviewer Review Type Date Requested Status
Iain Lane (community) Approve
software-store-developers Pending
Review via email: mp+264723@code.launchpad.net

Commit message

Port to WebKit 2

Description of the change

Initial review appreciated. There are probably still bugs (I didn't test purchasing for example).

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

This is great to see. I suggest testing these things:

* Does a purchase work?

* Does submitting a review work? (This should be fine, since the line you removed from submit_review.ui was also removed to fix bug 1445745.)

* Does an app's developer/support Web site link open in your default browser as expected?

* Does the checkbox list of add-ons show up for an app that has them? (Geany is a good example.)

lp:~laney/software-center/webkit2 updated
3325. By dobey

Fix the version string to not be so high (no previous releases of it).

3326. By Sebastien Bacher

Remove use of deprecated n_row property.

3327. By Sebastien Bacher

Use GtkIcon's lookup_icon method instead of has_icon to fix invalid icons.

3328. By Michael Vogt

Avoid a crash when the aptdaemon transaction has no package data.

3329. By Sebastien Bacher

Clear some source ID warnings.

3330. By Sebastien Bacher

Restore the GtkStyle context in the button widget.

3331. By Sebastien Bacher

Remove gwibber usage.

3332. By Sebastien Bacher

DB_NOMMAP needs to be set using set_flags, it's not valid in DBEnv.open

3333. By dobey

Multi-inherit from object as well, as RawConfigParser is old-style.
Use super to chain up initialization.

3334. By Barry Warsaw

Fix some bilingual Python 2/3 issues so plug-ins can work in both versions.

3335. By Iain Lane

Open cataloged_times.p as bytes for py3 compatibility.

3336. By Michael Vogt

Disable paste when search entry not visible.

3337. By Bruce Pieterse

Update README to mentione python3-aptdaemon.test instead.

3338. By Bruce Pieterse

Added support for Adwaita Dark Theme Variant.

3339. By dobey

Merge the debian tree in for CI train landing support.

3340. By dobey

Prepare the release.

3341. By CI Train Bot Account

Releasing 16.01+16.04.20160107.1

3342. By Iain Lane

Patch from Robin van der Vilet to not crash on locales with no country. Fixes: #1510237

3343. By CI Train Bot Account

Releasing 16.01+16.04.20160119

3344. By Iain Lane

Merge with trunk again

Revision history for this message
Iain Lane (laney) wrote :

Self approving - if you have feedback we can address in later rounds.

review: Approve
Revision history for this message
dobey (dobey) wrote :

Can you answer mpt's questions?

Revision history for this message
Iain Lane (laney) wrote :

On Wed, Feb 17, 2016 at 03:40:03PM -0000, Rodney Dawes wrote:
> Can you answer mpt's questions?

ok

--
Iain Lane [ <email address hidden> ]
Debian Developer [ <email address hidden> ]
Ubuntu Developer [ <email address hidden> ]

Revision history for this message
Iain Lane (laney) wrote :

On Tue, Jul 28, 2015 at 07:45:03AM -0000, Matthew Paul Thomas wrote:
> This is great to see. I suggest testing these things:
>
> * Does a purchase work?

I don't know how to purchase anything - is there a test server with some
packages available for xenial?

> * Does submitting a review work? (This should be fine, since the line you removed from submit_review.ui was also removed to fix bug 1445745.)

Yeah

> * Does an app's developer/support Web site link open in your default browser as expected?

Yeah

> * Does the checkbox list of add-ons show up for an app that has them? (Geany is a good example.)

Yeah

--
Iain Lane [ <email address hidden> ]
Debian Developer [ <email address hidden> ]
Ubuntu Developer [ <email address hidden> ]

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2016-01-07 18:59:19 +0000
3+++ debian/control 2016-02-17 13:44:00 +0000
4@@ -35,7 +35,7 @@
5 gir1.2-glib-2.0 (>= 1.31),
6 gir1.2-gtk-3.0,
7 gir1.2-gmenu-3.0 (>= 3.1.5),
8- gir1.2-webkit-3.0,
9+ gir1.2-webkit2-4.0,
10 gvfs-backends,
11 python-gi (>= 3.4.0-1ubuntu0.1),
12 python-gi-cairo,
13
14=== modified file 'run-tests.sh'
15--- run-tests.sh 2013-07-12 12:51:43 +0000
16+++ run-tests.sh 2016-02-17 13:44:00 +0000
17@@ -4,8 +4,8 @@
18
19 TESTS_DIR="tests"
20
21-dpkg-checkbuilddeps -d 'xvfb, python-mock, python-unittest2,
22- python3-aptdaemon.test, python-lxml, python-qt4'
23+#dpkg-checkbuilddeps -d 'xvfb, python-mock, python-unittest2,
24+# python3-aptdaemon.test, python-lxml, python-qt4'
25
26 if [ ! -e /var/lib/apt-xapian-index/index ]; then
27 echo "please run sudo update-apt-xapian-index"
28
29=== modified file 'softwarecenter/ui/gtk3/dialogs/dialog_tos.py'
30--- softwarecenter/ui/gtk3/dialogs/dialog_tos.py 2014-01-10 10:50:59 +0000
31+++ softwarecenter/ui/gtk3/dialogs/dialog_tos.py 2016-02-17 13:44:00 +0000
32@@ -20,7 +20,7 @@
33 import gi
34 gi.require_version("Gtk", "3.0")
35 from gi.repository import Gtk
36-from gi.repository import WebKit
37+from gi.repository import WebKit2
38
39 from gettext import gettext as _
40
41@@ -33,6 +33,7 @@
42
43 def __init__(self, parent):
44 Gtk.Dialog.__init__(self)
45+ self.failed = False
46 self.set_default_size(420, 400)
47 self.set_transient_for(parent)
48 self.set_title(_("Terms of Use"))
49@@ -57,7 +58,9 @@
50 wb.show_all()
51 self.webkit = wb.webkit
52 self.webkit.connect(
53- "notify::load-status", self._on_load_status_changed)
54+ "load-changed", self._on_load_changed)
55+ self.webkit.connect(
56+ "load-failed", self._on_load_failed)
57 # content
58 content = self.get_content_area()
59 self.spinner = SpinnerNotebook(wb)
60@@ -69,15 +72,17 @@
61 self.webkit.load_uri(SOFTWARE_CENTER_TOS_LINK_NO_HEADER)
62 return Gtk.Dialog.run(self)
63
64- def _on_load_status_changed(self, view, pspec):
65- prop = pspec.name
66- status = view.get_property(prop)
67- if (status == WebKit.LoadStatus.FINISHED or
68- status == WebKit.LoadStatus.FAILED):
69+ def _on_load_failed(self, view, load_event, failing_uri, error):
70+ self.failed = True
71+ return False
72+
73+ def _on_load_changed(self, view, load_event):
74+ if load_event == WebKit2.LoadEvent.FINISHED:
75 self.spinner.hide_spinner()
76- if status == WebKit.LoadStatus.FINISHED:
77- self.label.set_text(_("Do you accept these terms?"))
78- self.button_accept.set_sensitive(True)
79+
80+ if not self.failed:
81+ self.label.set_text(_("Do you accept these terms?"))
82+ self.button_accept.set_sensitive(True)
83
84 if __name__ == "__main__":
85 d = DialogTos(None)
86
87=== modified file 'softwarecenter/ui/gtk3/views/purchaseview.py'
88--- softwarecenter/ui/gtk3/views/purchaseview.py 2012-12-14 16:44:25 +0000
89+++ softwarecenter/ui/gtk3/views/purchaseview.py 2016-02-17 13:44:00 +0000
90@@ -26,7 +26,7 @@
91 import os
92 import json
93
94-from gi.repository import WebKit as webkit
95+from gi.repository import WebKit2 as webkit
96
97 from gettext import gettext as _
98
99@@ -119,21 +119,18 @@
100 self.pack_start(self.wk, True, True, 0)
101 # automatically fill in the email in the login page
102 self.wk.webkit.set_auto_insert_email(self.config.email)
103- #self.wk.webkit.connect("new-window-policy-decision-requested",
104- # self._on_new_window)
105- self.wk.webkit.connect("create-web-view", self._on_create_web_view)
106- self.wk.webkit.connect("close-web-view", self._on_close_web_view)
107- self.wk.webkit.connect("console-message", self._on_console_message)
108+ self.wk.webkit.connect("create", self._on_create_web_view)
109+ self.wk.webkit.connect("close", self._on_close_web_view)
110
111 # check if the user wants url debugging
112 if os.environ.get("SOFTWARE_CENTER_DEBUG_WEBKIT"):
113 self.wk.webkit.connect("notify::uri", self._log_debug_output)
114
115 # a possible way to do IPC (script or title change)
116- self.wk.webkit.connect("script-alert", self._on_script_alert)
117- self.wk.webkit.connect("title-changed", self._on_title_changed)
118- self.wk.webkit.connect("notify::load-status",
119- self._on_load_status_changed)
120+ self.wk.webkit.connect("script-dialog", self._on_script_alert)
121+ self.wk.webkit.connect("notify::title", self._on_title_changed)
122+ self.wk.webkit.connect("load-changed",
123+ self._on_load_changed)
124 # unblock signal handlers if needed when showing the purchase webkit
125 # view in case they were blocked after a previous purchase was
126 # completed or canceled
127@@ -162,7 +159,7 @@
128 self.init_view()
129 self.app = app
130 self.iconname = iconname
131- self.wk.webkit.load_html_string(self.LOADING_HTML, "file:///")
132+ self.wk.webkit.load_html(self.LOADING_HTML, "file:///")
133 self.wk.show()
134 context = GLib.main_context_default()
135 while context.pending():
136@@ -170,32 +167,26 @@
137 if url:
138 self.wk.webkit.load_uri(url)
139 elif html:
140- self.wk.webkit.load_html_string(html, "file:///")
141+ self.wk.webkit.load_html(html, "file:///")
142 else:
143- self.wk.webkit.load_html_string(DUMMY_HTML, "file:///")
144+ self.wk.webkit.load_html(DUMMY_HTML, "file:///")
145 # only for debugging
146 if os.environ.get("SOFTWARE_CENTER_DEBUG_BUY"):
147 GLib.timeout_add_seconds(1, _generate_events, self)
148 return True
149
150- def _on_new_window(self, view, frame, request, action, policy):
151- LOG.debug("_on_new_window")
152- import subprocess
153- subprocess.Popen(['xdg-open', request.get_uri()])
154- return True
155-
156 def _on_close_web_view(self, view):
157 win = view.parent_win
158 win.destroy()
159 return True
160
161- def _on_create_web_view(self, view, frame):
162+ def _on_create_web_view(self, view, action):
163 from softwarecenter.ui.gtk3.widgets.webkit import (
164 ScrolledWebkitWindow)
165 win = Gtk.Window()
166 win.set_size_request(400, 400)
167 wk = ScrolledWebkitWindow(include_progress_ui=True)
168- wk.webkit.connect("close-web-view", self._on_close_web_view)
169+ wk.webkit.connect("close", self._on_close_web_view)
170 win.add(wk)
171 win.show_all()
172 # make sure close will work later
173@@ -207,43 +198,23 @@
174 win.set_transient_for(w)
175 return wk.webkit
176
177- def _on_console_message(self, view, message, line, source_id):
178- try:
179- # load the token from the console message
180- self._oauth_token = json.loads(message)
181- # compat with the regular oauth naming
182- self._oauth_token["token"] = self._oauth_token["token_key"]
183- except ValueError:
184- pass
185- for k in ["token_key", "token_secret", "consumer_secret"]:
186- if k in message:
187- LOG.debug(
188- "skipping console message that contains sensitive data")
189- return True
190- LOG.debug("_on_console_message '%s'" % message)
191- return False
192-
193- def _on_script_alert(self, view, frame, message):
194- self._process_json(message)
195+ def _on_script_alert(self, view, dialog):
196+ self._process_json(dialog.get_message())
197 # stop further processing to avoid actually showing the alter
198 return True
199
200- def _on_title_changed(self, view, frame, title):
201- #print "on_title_changed", view, frame, title
202- # see wkwidget.py _on_title_changed() for a code example
203- self._process_json(title)
204+ def _on_title_changed(self, *args):
205+ self._process_json(self.wk.webkit.title)
206
207- def _on_load_status_changed(self, view, property_spec):
208+ def _on_load_changed(self, view, load_event):
209 """ helper to give visual feedback while the page is loading """
210- prop = view.get_property(property_spec.name)
211 window = self.get_window()
212- if prop == webkit.LoadStatus.PROVISIONAL:
213+ if (load_event == webkit.LoadEvent.STARTED or
214+ load_event == webkit.LoadEvent.COMMITTED):
215 self.emit("purchase-needs-spinner", True)
216 if window:
217 window.set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH))
218- elif (prop == webkit.LoadStatus.FIRST_VISUALLY_NON_EMPTY_LAYOUT or
219- prop == webkit.LoadStatus.FAILED or
220- prop == webkit.LoadStatus.FINISHED):
221+ elif load_event == webkit.LoadEvent.FINISHED:
222 self.emit("purchase-needs-spinner", False)
223 if window:
224 window.set_cursor(None)
225@@ -297,7 +268,7 @@
226 if not self._wk_handlers_blocked:
227 self.wk.webkit.handler_block_by_func(self._on_script_alert)
228 self.wk.webkit.handler_block_by_func(self._on_title_changed)
229- self.wk.webkit.handler_block_by_func(self._on_load_status_changed)
230+ self.wk.webkit.handler_block_by_func(self._on_load_changed)
231 self._wk_handlers_blocked = True
232
233 def _unblock_wk_handlers(self):
234@@ -305,7 +276,7 @@
235 self.wk.webkit.handler_unblock_by_func(self._on_script_alert)
236 self.wk.webkit.handler_unblock_by_func(self._on_title_changed)
237 self.wk.webkit.handler_unblock_by_func(
238- self._on_load_status_changed)
239+ self._on_status_changed)
240 self._wk_handlers_blocked = False
241
242
243
244=== modified file 'softwarecenter/ui/gtk3/widgets/exhibits.py'
245--- softwarecenter/ui/gtk3/widgets/exhibits.py 2015-10-06 16:44:03 +0000
246+++ softwarecenter/ui/gtk3/widgets/exhibits.py 2016-02-17 13:44:00 +0000
247@@ -27,7 +27,7 @@
248 from gi.repository import GLib
249 from gi.repository import GObject
250 from gi.repository import GdkPixbuf
251-from gi.repository import WebKit
252+from gi.repository import WebKit2
253
254 from urlparse import urlparse
255
256@@ -35,6 +35,7 @@
257 from softwarecenter.ui.gtk3.em import StockEms
258 from softwarecenter.ui.gtk3.drawing import rounded_rect
259 from softwarecenter.ui.gtk3.utils import point_in
260+from softwarecenter.ui.gtk3.widgets.webkit import SCWebKit
261 import softwarecenter.paths
262
263 LOG = logging.getLogger(__name__)
264@@ -64,6 +65,7 @@
265 position:absolute;
266 top:100px;
267 left:232px;
268+white-space: nowrap;
269 }
270 </style>
271 </head><body>
272@@ -101,25 +103,15 @@
273 # "cached banners")
274
275
276-class _HtmlRenderer(Gtk.OffscreenWindow):
277-
278- __gsignals__ = {
279- "render-finished": (GObject.SignalFlags.RUN_LAST,
280- None,
281- (),
282- )
283- }
284+class _HtmlRenderer(SCWebKit):
285
286 def __init__(self):
287- Gtk.OffscreenWindow.__init__(self)
288- self.view = WebKit.WebView()
289- settings = self.view.get_settings()
290- settings.set_property("enable-java-applet", False)
291+ super(_HtmlRenderer, self).__init__()
292+ settings = self.get_settings()
293+ settings.set_property("enable-java", False)
294 settings.set_property("enable-plugins", False)
295- settings.set_property("enable-scripts", False)
296- self.view.set_size_request(-1, ExhibitBanner.MAX_HEIGHT)
297- self.add(self.view)
298- self.show_all()
299+ settings.set_property("enable-javascript", False)
300+ self.set_size_request(-1, ExhibitBanner.MAX_HEIGHT)
301 self.loader = SimpleFileDownloader()
302 self.loader.connect("file-download-complete",
303 self._on_one_download_complete)
304@@ -127,8 +119,6 @@
305 self._on_download_error)
306 self.exhibit = None
307 self._downloaded_banner_images = []
308- self.view.connect(
309- "notify::load-status", self._on_internal_renderer_load_status)
310
311 def set_exhibit(self, exhibit):
312 LOG.debug("set_exhibit: '%s'" % exhibit)
313@@ -165,8 +155,7 @@
314 html = html.replace(server_path, image_name)
315 self.exhibit.html = html
316 LOG.debug("mangled html: '%s'" % html)
317- self.view.load_string(html, "text/html", "UTF-8",
318- "file:%s/" % cache_dir)
319+ self.load_html(html, "file:%s/" % cache_dir)
320
321 def _download_next_banner_image(self):
322 LOG.debug("_download_next_banner_image")
323@@ -175,12 +164,6 @@
324 use_cache=True,
325 simple_quoting_for_webkit=True)
326
327- def _on_internal_renderer_load_status(self, view, prop):
328- """Called when the rendering of the html banner is done"""
329- if view.get_property("load-status") == WebKit.LoadStatus.FINISHED:
330- # this needs to run with a timeout because otherwise the
331- # status is emitted before the offscreen image is finished
332- GLib.timeout_add(100, lambda: self.emit("render-finished"))
333
334
335 class ExhibitButton(Gtk.Button):
336@@ -311,7 +294,7 @@
337 self.image = None
338 self.old_image = None
339 self.renderer = _HtmlRenderer()
340- self.renderer.connect("render-finished", self.on_banner_rendered)
341+ self.renderer.connect("load-changed", self.on_load_changed)
342
343 self.set_visible_window(False)
344 self.set_size_request(-1, self.MAX_HEIGHT)
345@@ -449,14 +432,11 @@
346 self.TIMEOUT_SECONDS, self.next_exhibit)
347 return self._timeout
348
349- def on_banner_rendered(self, renderer):
350- self.image = renderer.get_pixbuf()
351-
352- if self.image.get_width() == 1:
353- # the offscreen window is not really as such content not
354- # correctly rendered
355- GLib.timeout_add(500, self.on_banner_rendered, renderer)
356- return
357+ def on_snapshot_created(self, obj, result):
358+ surface = obj.get_snapshot_finish(result)
359+ self.image = Gdk.pixbuf_get_from_surface(surface, 0, 0,
360+ surface.get_width(),
361+ surface.get_height())
362
363 from gi.repository import Atk
364 self.get_accessible().set_name(
365@@ -464,6 +444,26 @@
366 self.get_accessible().set_role(Atk.Role.PUSH_BUTTON)
367 self._fade_in()
368 self.queue_next()
369+
370+ def on_load_changed(self, renderer, load_event):
371+ from gi.repository import WebKit2
372+
373+ if load_event != WebKit2.LoadEvent.FINISHED:
374+ return False
375+
376+ renderer.get_snapshot(WebKit2.SnapshotRegion.FULL_DOCUMENT,
377+ WebKit2.SnapshotOptions.NONE,
378+ None,
379+ self.on_snapshot_created)
380+
381+ return True
382+
383+ if self.image.get_width() == 1:
384+ # the offscreen window is not really as such content not
385+ # correctly rendered
386+ GLib.timeout_add(500, self.on_banner_rendered, renderer)
387+ return
388+
389 return False
390
391 def _fade_in(self, step=0.05):
392
393=== modified file 'softwarecenter/ui/gtk3/widgets/videoplayer.py'
394--- softwarecenter/ui/gtk3/widgets/videoplayer.py 2014-01-10 10:50:59 +0000
395+++ softwarecenter/ui/gtk3/widgets/videoplayer.py 2016-02-17 13:44:00 +0000
396@@ -21,6 +21,7 @@
397
398 from gettext import gettext as _
399 from gi.repository import Gdk
400+from gi.repository import WebKit2
401
402 # FIXME: remove this try/except and add a dependency on gir1.2-gstreamer-0.10
403 # if we (ever) start using VideoPlayerGtk3
404@@ -30,7 +31,8 @@
405 pass
406
407 from gi.repository import Gtk
408-from gi.repository import WebKit
409+
410+from softwarecenter.ui.gtk3.widgets.webkit import SCWebKit
411
412 LOG = logging.getLogger(__name__)
413
414@@ -39,7 +41,7 @@
415 def __init__(self):
416 super(VideoPlayer, self).__init__()
417 self.set_size_request(400, 255)
418- self.webkit = WebKit.WebView()
419+ self.webkit = SCWebKit()
420 settings = self.webkit.get_settings()
421 # this disables the flash and other plugins so that we force html5
422 # video on the system. This is works currently (11/2011) fine with
423@@ -48,25 +50,30 @@
424 settings.set_property("enable-plugins", False)
425 # on navigation/new window etc, just use the proper browser
426 self.webkit.connect(
427- "new-window-policy-decision-requested", self._on_new_window)
428- self.webkit.connect("create-web-view", self._on_create_web_view)
429+ "decide-policy", self._on_decide_policy)
430+ self.webkit.connect("create", self._on_create_web_view)
431 self.pack_start(self.webkit, True, True, 0)
432 self._uri = ""
433
434 # helper required to follow ToS about the "back" link (flash version)
435- def _on_new_window(self, view, frame, request, action, policy):
436- subprocess.Popen(['xdg-open', request.get_uri()])
437- return True
438+ def _on_decide_policy(self, decision, decision_type):
439+ if decision_type == WebKit2.PolicyDecisionType.NEW_WINDOW_ACTION:
440+ request = decision.get_request()
441+ subprocess.Popen(['xdg-open', request.uri])
442+ decision.ignore()
443+ return True
444+
445+ return False
446
447 # helper for the embedded html5 viewer
448- def _on_create_web_view(self, view, frame):
449+ def _on_create_web_view(self, view, action):
450 # mvo: this is not ideal, the trouble is that we do not get the
451 # url that the new view points to until after the view was
452 # created. But we don't want to be a full blow internal
453 # webbrowser so we simply go back to the youtube url here
454 # and the user needs to click "youtube" there again :/
455- uri = frame.get_uri()
456- subprocess.Popen(['xdg-open', uri])
457+ req = action.get_request()
458+ subprocess.Popen(['xdg-open', req.uri])
459
460 # uri property
461 def _set_uri(self, v):
462@@ -75,86 +82,20 @@
463 # only load the uri if it's defined, otherwise we may get:
464 # Program received signal SIGSEGV, Segmentation fault.
465 # webkit_web_frame_load_uri () from /usr/lib/libwebkitgtk-3.0.so.0
466- self.webkit.load_uri(self._uri)
467+ self.webkit.uri = self._uri
468
469 def _get_uri(self):
470 return self._uri
471 uri = property(_get_uri, _set_uri, None, "uri property")
472
473- def load_html_string(self, html):
474+ def load_html(self, html):
475 """ Instead of a video URI use a html embedded video like e.g.
476 youtube or vimeo. Note that on a default install not all
477 video codecs will play (no flash!), so be careful!
478 """
479 # FIXME: add something more useful here
480 base_uri = "http://www.ubuntu.com"
481- self.webkit.load_html_string(html, base_uri)
482+ self.webkit.load_html(html, base_uri)
483
484 def stop(self):
485 self.webkit.load_uri('')
486-
487-
488-# AKA the-segfault-edition-with-no-documentation
489-class VideoPlayerGtk3(Gtk.VBox):
490-
491- def __init__(self):
492- super(VideoPlayerGtk3, self).__init__()
493- self.uri = ""
494- # gtk ui
495- self.movie_window = Gtk.DrawingArea()
496- self.pack_start(self.movie_window, True, True, 0)
497- self.button = Gtk.Button(label=_("Play"))
498- self.pack_start(self.button, False, True, 0)
499- self.button.connect("clicked", self.on_play_clicked)
500- # player
501- self.player = Gst.ElementFactory.make("playbin2", "player")
502- # bus stuff
503- bus = self.player.get_bus()
504- bus.add_signal_watch()
505- bus.enable_sync_message_emission()
506- bus.connect("message", self.on_message)
507- # FIXME: no sync messages currently so no playing in the widget :/
508- # the former appears to be not working anymore with GIR, the
509- # later is not exported (introspectable=0 in the GIR)
510- bus.connect("sync-message", self.on_sync_message)
511- #bus.set_sync_handler(self.on_sync_message)
512-
513- def on_play_clicked(self, button):
514- if self.button.get_label() == _("Play"):
515- self.button.set_label("Stop")
516- print(self.uri)
517- self.player.set_property("uri", self.uri)
518- self.player.set_state(Gst.State.PLAYING)
519- else:
520- self.player.set_state(Gst.State.NULL)
521- self.button.set_label(_("Play"))
522-
523- def on_message(self, bus, message):
524- print("message: %s" % bus, message)
525- if message is None:
526- return
527- t = message.type
528- print(t)
529- if t == Gst.MessageType.EOS:
530- self.player.set_state(Gst.State.NULL)
531- self.button.set_label(_("Play"))
532- elif t == Gst.MessageType.ERROR:
533- self.player.set_state(Gst.State.NULL)
534- err, debug = message.parse_error()
535- LOG.error("Error playing video: %s (%s)" % (err, debug))
536- self.button.set_label(_("Play"))
537-
538- def on_sync_message(self, bus, message):
539- print("sync: %s" % bus, message)
540- if message is None or message.structure is None:
541- return
542- message_name = message.structure.get_name()
543- if message_name == "prepare-xwindow-id":
544- imagesink = message.src
545- imagesink.set_property("force-aspect-ratio", True)
546- Gdk.threads_enter()
547- # FIXME: this is the way to do it, *but* get_xid() is not
548- # exported in the GIR
549- xid = self.player.movie_window.get_window().get_xid()
550- imagesink.set_xwindow_id(xid)
551- Gdk.threads_leave()
552
553=== modified file 'softwarecenter/ui/gtk3/widgets/webkit.py'
554--- softwarecenter/ui/gtk3/widgets/webkit.py 2012-12-14 16:44:25 +0000
555+++ softwarecenter/ui/gtk3/widgets/webkit.py 2016-02-17 13:44:00 +0000
556@@ -20,7 +20,7 @@
557 import logging
558 import os
559
560-from gi.repository import WebKit as webkit
561+from gi.repository import WebKit2 as webkit
562 from gi.repository import Gtk
563 from gi.repository import Pango
564 import urlparse
565@@ -31,48 +31,41 @@
566 from softwarecenter.utils import get_oem_channel_descriptor
567
568 from gi.repository import Soup
569-from gi.repository import WebKit
570
571
572 LOG = logging.getLogger(__name__)
573
574
575-def global_webkit_init():
576- """ this sets the defaults for webkit, its important that this gets
577- run if you want a secure webkit session
578- """
579- session = WebKit.get_default_session()
580- # add security by default (see bugzilla #666280 and #666276)
581- # enable certificates validation in webkit views unless specified otherwise
582- if not "SOFTWARE_CENTER_FORCE_DISABLE_CERTS_CHECK" in os.environ:
583- session = webkit.get_default_session()
584- session.set_property(
585- "ssl-ca-file", "/etc/ssl/certs/ca-certificates.crt")
586- else:
587- # WARN the user!! Do not remove this
588- LOG.warning("SOFTWARE_CENTER_FORCE_DISABLE_CERTS_CHECK " +
589- "has been specified, all purchase transactions " +
590- "are now INSECURE and UNENCRYPTED!!")
591- # cookies by default
592- fname = os.path.join(SOFTWARE_CENTER_CACHE_DIR, "cookies.txt")
593- # clear cookies again in a new session, see #1018347 comment #4
594- # there is no "logout" support right now on any of the USC pages
595- try:
596- os.remove(fname)
597- except OSError:
598- pass
599- cookie_jar = Soup.CookieJarText.new(fname, False)
600- session.add_feature(cookie_jar)
601- # optional session debugging
602- if "SOFTWARE_CENTER_DEBUG_WEBKIT" in os.environ:
603- # alternatively you can use HEADERS, BODY here
604- logger = Soup.Logger.new(Soup.LoggerLogLevel.BODY, -1)
605- logger.attach(session)
606-# ALWAYS run this or get insecurity by default
607-global_webkit_init()
608-
609-
610-class SoftwareCenterWebView(webkit.WebView):
611+class SCWebKit(webkit.WebView):
612+ def __init__(self):
613+ super(SCWebKit, self).__init__()
614+ """ this sets the defaults for webkit, its important that this gets
615+ run if you want a secure webkit session
616+ """
617+ context = self.get_context()
618+
619+ # enable certificates validation in webkit views unless specified otherwise
620+ if "SOFTWARE_CENTER_FORCE_DISABLE_CERTS_CHECK" in os.environ:
621+ context.set_tls_errors_policy(webkit.TLSErrorsPolicy.IGNORE)
622+ # WARN the user!! Do not remove this
623+ LOG.warning("SOFTWARE_CENTER_FORCE_DISABLE_CERTS_CHECK " +
624+ "has been specified, all purchase transactions " +
625+ "are now INSECURE and UNENCRYPTED!!")
626+
627+ # cookies by default
628+ fname = os.path.join(SOFTWARE_CENTER_CACHE_DIR, "cookies.txt")
629+ # clear cookies again in a new session, see #1018347 comment #4
630+ # there is no "logout" support right now on any of the USC pages
631+ try:
632+ os.remove(fname)
633+ except OSError:
634+ pass
635+ cookie_manager = context.get_cookie_manager()
636+ cookie_manager.set_persistent_storage(fname,
637+ webkit.CookiePersistentStorage.TEXT)
638+
639+
640+class SoftwareCenterWebView(SCWebKit):
641 """ A customized version of the regular webview
642
643 It will:
644@@ -91,10 +84,10 @@
645
646 def __init__(self):
647 # actual webkit init
648- webkit.WebView.__init__(self)
649- self.connect("resource-request-starting",
650+ super(SoftwareCenterWebView, self).__init__()
651+ self.connect("resource-load-started",
652 self._on_resource_request_starting)
653- self.connect("notify::load-status",
654+ self.connect("load-changed",
655 self._on_load_status_changed)
656 settings = self.get_settings()
657 settings.set_property("enable-plugins", False)
658@@ -111,29 +104,23 @@
659 user_agent_string += get_oem_channel_descriptor()
660 return user_agent_string
661
662- def _on_resource_request_starting(self, view, frame, res, req, resp):
663+ def _on_resource_request_starting(self, view, res, req):
664 lang = get_language()
665 if lang:
666- message = req.get_message()
667- if message:
668- headers = message.get_property("request-headers")
669+ headers = req.get_http_headers()
670+ if headers:
671 headers.append("Accept-Language", lang)
672- #def _show_header(name, value, data):
673- # print name, value
674- #headers.foreach(_show_header, None)
675
676 def _maybe_auto_fill_in_username(self):
677 uri = self.get_uri()
678 if self._auto_fill_email and uri.startswith(self.AUTO_FILL_SERVER):
679- self.execute_script(
680+ self.run_javascript(
681 self.AUTO_FILL_EMAIL_JS % self._auto_fill_email)
682 # ensure that we have the keyboard focus
683 self.grab_focus()
684
685- def _on_load_status_changed(self, view, pspec):
686- prop = pspec.name
687- status = view.get_property(prop)
688- if status == webkit.LoadStatus.FINISHED:
689+ def _on_load_status_changed(self, view, load_event):
690+ if load_event == webkit.LoadEvent.FINISHED:
691 self._maybe_auto_fill_in_username()
692
693
694@@ -147,12 +134,7 @@
695 if include_progress_ui:
696 self._add_progress_ui()
697 # create main webkitview
698- self.scroll = Gtk.ScrolledWindow()
699- self.scroll.set_policy(Gtk.PolicyType.AUTOMATIC,
700- Gtk.PolicyType.AUTOMATIC)
701- self.pack_start(self.scroll, True, True, 0)
702- # embed the webkit view in a scrolled window
703- self.scroll.add(self.webkit)
704+ self.pack_start(self.webkit, True, True, 0)
705 self.show_all()
706
707 def _add_progress_ui(self):
708@@ -174,7 +156,7 @@
709 self.pack_start(self.frame, False, False, 6)
710 # connect the webkit stuff
711 self.webkit.connect("notify::uri", self._on_uri_changed)
712- self.webkit.connect("notify::load-status",
713+ self.webkit.connect("load-changed",
714 self._on_load_status_changed)
715
716 def _on_uri_changed(self, view, pspec):
717@@ -191,14 +173,10 @@
718 # start spinner when the uri changes
719 #self.spinner.start()
720
721- def _on_load_status_changed(self, view, pspec):
722- prop = pspec.name
723- status = view.get_property(prop)
724- #print status
725- if status == webkit.LoadStatus.PROVISIONAL:
726+ def _on_load_status_changed(self, view, load_event):
727+ if load_event == webkit.LoadEvent.STARTED:
728 self.spinner.start()
729 self.spinner.show()
730- if (status == webkit.LoadStatus.FINISHED or
731- status == webkit.LoadStatus.FAILED):
732+ if load_event == webkit.LoadEvent.FINISHED:
733 self.spinner.stop()
734 self.spinner.hide()
735
736=== modified file 'tests/gtk3/test_purchase.py'
737--- tests/gtk3/test_purchase.py 2012-09-18 06:38:40 +0000
738+++ tests/gtk3/test_purchase.py 2016-02-17 13:44:00 +0000
739@@ -17,30 +17,6 @@
740
741 class TestPurchase(unittest.TestCase):
742
743- def test_purchase_view_log_cleaner(self):
744- win = get_test_window_purchaseview()
745- self.addCleanup(win.destroy)
746- do_events_with_sleep()
747- # get the view
748- view = win.get_data("view")
749- # install the mock
750- purchaseview.LOG = mock = Mock()
751- # run a "harmless" log message and ensure its logged normally
752- view.wk.webkit.execute_script('console.log("foo")')
753- self.assertTrue("foo" in mock.debug.call_args[0][0])
754- mock.reset_mock()
755-
756- # run a message that contains token info
757- s = ('http://sca.razorgirl.info/subscriptions/19077/checkout_complete/'
758- ' @10: {"token_key": "hiddenXXXXXXXXXX", "consumer_secret": '
759- '"hiddenXXXXXXXXXXXX", "api_version": 2.0, "subscription_id": '
760- '19077, "consumer_key": "rKhNPBw", "token_secret": '
761- '"hiddenXXXXXXXXXXXXXXX"}')
762- view.wk.webkit.execute_script("console.log('%s')" % s)
763- self.assertTrue("skipping" in mock.debug.call_args[0][0])
764- self.assertFalse("consumer_secret" in mock.debug.call_args[0][0])
765- mock.reset_mock()
766-
767 def test_purchase_view_tos(self):
768 win = get_test_window_purchaseview()
769 self.addCleanup(win.destroy)
770
771=== modified file 'tests/gtk3/test_webkit.py'
772--- tests/gtk3/test_webkit.py 2012-11-28 15:43:49 +0000
773+++ tests/gtk3/test_webkit.py 2016-02-17 13:44:00 +0000
774@@ -3,7 +3,7 @@
775 from gi.repository import (
776 GLib,
777 Soup,
778- WebKit,
779+ WebKit2,
780 )
781
782 from mock import patch
783@@ -19,19 +19,10 @@
784
785 class TestWebkit(unittest.TestCase):
786
787- def test_have_cookie_jar(self):
788- # ensure we have a cookie jar available
789- session = WebKit.get_default_session()
790- cookie_jars = [feature
791- for feature in session.get_features(Soup.SessionFeature)
792- if isinstance(feature, Soup.CookieJar)]
793- self.assertEqual(len(cookie_jars), 1)
794-
795 def test_user_agent_string(self):
796 webview = SoftwareCenterWebView()
797 settings = webview.get_settings()
798- self.assertTrue(
799- WEBKIT_USER_AGENT_SUFFIX in settings.get_property("user-agent"))
800+ self.assertTrue(WEBKIT_USER_AGENT_SUFFIX in settings.get_user_agent())
801
802 @patch("softwarecenter.ui.gtk3.widgets.webkit.get_oem_channel_descriptor")
803 def test_user_agent_oem_channel_descriptor(self, mock_oem_channel):
804@@ -39,19 +30,18 @@
805 mock_oem_channel.return_value = canary
806 webview = SoftwareCenterWebView()
807 settings = webview.get_settings()
808- self.assertTrue(
809- canary in settings.get_property("user-agent"))
810-
811+ self.assertTrue(canary in settings.get_user_agent())
812+
813 def test_auto_fill_in_email(self):
814 def _load_status_changed(view, status):
815- if view.get_property("load-status") == WebKit.LoadStatus.FINISHED:
816+ if status == WebKit2.LoadEvent.FINISHED:
817 loop.quit()
818- loop = GLib.MainLoop(GLib.main_context_default())
819+ loop = GLib.MainLoop(GLib.main_context_default())
820 webview = SoftwareCenterWebView()
821 email = "foo@bar"
822 webview.set_auto_insert_email(email)
823- with patch.object(webview, "execute_script") as mock_execute_js:
824- webview.connect("notify::load-status", _load_status_changed)
825+ with patch.object(webview, "run_javascript") as mock_execute_js:
826+ webview.connect("load-changed", _load_status_changed)
827 webview.load_uri("https://login.ubuntu.com")
828 loop.run()
829 mock_execute_js.assert_called()
830
831=== modified file 'tests/gtk3/test_widgets.py'
832--- tests/gtk3/test_widgets.py 2012-12-13 16:41:05 +0000
833+++ tests/gtk3/test_widgets.py 2016-02-17 13:44:00 +0000
834@@ -267,7 +267,7 @@
835 self.vp.uri = expected_uri
836
837 self.assertEqual(self.vp.uri, expected_uri)
838- self.assertEqual(self.vp.webkit.get_uri(), self.vp.uri)
839+ self.assertEqual(self.vp.webkit.uri, self.vp.uri)
840
841 def test_stop(self):
842 self.vp.uri = 'http://foo.bar.baz'
843
844=== modified file 'tests/gtk3/windows.py'
845--- tests/gtk3/windows.py 2014-01-13 10:51:30 +0000
846+++ tests/gtk3/windows.py 2016-02-17 13:44:00 +0000
847@@ -1122,10 +1122,7 @@
848 win = get_test_window(child=player, width=500, height=400)
849
850 if video_url is None:
851- #player.uri = "http://upload.wikimedia.org/wikipedia/commons/9/9b/" \
852- # "Pentagon_News_Sample.ogg"
853- #player.uri = "http://people.canonical.com/~mvo/totem.html"
854- player.load_html_string(html_vimeo)
855+ player.load_html(html_vimeo)
856 else:
857 player.uri = video_url
858