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

Proposed by Iain Lane on 2015-07-14
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 on 2016-02-17
software-store-developers 2015-07-14 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.
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 on 2016-02-17
3325. By dobey on 2015-12-18

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

3326. By Sebastien Bacher on 2015-12-18

Remove use of deprecated n_row property.

3327. By Sebastien Bacher on 2015-12-18

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

3328. By Michael Vogt on 2015-12-18

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

3329. By Sebastien Bacher on 2015-12-18

Clear some source ID warnings.

3330. By Sebastien Bacher on 2015-12-18

Restore the GtkStyle context in the button widget.

3331. By Sebastien Bacher on 2015-12-18

Remove gwibber usage.

3332. By Sebastien Bacher on 2015-12-18

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

3333. By dobey on 2015-12-18

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

3334. By Barry Warsaw on 2015-12-18

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

3335. By Iain Lane on 2015-12-18

Open cataloged_times.p as bytes for py3 compatibility.

3336. By Michael Vogt on 2015-12-18

Disable paste when search entry not visible.

3337. By Bruce Pieterse on 2016-01-06

Update README to mentione python3-aptdaemon.test instead.

3338. By Bruce Pieterse on 2016-01-06

Added support for Adwaita Dark Theme Variant.

3339. By dobey on 2016-01-07

Merge the debian tree in for CI train landing support.

3340. By dobey on 2016-01-07

Prepare the release.

3341. By CI Train Bot Account on 2016-01-07

Releasing 16.01+16.04.20160107.1

3342. By Iain Lane on 2016-01-19

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

3343. By CI Train Bot Account on 2016-01-19

Releasing 16.01+16.04.20160119

3344. By Iain Lane on 2016-02-17

Merge with trunk again

Iain Lane (laney) wrote :

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

review: Approve
dobey (dobey) wrote :

Can you answer mpt's questions?

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> ]

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