[polari] thumbnailer: Add helper script
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [polari] thumbnailer: Add helper script
- Date: Wed, 18 Dec 2019 01:41:04 +0000 (UTC)
commit df44fb0d332a26721b86ad0305379bb3c6dc1ff3
Author: daronion <stefanosdimos 98 gmail com>
Date: Mon Aug 26 17:44:41 2019 +0300
thumbnailer: Add helper script
We want to handle all types of URL content which means we will
actually have to load the web page and take a snapshot of it.
Embedding a web browser inside Polari isn't great for either
performance or security, so implement the functionality in a
separate script that can run from the main process.
https://gitlab.gnome.org/GNOME/polari/issues/58
src/meson.build | 2 +
src/thumbnailer.js | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 119 insertions(+)
---
diff --git a/src/meson.build b/src/meson.build
index 1a30e3e..0d63989 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -110,3 +110,5 @@ gnome.generate_gir(libpolari,
)
subdir('tests')
+
+install_data('thumbnailer.js', install_dir: pkgdatadir)
diff --git a/src/thumbnailer.js b/src/thumbnailer.js
new file mode 100644
index 0000000..3640280
--- /dev/null
+++ b/src/thumbnailer.js
@@ -0,0 +1,117 @@
+imports.gi.versions.Gtk = '3.0';
+
+const { GLib, GObject, Gtk, WebKit2 } = imports.gi;
+const Cairo = imports.cairo;
+
+const PREVIEW_WIDTH = 120;
+const PREVIEW_HEIGHT = 90;
+
+let PreviewWindow = GObject.registerClass({
+ Properties: {
+ 'uri': GObject.ParamSpec.string(
+ 'uri', 'uri', 'uri',
+ GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
+ null),
+ },
+ Signals: {
+ 'snapshot-ready': {},
+ },
+}, class PreviewWindow extends Gtk.Window {
+ _init(params) {
+ this._snapshot = null;
+
+ super._init(params);
+
+ this._view = new WebKit2.WebView({
+ is_ephemeral: true,
+ visible: true,
+ });
+ this.add(this._view);
+
+ this._view.connect('notify::is-loading',
+ this._onLoadingChanged.bind(this));
+ this._view.load_uri(this.uri);
+ }
+
+ _onLoadingChanged() {
+ if (this._view.is_loading)
+ return;
+
+ /* Hopefully wait long enough for a meaningful snapshot,
+ see https://bugs.webkit.org/show_bug.cgi?id=164180 */
+ GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1000, () => {
+ this._createSnapshot();
+ return GLib.SOURCE_REMOVE;
+ });
+ }
+
+ _createSnapshot() {
+ this._view.get_snapshot(
+ WebKit2.SnapshotRegion.VISIBLE,
+ WebKit2.SnapshotOptions.TRANSPARENT_BACKGROUND,
+ null,
+ (o, res) => {
+ try {
+ this._snapshot = this._view.get_snapshot_finish(res);
+ } catch (e) {
+ log(`Creating snapshot failed: ${e}`);
+ }
+ this.emit('snapshot-ready');
+ });
+ }
+
+ getSnapshot() {
+ return this._snapshot;
+ }
+});
+
+class App {
+ constructor(url, filename) {
+ this._uri = url;
+ this._filename = filename;
+ }
+
+ run() {
+ Gtk.init(null);
+
+ let window = new PreviewWindow({
+ uri: this._uri,
+ default_width: 10 * PREVIEW_WIDTH,
+ default_height: 10 * PREVIEW_HEIGHT,
+ });
+
+ window.realize();
+ window.connect('snapshot-ready', this._onSnapshotReady.bind(this));
+ window.connect('destroy', () => Gtk.main_quit());
+
+ Gtk.main();
+ }
+
+ _onSnapshotReady(window) {
+ let surface = window.getSnapshot();
+ window.destroy();
+
+ if (!surface)
+ return;
+
+ let sourceWidth = surface.getWidth();
+ let sourceHeight = surface.getHeight();
+
+ let target = new Cairo.ImageSurface(Cairo.Format.ARGB32,
+ PREVIEW_WIDTH,
+ PREVIEW_HEIGHT);
+
+ let cr = new Cairo.Context(target);
+ cr.scale(
+ PREVIEW_WIDTH / sourceWidth,
+ PREVIEW_HEIGHT / sourceHeight);
+ cr.setSourceSurface(surface, 0, 0);
+ cr.paint();
+
+ target.writeToPNG(this._filename);
+ }
+}
+
+let [url, filename] = ARGV;
+let app = new App(url, filename);
+app.run();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]