Skip to content

Commit

Permalink
Handle flatpak+https scheme (#170)
Browse files Browse the repository at this point in the history
  • Loading branch information
meisenzahl authored Jul 31, 2024
1 parent 2037062 commit 96e57ff
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 72 deletions.
2 changes: 1 addition & 1 deletion data/sideload.desktop.in
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ Type=Application
StartupNotify=true
Categories=PackageManager;
NoDisplay=true
MimeType=application/vnd.flatpak.ref;application/vnd.flatpak;
MimeType=application/vnd.flatpak.ref;application/vnd.flatpak;x-scheme-handler/flatpak+https;
X-GNOME-UsesNotifications=true
53 changes: 4 additions & 49 deletions src/Application.vala
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,6 @@
*/

public class Sideload.Application : Gtk.Application {
private const string BUNDLE_CONTENT_TYPE = "application/vnd.flatpak";
private const string REF_CONTENT_TYPE = "application/vnd.flatpak.ref";
private const string[] SUPPORTED_CONTENT_TYPES = {
BUNDLE_CONTENT_TYPE,
REF_CONTENT_TYPE
};

public Application () {
GLib.Intl.setlocale (LocaleCategory.ALL, "");
GLib.Intl.bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
Expand Down Expand Up @@ -54,56 +47,18 @@ public class Sideload.Application : Gtk.Application {
}

private async void open_file (File file) {
FileInfo? file_info = null;
try {
file_info = yield file.query_info_async (
FileAttribute.STANDARD_CONTENT_TYPE,
FileQueryInfoFlags.NONE
);
} catch (Error e) {
critical ("Unable to query content type of provided file: %s", e.message);
release ();
return;
}

if (file_info == null) {
warning ("Unable to query content type of provided file");
release ();
return;
}

var content_type = file_info.get_attribute_as_string (FileAttribute.STANDARD_CONTENT_TYPE);
if (content_type == null) {
warning ("Unable to query content type of provided file");
release ();
return;
}

if (!(content_type in SUPPORTED_CONTENT_TYPES)) {
warning ("This does not appear to be a valid flatpak/flatpakref file");
release ();
return;
}

Gtk.ApplicationWindow main_window = null;
FlatpakFile flatpak_file = null;

if (content_type == REF_CONTENT_TYPE) {
flatpak_file = new FlatpakRefFile (file);
} else if (content_type == BUNDLE_CONTENT_TYPE) {
flatpak_file = new FlatpakBundleFile (file);
}
Sideload.MainWindow main_window = null;

main_window = new MainWindow (this, flatpak_file);
main_window = new MainWindow (this, file);
main_window.present ();

var launch_action = new SimpleAction ("launch", null);

add_action (launch_action);

launch_action.activate.connect (() => {
flatpak_file.launch.begin ((obj, res) => {
flatpak_file.launch.end (res);
main_window.flatpak_file.launch.begin ((obj, res) => {
main_window.flatpak_file.launch.end (res);
main_window.close ();
});
});
Expand Down
127 changes: 106 additions & 21 deletions src/MainWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,17 @@
*/

public class Sideload.MainWindow : Gtk.ApplicationWindow {
public FlatpakFile file { get; construct; }
private const string BUNDLE_CONTENT_TYPE = "application/vnd.flatpak";
private const string REF_CONTENT_TYPE = "application/vnd.flatpak.ref";
private const string FLATPAK_HTTPS_CONTENT_TYPE = "x-scheme-handler/flatpak+https";
private const string[] SUPPORTED_CONTENT_TYPES = {
BUNDLE_CONTENT_TYPE,
REF_CONTENT_TYPE,
FLATPAK_HTTPS_CONTENT_TYPE
};

public File file { get; construct; }
public FlatpakFile flatpak_file { get; construct; }
private Cancellable? current_cancellable = null;

private Gtk.Stack stack;
Expand All @@ -29,7 +39,7 @@ public class Sideload.MainWindow : Gtk.ApplicationWindow {
private string? app_name = null;
private string? app_id = null;

public MainWindow (Gtk.Application application, FlatpakFile file) {
public MainWindow (Gtk.Application application, File file) {
Object (
application: application,
icon_name: "io.elementary.sideload",
Expand Down Expand Up @@ -75,35 +85,110 @@ public class Sideload.MainWindow : Gtk.ApplicationWindow {
}
});

if (file.size == "0") {
var error_view = new ErrorView (file.error_code, file.error_message);
if (file.get_uri ().has_prefix ("flatpak+https://")) {
var uri = file.get_uri ().replace ("flatpak+https://", "https://");
var path = Path.build_filename (
Environment.get_user_special_dir (UserDirectory.DOWNLOAD),
Path.get_basename (uri)
);

var remote_file = File.new_for_uri (uri);
var local_file = File.new_for_path (path);
try {
if (!remote_file.copy (local_file, FileCopyFlags.OVERWRITE)) {
var message = (_("Failed to download file from %s")).printf (uri);
var error_view = new ErrorView (-1, message);
stack.add_child (error_view);
stack.visible_child = error_view;
return;
}
} catch (Error e) {
var message = (_("Failed to download file from %s: %s")).printf (uri, e.message);
var error_view = new ErrorView (-1, message);
stack.add_child (error_view);
stack.visible_child = error_view;
return;
}

file = local_file;
}

FileInfo? file_info = null;
try {
file_info = file.query_info (
FileAttribute.STANDARD_CONTENT_TYPE,
FileQueryInfoFlags.NONE
);
} catch (Error e) {
var message = (_("Unable to query content type of provided file: %s")).printf (e.message);
var error_view = new ErrorView (-1, message);
stack.add_child (error_view);
stack.visible_child = error_view;
return;
}

if (file_info == null) {
var message = _("Unable to query content type of provided file");
var error_view = new ErrorView (-1, message);
stack.add_child (error_view);
stack.visible_child = error_view;
return;
}

var content_type = file_info.get_attribute_as_string (FileAttribute.STANDARD_CONTENT_TYPE);
if (content_type == null) {
var message = _("Unable to query content type of provided file");
var error_view = new ErrorView (-1, message);
stack.add_child (error_view);
stack.visible_child = error_view;
return;
}

if (!(content_type in SUPPORTED_CONTENT_TYPES)) {
var message = _("This does not appear to be a valid flatpak/flatpakref file");
var error_view = new ErrorView (-1, message);
stack.add_child (error_view);
stack.visible_child = error_view;
return;
}

if (content_type == REF_CONTENT_TYPE) {
flatpak_file = new FlatpakRefFile (file);
} else if (content_type == BUNDLE_CONTENT_TYPE) {
flatpak_file = new FlatpakBundleFile (file);
} else if (content_type == FLATPAK_HTTPS_CONTENT_TYPE) {
flatpak_file = new FlatpakRefFile (file);
}

if (flatpak_file.size == "0") {
var error_view = new ErrorView (flatpak_file.error_code, flatpak_file.error_message);
stack.add_child (error_view);
stack.visible_child = error_view;
return;
} else if (file is FlatpakRefFile) {
} else if (flatpak_file is FlatpakRefFile) {
progress_view = new ProgressView (ProgressView.ProgressType.REF_INSTALL);
} else {
progress_view = new ProgressView (ProgressView.ProgressType.BUNDLE_INSTALL);
progress_view.status = (_("Installing %s. Unable to estimate time remaining.")).printf (file.size);
progress_view.status = (_("Installing %s. Unable to estimate time remaining.")).printf (flatpak_file.size);
}

stack.add_child (progress_view);

main_view.install_request.connect (on_install_button_clicked);
file.progress_changed.connect (on_progress_changed);
file.installation_failed.connect (on_install_failed);
file.installation_succeeded.connect (on_install_succeeded);
file.details_ready.connect (() => {
if (file.already_installed) {
flatpak_file.progress_changed.connect (on_progress_changed);
flatpak_file.installation_failed.connect (on_install_failed);
flatpak_file.installation_succeeded.connect (on_install_succeeded);
flatpak_file.details_ready.connect (() => {
if (flatpak_file.already_installed) {
var success_view = new SuccessView (app_name, SuccessView.SuccessType.ALREADY_INSTALLED);

stack.add_child (success_view);
stack.visible_child = success_view;
} else {
if (file is FlatpakRefFile) {
main_view.display_ref_details (file.size, file.extra_remotes_needed, file.permissions_flags);
if (flatpak_file is FlatpakRefFile) {
main_view.display_ref_details (flatpak_file.size, flatpak_file.extra_remotes_needed, flatpak_file.permissions_flags);
} else {
main_view.display_bundle_details (file.size, ((FlatpakBundleFile) file).has_remote, file.extra_remotes_needed);
main_view.display_bundle_details (flatpak_file.size, ((FlatpakBundleFile) file).has_remote, flatpak_file.extra_remotes_needed);
}
}
});
Expand All @@ -112,9 +197,9 @@ public class Sideload.MainWindow : Gtk.ApplicationWindow {
}

private async void get_details () {
yield file.get_details ();
app_name = yield file.get_name ();
app_id = yield file.get_id ();
yield flatpak_file.get_details ();
app_name = yield flatpak_file.get_name ();
app_id = yield flatpak_file.get_id ();

if (app_name != null) {
progress_view.app_name = app_name;
Expand All @@ -124,10 +209,10 @@ public class Sideload.MainWindow : Gtk.ApplicationWindow {

private void on_install_button_clicked () {
current_cancellable = new Cancellable ();
file.install.begin (current_cancellable);
flatpak_file.install.begin (current_cancellable);
stack.visible_child = progress_view;

if (file is FlatpakRefFile) {
if (flatpak_file is FlatpakRefFile) {
Granite.Services.Application.set_progress_visible.begin (true);
}
}
Expand Down Expand Up @@ -158,7 +243,7 @@ public class Sideload.MainWindow : Gtk.ApplicationWindow {
break;
}

if (file is FlatpakRefFile) {
if (flatpak_file is FlatpakRefFile) {
Granite.Services.Application.set_progress_visible.begin (false);
}
}
Expand All @@ -169,7 +254,7 @@ public class Sideload.MainWindow : Gtk.ApplicationWindow {
stack.add_child (success_view);
stack.visible_child = success_view;

if (file is FlatpakRefFile) {
if (flatpak_file is FlatpakRefFile) {
Granite.Services.Application.set_progress_visible.begin (false);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Views/SuccessView.vala
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class Sideload.SuccessView : AbstractView {

var app = (Sideload.Application) GLib.Application.get_default ();
var appstore_name = app.get_appstore_name ();
var file = ((Sideload.MainWindow) app.active_window).file;
var file = ((Sideload.MainWindow) app.active_window).flatpak_file;
string? secondary_label_string;

if (view_type == SuccessType.INSTALLED) {
Expand Down

0 comments on commit 96e57ff

Please sign in to comment.