Skip to content

Commit

Permalink
daemon/screenshot: Support uploading to web services
Browse files Browse the repository at this point in the history
Resolves BuddiesOfBudgie#281.

Initially support imgur, imagebin and 0x0. Based on cybre's
screen shotshot applet but ported to libsoup3.
  • Loading branch information
joebonrichie committed Feb 20, 2023
1 parent e5908ec commit 96a54ac
Show file tree
Hide file tree
Showing 5 changed files with 411 additions and 4 deletions.
2 changes: 2 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ dep_gtk3 = dependency('gtk+-3.0', version: '>= 3.24.0')
dep_glib = dependency('glib-2.0', version: '>= 2.64.0')
dep_gee = dependency('gee-0.8', version: '>= 0.20.0')
dep_giounix = dependency('gio-unix-2.0', version: '>= 2.64.0')
dep_jsonglib = dependency('json-glib-1.0', version: '>= 1.6.6')
dep_peas = dependency('libpeas-1.0', version: '>= 1.26.0')
dep_soup3 = dependency('libsoup-3.0', version: '>= 3.2.0')
dep_gdkx11 = dependency('gdk-x11-3.0', version: '>= 3.24.0')
dep_libuuid = dependency('uuid')
dep_vala = dependency('vapigen', version: '>= 0.52.5')
Expand Down
12 changes: 12 additions & 0 deletions src/daemon/icons/cloud-upload.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/daemon/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ daemon_sources = [
'notifications/dbus.vala',
'notifications/popup.vala',
'screenshot.vala',
'screenshot_uploader.vala',
'main.vala',
'manager.vala',
'menus.vala',
Expand All @@ -43,10 +44,12 @@ daemon_deps = [
dep_giounix,
dep_gtk3,
dep_gdkx11,
dep_jsonglib,
dep_notify,
dep_wnck,
dep_gst,
dep_cairo,
dep_soup3,
link_libbudgieprivate,
libpanelplugin_vapi,
link_libappsys,
Expand Down Expand Up @@ -84,6 +87,8 @@ executable(
'--pkg', 'gio-unix-2.0',
'--pkg', 'gtk+-3.0',
'--pkg', 'gdk-x11-3.0',
'--pkg', 'json-glib-1.0',
'--pkg', 'libsoup-3.0',
'--pkg', 'libwnck-3.0',
# Make gresource work
'--target-glib=2.38',
Expand Down
116 changes: 112 additions & 4 deletions src/daemon/screenshot.vala
Original file line number Diff line number Diff line change
Expand Up @@ -826,8 +826,6 @@ namespace BudgieScr {
if (pixfile.query_exists()) {
try {
Pixbuf pxb = new Gdk.Pixbuf.from_file(windowstate.tempfile_path);
delete_file(pixfile);

return pxb;
} catch (Error e) {
message("unable to load image from /tmp\n");
Expand All @@ -850,6 +848,12 @@ namespace BudgieScr {
} else {
makeaftershotwindow(pxb);
}
this.destroy.connect(() => {
var file = File.new_for_path(windowstate.tempfile_path);
if (file.query_exists() == true) {
delete_file(file);
}
});
}

private void makeaftershotwindow(Pixbuf pxb) {
Expand Down Expand Up @@ -898,13 +902,15 @@ namespace BudgieScr {
_("Cancel screenshot"),
_("Save screenshot to the selected directory"),
_("Copy screenshot to the clipboard"),
_("Open screenshot in default application")
_("Open screenshot in default application"),
_("Upload screenshot to a web service")
};
string[] header_imagenames = {
"trash-shot-symbolic",
"save-shot-symbolic",
"clipboard-shot-symbolic",
"edit-shot-symbolic"
"edit-shot-symbolic",
"emblem-shared-symbolic"
};

int currbutton = 0;
Expand Down Expand Up @@ -975,10 +981,93 @@ namespace BudgieScr {
}
});

// upload to web service
decisionbuttons[4].clicked.connect(() => {
var path = save_tmp_jpeg_file(pxb);
make_providers_popover(decisionbuttons[4], clp, path);
});

this.set_titlebar(bar);
this.show_all();
}

// Creates a popover menu where the screenshot can be uploaded to a web provider
private Gtk.Popover make_providers_popover(Gtk.Button button, Clipboard clp, string imagepath) {
var padding = 5;

// Menu popover on share btn click
var providerspopover = new Gtk.Popover(button);
providerspopover.set_position(Gtk.PositionType.BOTTOM);
// Master container for all other boxes
var containerbox = new Gtk.Box(Gtk.Orientation.VERTICAL, padding);
// Box for selecting a web provider and uploading to it
var providersbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL, padding);
// Box to display uploaded URLs
var urlsbox = new Gtk.Box(Gtk.Orientation.VERTICAL, padding);

containerbox.pack_start(providersbox, false, false, padding);
containerbox.add(urlsbox);
providerspopover.add(containerbox);

var providerslabel = new Gtk.Label("Provider:");
providersbox.pack_start(providerslabel, true, false, padding);

// Populate combobox with providers
var combobox = new Gtk.ComboBoxText();
foreach (var p in Uploader.provider) {
combobox.append_text(Uploader.provider_string_to_display(p));
}
combobox.set_active(0);
// Initialize provider from idx 0
string chosenprovider = combobox.get_active_text();
combobox.changed.connect(() => {
chosenprovider = combobox.get_active_text();
});
providersbox.add(combobox);

// Create upload button
var uploadbutton = new Gtk.Button();
var uploadicon = new ThemedIcon(name = "cloud-upload");
var uploadimage = new Gtk.Image.from_gicon(uploadicon,Gtk.IconSize.DND);
uploadimage.pixel_size = 16;
uploadimage.margin_start = padding;
uploadimage.margin_end = padding;
uploadbutton.add(uploadimage);
uploadbutton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
providersbox.pack_end(uploadbutton, false, false, padding);

// Upload to provider on clicked
uploadbutton.clicked.connect(() => {
string? link = null;
bool status = false;
status = Uploader.upload_to_provider(chosenprovider, imagepath, out link);

if (link == null || status == false) {
var failed_label = new Gtk.Label("Failed to get a response");
urlsbox.add(failed_label);
warning("Failed to get response from provider: %s\n", chosenprovider);
}
if (link != null) {
clp.set_text(link, link.length);
// TODO: Save the URLs for later incase popover is destroyed
var link_btn = new Gtk.LinkButton.with_label(link, link);
urlsbox.add(link_btn);
providerspopover.show_all();
}
});

providerspopover.show_all();

this.destroy.connect(() => {
var file = File.new_for_path(imagepath);
if (file.query_exists() == true) {
delete_file(file);
}
});

return providerspopover;
}

private void open_indefaultapp(string path) {
File file = File.new_for_path(path);
if (file.query_exists()) {
Expand Down Expand Up @@ -1008,6 +1097,25 @@ namespace BudgieScr {
return now.format(@"Snapshot_%F_%H-%M-%S.$extension");
}

// Convert pixbuf to a slightly compressed jpeg for uploading to a web service
private string save_tmp_jpeg_file(Pixbuf pxb) {
var extension = "jpeg";
var username = Environment.get_user_name();
var tmpdir = Environment.get_tmp_dir();
var tempfile_path = GLib.Path.build_path(GLib.Path.DIR_SEPARATOR_S, tmpdir, username + "_budgiescreenshot_tempfile." + extension);

string[] option_keys = {"quality"};
string[] option_values = {"85"};

try {
pxb.savev(tempfile_path, extension, option_keys, option_values);
} catch (Error e) {
warning("save_tmp_jpeg_file failed, reason: %s\n", e.message);
return "fail";
}
return tempfile_path;
}

private string save_tofile(Gtk.Entry entry, ComboBox combo, Pixbuf pxb) {
string? found_dir = get_path_fromcombo(combo);
string fname = entry.get_text();
Expand Down
Loading

0 comments on commit 96a54ac

Please sign in to comment.