From 280dc29c9b8fea24396c1550d16bce9f5b9af495 Mon Sep 17 00:00:00 2001
From: Nico Alt <nicoalt@posteo.org>
Date: Wed, 10 Jun 2020 05:00:05 +0000
Subject: [PATCH] Add support for non-flatpak installations

Briar GTK now searches for the Briar Headless JAR at three places:
* _/app/share/java/briar-headless.jar_
* _/usr/share/java/briar-headless.jar_
* _~/.local/share/java/briar-headless.jar_
---
 README.md                                     |  3 +-
 app.briar.gtk.json                            |  4 +-
 briar-gtk/briar_gtk/application.py            |  4 +-
 briar-gtk/briar_gtk/define.py                 | 22 ++++++++-
 briar-gtk/tests/briar_gtk/test_application.py | 10 +++-
 briar-gtk/tests/briar_gtk/test_container.py   |  8 ++++
 briar-gtk/tests/briar_gtk/test_define.py      | 48 +++++++++++++++++++
 briar-gtk/tests/briar_gtk/test_window.py      |  8 ++++
 briar-gtk/tests/conftest.py                   |  7 +++
 9 files changed, 107 insertions(+), 7 deletions(-)
 create mode 100644 briar-gtk/tests/briar_gtk/test_define.py

diff --git a/README.md b/README.md
index 6c67d7e..ec38835 100644
--- a/README.md
+++ b/README.md
@@ -91,7 +91,8 @@ pip3 install -r requirements.txt
 You also need to build
 [Briar Headless](https://code.briarproject.org/briar/briar/-/tree/master/briar-headless).
 Check its readme to learn how to do it. You can also use
-[builds provided by Nico Alt](https://media.dorfbrunnen.eu/briar/).
+[builds provided by Nico Alt](https://media.dorfbrunnen.eu/briar/)
+and put the .jar file at _~/.local/share/java/briar-headless.jar_.
 Make sure to have _java_ (e.g. `openjdk-11-jdk`) installed.
 
 Once you've done this, change the path to the Briar headless
diff --git a/app.briar.gtk.json b/app.briar.gtk.json
index 1568c2a..831bd84 100644
--- a/app.briar.gtk.json
+++ b/app.briar.gtk.json
@@ -107,8 +107,8 @@
             "name": "briar-headless",
             "buildsystem": "simple",
             "build-commands": [
-                "mkdir -p /app/briar",
-                "install -Dm644 briar-headless.jar /app/briar/briar-headless.jar"
+                "mkdir -p /app/share/java",
+                "install -Dm644 briar-headless.jar /app/share/java/briar-headless.jar"
             ],
             "sources": [
                 {
diff --git a/briar-gtk/briar_gtk/application.py b/briar-gtk/briar_gtk/application.py
index 1dc959d..76040bd 100644
--- a/briar-gtk/briar_gtk/application.py
+++ b/briar-gtk/briar_gtk/application.py
@@ -16,7 +16,7 @@ from briar_wrapper.api import Api
 
 from briar_gtk.actions.application import ApplicationActions
 from briar_gtk.define import APPLICATION_ID, APPLICATION_NAME
-from briar_gtk.define import APPLICATION_STYLING_PATH, BRIAR_HEADLESS_JAR
+from briar_gtk.define import APPLICATION_STYLING_PATH, get_briar_headless_jar
 from briar_gtk.window import Window
 
 
@@ -61,7 +61,7 @@ class Application(Gtk.Application):
                                               Gtk.STYLE_PROVIDER_PRIORITY_USER)
 
     def _setup_api(self):
-        self.api = Api(BRIAR_HEADLESS_JAR)
+        self.api = Api(get_briar_headless_jar())
 
     # pylint: disable=access-member-before-definition
     def _setup_window(self):
diff --git a/briar-gtk/briar_gtk/define.py b/briar-gtk/briar_gtk/define.py
index 5a9811a..6b323f6 100644
--- a/briar-gtk/briar_gtk/define.py
+++ b/briar-gtk/briar_gtk/define.py
@@ -7,6 +7,7 @@
 # https://gitlab.gnome.org/World/lollypop/blob/1.0.2/lollypop/define.py
 
 import os
+import pathlib
 
 from gi.repository import Gio
 
@@ -14,6 +15,25 @@ APPLICATION_ID = "app.briar.gtk"
 APPLICATION_NAME = "Briar"
 RESOURCES_DIR = os.path.join("/app", "briar", "gtk")
 APPLICATION_STYLING_PATH = "resource:///app/briar/gtk/application.css"
-BRIAR_HEADLESS_JAR = os.path.join("/app", "briar", "briar-headless.jar")
 
 APP = Gio.Application.get_default
+
+
+def get_briar_headless_jar():
+    flatpak_path = "/app/share/java/briar-headless.jar"
+    if os.path.isfile(flatpak_path):
+        return flatpak_path
+
+    debian_path = "/usr/share/java/briar-headless.jar"
+    if os.path.isfile(debian_path):
+        return debian_path
+
+    local_path = os.path.join(
+        pathlib.Path.home(),
+        ".local", "share", "java",
+        "briar-headless.jar"
+    )
+    if os.path.isfile(local_path):
+        return local_path
+
+    raise FileNotFoundError("Couldn't find briar-headless.jar")
diff --git a/briar-gtk/tests/briar_gtk/test_application.py b/briar-gtk/tests/briar_gtk/test_application.py
index b19cbec..63eab47 100644
--- a/briar-gtk/tests/briar_gtk/test_application.py
+++ b/briar-gtk/tests/briar_gtk/test_application.py
@@ -35,7 +35,7 @@ def test_api_at_startup(mocker):
 
     Application().do_startup()
 
-    api_mock.assert_called_once_with("/app/briar/briar-headless.jar")
+    api_mock.assert_called_once_with("/app/share/java/briar-headless.jar")
 
 
 def test_css_provider_at_startup(mocker):
@@ -117,6 +117,14 @@ def test_window_hide_at_shutdown(mocker):
     window_mock.hide.assert_called_once()
 
 
+@pytest.fixture(autouse=True)
+def briar_headless_jar(is_file):
+    flatpak_path = "/app/share/java/briar-headless.jar"
+    return_values = {flatpak_path: True}
+    is_file.side_effect = return_values.get
+    return is_file
+
+
 @pytest.fixture(autouse=True)
 def gi_dependencies(mocker):
     gi_dependencies = ('Gdk', 'Gio', 'GLib', 'Gtk', 'Handy')
diff --git a/briar-gtk/tests/briar_gtk/test_container.py b/briar-gtk/tests/briar_gtk/test_container.py
index 853f7dd..8a28b7d 100644
--- a/briar-gtk/tests/briar_gtk/test_container.py
+++ b/briar-gtk/tests/briar_gtk/test_container.py
@@ -21,6 +21,14 @@ def test_builder_at_init(mocker):
     builder_mock.assert_called_once()
 
 
+@pytest.fixture(autouse=True)
+def briar_headless_jar(is_file):
+    flatpak_path = "/app/share/java/briar-headless.jar"
+    return_values = {flatpak_path: True}
+    is_file.side_effect = return_values.get
+    return is_file
+
+
 @pytest.fixture(autouse=True)
 def gi_dependencies(mocker):
     mocker.patch(MODULE % "Gtk")
diff --git a/briar-gtk/tests/briar_gtk/test_define.py b/briar-gtk/tests/briar_gtk/test_define.py
new file mode 100644
index 0000000..8312316
--- /dev/null
+++ b/briar-gtk/tests/briar_gtk/test_define.py
@@ -0,0 +1,48 @@
+# Copyright (c) 2020 Nico Alt
+# SPDX-License-Identifier: AGPL-3.0-only
+# License-Filename: LICENSE.md
+
+import pytest
+
+from briar_gtk.define import get_briar_headless_jar
+
+
+def test_headless_flatpak_path(is_file):
+    flatpak_path = "/app/share/java/briar-headless.jar"
+    return_values = {flatpak_path: True}
+    is_file.side_effect = return_values.get
+
+    assert get_briar_headless_jar() == flatpak_path
+    is_file.assert_called_once_with(flatpak_path)
+
+
+def test_headless_debian_path(is_file):
+    debian_path = "/usr/share/java/briar-headless.jar"
+    return_values = {debian_path: True}
+    is_file.side_effect = return_values.get
+
+    assert get_briar_headless_jar() == debian_path
+    is_file.assert_called_with(debian_path)
+
+
+def test_headless_local_path(is_file, mocker):
+    local_path = "/home/alice/.local/share/java/briar-headless.jar"
+
+    home_mock = mocker.patch('pathlib.Path.home')
+    home_mock.return_value = "/home/alice"
+
+    return_values = {local_path: True}
+    is_file.side_effect = return_values.get
+
+    assert get_briar_headless_jar() == local_path
+    is_file.assert_called_with(local_path)
+
+
+def test_headless_no_path(is_file):
+    is_file.return_value = False
+
+    with pytest.raises(FileNotFoundError,
+                       match="Couldn't find briar-headless.jar"):
+        get_briar_headless_jar()
+
+    assert is_file.called is True
diff --git a/briar-gtk/tests/briar_gtk/test_window.py b/briar-gtk/tests/briar_gtk/test_window.py
index 4cef637..157ca23 100644
--- a/briar-gtk/tests/briar_gtk/test_window.py
+++ b/briar-gtk/tests/briar_gtk/test_window.py
@@ -79,6 +79,14 @@ def test_show_main_destroy_old(main_window_container, mocker,
     current_container_mock.destroy.assert_called_once()
 
 
+@pytest.fixture(autouse=True)
+def briar_headless_jar(is_file):
+    flatpak_path = "/app/share/java/briar-headless.jar"
+    return_values = {flatpak_path: True}
+    is_file.side_effect = return_values.get
+    return is_file
+
+
 @pytest.fixture(autouse=True)
 def gi_dependencies(mocker):
     mocker.patch(MODULE % "Gtk")
diff --git a/briar-gtk/tests/conftest.py b/briar-gtk/tests/conftest.py
index bb0bffd..874250e 100644
--- a/briar-gtk/tests/conftest.py
+++ b/briar-gtk/tests/conftest.py
@@ -1,3 +1,10 @@
 # Copyright (c) 2019 Nico Alt
 # SPDX-License-Identifier: AGPL-3.0-only
 # License-Filename: LICENSE.md
+
+import pytest
+
+
+@pytest.fixture()
+def is_file(mocker):
+    return mocker.patch('os.path.isfile')
-- 
GitLab