diff --git a/public/index.html b/public/index.html index f317cfb..209e447 100644 --- a/public/index.html +++ b/public/index.html @@ -119,6 +119,18 @@ + +
  • + +
  • + @@ -1027,6 +1039,53 @@ + +
    + + +
    +
    App Info
    +
    +
    +
    Version
    +
    v{{ appInfo.version }}
    +
    +
    +
    Reticulum Config Path
    +
    {{ appInfo.reticulum_config_path }}
    +
    +
    +
    Database Path
    +
    {{ appInfo.database_path }}
    +
    +
    +
    Database File Size
    +
    {{ formatBytes(appInfo.database_file_size) }}
    +
    +
    +
    + + +
    +
    My Addresses
    +
    +
    +
    Identity Hash
    +
    {{ config.identity_hash }}
    +
    +
    +
    LXMF Address
    +
    {{ config.lxmf_address_hash }}
    +
    +
    +
    Audio Call Address
    +
    {{ config.audio_call_address_hash }}
    +
    +
    +
    + +
    + @@ -1053,6 +1112,7 @@ displayName: "Anonymous Peer", config: null, + appInfo: null, audioCalls: [], lxmfDeliveryAnnounces: [], @@ -1112,6 +1172,7 @@ }, mounted: function() { + this.getAppInfo(); this.connectWebsocket(); this.getLxmfDeliveryAnnounces(); this.getNomadnetworkNodeAnnounces(); @@ -1325,6 +1386,15 @@ container.scrollTop = container.scrollHeight; }); }, + async getAppInfo() { + try { + const response = await window.axios.get(`/api/v1/app/info`); + this.appInfo = response.data.app_info; + } catch(e) { + // do nothing if failed to load app info + console.log(e); + } + }, async getConfig() { try { const response = await window.axios.get(`/api/v1/config`); @@ -2291,6 +2361,10 @@ await this.getConversations(); }, + showAboutTab() { + this.tab = "about"; + this.getAppInfo(); + }, async enableInterface(interfaceName) { // enable interface diff --git a/setup.py b/setup.py index 36811f3..5e30678 100644 --- a/setup.py +++ b/setup.py @@ -26,6 +26,7 @@ ], # files that are required 'include_files': [ + 'package.json', # used to determine app version from python 'public/', # static files served by web server ], # slim down the build by excluding these unused libs diff --git a/web.py b/web.py index 3ee37f4..21be561 100644 --- a/web.py +++ b/web.py @@ -48,17 +48,17 @@ def __init__(self, identity: RNS.Identity, storage_dir, reticulum_config_dir): # ./storage/identities//database.db # ensure a storage path exists for the loaded identity - base_storage_dir = storage_dir or os.path.join("storage") - storage_path = os.path.join(base_storage_dir, "identities", identity.hash.hex()) - print("Using Storage Path: {}".format(storage_path)) - os.makedirs(storage_path, exist_ok=True) + self.storage_dir = storage_dir or os.path.join("storage") + self.storage_path = os.path.join(self.storage_dir, "identities", identity.hash.hex()) + print("Using Storage Path: {}".format(self.storage_path)) + os.makedirs(self.storage_path, exist_ok=True) # define path to files based on storage path - database_path = os.path.join(storage_path, "database.db") - lxmf_router_path = os.path.join(storage_path, "lxmf_router") + self.database_path = os.path.join(self.storage_path, "database.db") + lxmf_router_path = os.path.join(self.storage_path, "lxmf_router") # init database - sqlite_database = SqliteDatabase(database_path) + sqlite_database = SqliteDatabase(self.database_path) database.database.initialize(sqlite_database) self.db = database.database self.db.connect() @@ -109,6 +109,12 @@ def __init__(self, identity: RNS.Identity, storage_dir, reticulum_config_dir): thread.daemon = True thread.start() + # gets app version from package.json + def get_app_version(self) -> str: + with open(get_file_path("package.json")) as f: + package_json = json.load(f) + return package_json["version"] + # automatically announces based on user config async def announce_loop(self): while True: @@ -443,6 +449,19 @@ async def ws(request): return websocket_response + # get app info + @routes.get("/api/v1/app/info") + async def index(request): + return web.json_response({ + "app_info": { + "version": self.get_app_version(), + "storage_path": self.storage_path, + "database_path": self.database_path, + "database_file_size": os.path.getsize(self.database_path), + "reticulum_config_path": self.reticulum.configpath, + }, + }) + # get config @routes.get("/api/v1/config") async def index(request):