Skip to content

Commit

Permalink
feat(tapplets): predownload tapplets icons (#134)
Browse files Browse the repository at this point in the history
Description
---
Pre-download and display tapplets icons. Registry holds icon for each
tapplet but tari universe displayed fixed icon in every case.

Motivation and Context
---
Implement basic feature

How Has This Been Tested?
---
Tested manually

What process can a PR reviewer use to test or verify this change?
---
Just run application and check if there are icons next to the name for
registered and installed tapplets.


Breaking Changes
---

- [ ] None
- [ ] Requires data directory on base node to be deleted
- [ ] Requires hard fork
- [x] Other - Please specify

Delete database and run tari universe to initialize it with new table
  • Loading branch information
MCozhusheck authored Aug 22, 2024
1 parent 60de0f6 commit cd92a22
Show file tree
Hide file tree
Showing 18 changed files with 282 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ DROP TABLE tapplet_version;
DROP TABLE tapplet_audit;
DROP TABLE installed_tapplet;
DROP TABLE dev_tapplet;
DROP TABLE tapplet_asset;
8 changes: 8 additions & 0 deletions src-tauri/migrations/2024-04-25-073069_create_tapplets/up.sql
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,11 @@ CREATE TABLE dev_tapplet (
display_name TEXT NOT NULL,
UNIQUE(endpoint)
);

CREATE TABLE tapplet_asset (
id INTEGER PRIMARY KEY,
tapplet_id INTEGER,
icon_url TEXT NOT NULL,
background_url TEXT NOT NULL,
FOREIGN KEY (tapplet_id) REFERENCES tapplet(id)
);
46 changes: 36 additions & 10 deletions src-tauri/src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use tari_wallet_daemon_client::types::AccountsGetBalancesResponse;
use tauri::{ self, State };
use tauri::{ self, AppHandle, State };
use std::path::PathBuf;

use crate::{
constants::REGISTRY_URL,
database::{
models::{
CreateDevTapplet,
CreateInstalledTapplet,
CreateTapplet,
CreateTappletAsset,
CreateTappletAudit,
CreateTappletVersion,
DevTapplet,
Expand All @@ -26,8 +28,16 @@ use crate::{
hash_calculator::calculate_checksum,
interface::{ DevTappletResponse, InstalledTappletWithName, RegisteredTappletWithVersion, RegisteredTapplets },
rpc::{ balances, free_coins, make_request },
tapplet_installer::{ check_extracted_files, delete_tapplet, download_file, extract_tar, get_tapp_download_path },
tapplet_installer::{
check_extracted_files,
delete_tapplet,
download_asset,
download_file_and_archive,
extract_tar,
get_tapp_download_path,
},
tapplet_server::start,
AssetServer,
DatabaseConnection,
ShutdownTokens,
Tokens,
Expand Down Expand Up @@ -128,6 +138,11 @@ pub async fn close_tapplet(installed_tapplet_id: i32, shutdown_tokens: State<'_,
Ok(())
}

#[tauri::command]
pub fn get_assets_server_addr(state: tauri::State<'_, AssetServer>) -> Result<String, String> {
Ok(format!("http://{}", state.addr))
}

#[tauri::command]
pub async fn download_and_extract_tapp(
tapplet_id: i32,
Expand All @@ -143,7 +158,7 @@ pub async fn download_and_extract_tapp(
// download tarball
let url = tapp_version.registry_url.clone();
let download_path = tapplet_path.clone();
let handle = tauri::async_runtime::spawn(async move { download_file(&url, download_path).await });
let handle = tauri::async_runtime::spawn(async move { download_file_and_archive(&url, download_path).await });
handle.await?.map_err(|_| Error::RequestError(FailedToDownload { url: tapp_version.registry_url }))?;

//extract tarball
Expand Down Expand Up @@ -196,10 +211,8 @@ pub fn read_tapp_registry_db(db_connection: State<'_, DatabaseConnection>) -> Re
* REGISTERED TAPPLETS - FETCH DATA FROM MANIFEST JSON
*/
#[tauri::command]
pub async fn fetch_tapplets(db_connection: State<'_, DatabaseConnection>) -> Result<(), Error> {
let manifest_endpoint = String::from(
"https://raw.githubusercontent.com/karczuRF/tapp-registry/main/dist/tapplets-registry.manifest.json"
);
pub async fn fetch_tapplets(app_handle: AppHandle, db_connection: State<'_, DatabaseConnection>) -> Result<(), Error> {
let manifest_endpoint = format!("{}/dist/tapplets-registry.manifest.json", REGISTRY_URL);
let manifest_res = reqwest
::get(&manifest_endpoint).await
.map_err(|_| RequestError(FetchManifestError { endpoint: manifest_endpoint.clone() }))?
Expand All @@ -212,12 +225,11 @@ pub async fn fetch_tapplets(db_connection: State<'_, DatabaseConnection>) -> Res

for tapplet_manifest in tapplets.registered_tapplets.values() {
let inserted_tapplet = store.create(&CreateTapplet::from(tapplet_manifest))?;
let tapplet_db_id = inserted_tapplet.id;

// for audit_data in tapplet_manifest.metadata.audits.iter() {
// store.create(
// &(CreateTappletAudit {
// tapplet_id: tapplet_db_id,
// tapplet_id: inserted_tapplet.id,
// auditor: &audit_data.auditor,
// report_url: &audit_data.report_url,
// })
Expand All @@ -227,13 +239,27 @@ pub async fn fetch_tapplets(db_connection: State<'_, DatabaseConnection>) -> Res
for (version, version_data) in tapplet_manifest.versions.iter() {
store.create(
&(CreateTappletVersion {
tapplet_id: tapplet_db_id,
tapplet_id: inserted_tapplet.id,
version: &version,
integrity: &version_data.integrity,
registry_url: &version_data.registry_url,
})
)?;
}

match store.get_tapplet_assets_by_tapplet_id(inserted_tapplet.id.unwrap())? {
Some(_) => {}
None => {
let tapplet_assets = download_asset(app_handle.clone(), inserted_tapplet.registry_id).await?;
store.create(
&(CreateTappletAsset {
tapplet_id: inserted_tapplet.id,
icon_url: &tapplet_assets.icon_url,
background_url: &tapplet_assets.background_url,
})
)?;
}
}
}
Ok(())
}
Expand Down
2 changes: 2 additions & 0 deletions src-tauri/src/constants.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
pub const TAPPLETS_INSTALLED_DIR: &'static str = "tapplets_installed";
pub const TAPPLETS_ASSETS_DIR: &'static str = "assets";
pub const DB_FILE_NAME: &'static str = "tari_universe.sqlite3";
pub const REGISTRY_URL: &'static str = "https://raw.githubusercontent.com/karczuRF/tapp-registry/main";
36 changes: 36 additions & 0 deletions src-tauri/src/database/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,39 @@ pub struct UpdateTappletAudit {
pub auditor: String,
pub report_url: String,
}

#[derive(Queryable, Selectable, Debug, Serialize)]
#[diesel(table_name = tapplet_asset)]
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
pub struct TappletAsset {
pub id: Option<i32>,
pub tapplet_id: Option<i32>,
pub icon_url: String,
pub background_url: String,
}

#[derive(Insertable, Debug)]
#[diesel(table_name = tapplet_asset)]
pub struct CreateTappletAsset<'a> {
pub tapplet_id: Option<i32>,
pub icon_url: &'a str,
pub background_url: &'a str,
}

impl<'a> From<&CreateTappletAsset<'a>> for UpdateTappletAsset {
fn from(create_tapplet_asset: &CreateTappletAsset) -> Self {
UpdateTappletAsset {
tapplet_id: create_tapplet_asset.tapplet_id,
icon_url: create_tapplet_asset.icon_url.to_string(),
background_url: create_tapplet_asset.background_url.to_string(),
}
}
}

#[derive(Debug, AsChangeset)]
#[diesel(table_name = tapplet_asset)]
pub struct UpdateTappletAsset {
pub tapplet_id: Option<i32>,
pub icon_url: String,
pub background_url: String,
}
11 changes: 11 additions & 0 deletions src-tauri/src/database/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ diesel::table! {
}
}

diesel::table! {
tapplet_asset (id) {
id -> Nullable<Integer>,
tapplet_id -> Nullable<Integer>,
icon_url -> Text,
background_url -> Text,
}
}

diesel::table! {
tapplet_audit (id) {
id -> Nullable<Integer>,
Expand All @@ -54,13 +63,15 @@ diesel::table! {

diesel::joinable!(installed_tapplet -> tapplet (tapplet_id));
diesel::joinable!(installed_tapplet -> tapplet_version (tapplet_version_id));
diesel::joinable!(tapplet_asset -> tapplet (tapplet_id));
diesel::joinable!(tapplet_audit -> tapplet (tapplet_id));
diesel::joinable!(tapplet_version -> tapplet (tapplet_id));

diesel::allow_tables_to_appear_in_same_query!(
dev_tapplet,
installed_tapplet,
tapplet,
tapplet_asset,
tapplet_audit,
tapplet_version,
);
65 changes: 65 additions & 0 deletions src-tauri/src/database/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ use crate::interface::InstalledTappletWithName;
use crate::interface::TappletSemver;

use super::models::CreateDevTapplet;
use super::models::CreateTappletAsset;
use super::models::CreateTappletVersion;
use super::models::CreateTappletAudit;
use super::models::DevTapplet;
use super::models::TappletAsset;
use super::models::UpdateDevTapplet;
use super::models::UpdateInstalledTapplet;
use super::models::UpdateTappletAsset;
use super::models::UpdateTappletVersion;
use super::models::UpdateTappletAudit;

Expand Down Expand Up @@ -121,6 +124,16 @@ impl SqliteStore {

return Ok((boxed_tapplet, latest_version.tapplet_version));
}

pub fn get_tapplet_assets_by_tapplet_id(&mut self, tapp_id: i32) -> Result<Option<TappletAsset>, Error> {
use crate::database::schema::tapplet_asset::dsl::*;

tapplet_asset
.filter(tapplet_id.eq(tapp_id))
.first::<TappletAsset>(self.get_connection().deref_mut())
.optional()
.map_err(|_| DatabaseError(FailedToRetrieveData { entity_name: "tapplet asset".to_string() }))
}
}

impl<'a> Store<Tapplet, CreateTapplet<'a>, UpdateTapplet> for SqliteStore {
Expand Down Expand Up @@ -391,3 +404,55 @@ impl<'a> Store<DevTapplet, CreateDevTapplet<'a>, UpdateDevTapplet> for SqliteSto
.map_err(|_| DatabaseError(FailedToDelete { entity_name: "Dev Tapplet".to_string() }))
}
}

impl<'a> Store<TappletAsset, CreateTappletAsset<'a>, UpdateTappletAsset> for SqliteStore {
fn get_all(&mut self) -> Result<Vec<TappletAsset>, Error> {
use crate::database::schema::tapplet_asset::dsl::*;

tapplet_asset
.load::<TappletAsset>(self.get_connection().deref_mut())
.map_err(|_| DatabaseError(FailedToRetrieveData { entity_name: "Tapplet asset".to_string() }))
}

fn get_by_id(&mut self, tapplet_asset_id: i32) -> Result<TappletAsset, Error> {
use crate::database::schema::tapplet_asset::dsl::*;

tapplet_asset
.filter(id.eq(tapplet_asset_id))
.first::<TappletAsset>(self.get_connection().deref_mut())
.map_err(|_| DatabaseError(FailedToRetrieveData { entity_name: "Tapplet asset".to_string() }))
}

fn create(&mut self, item: &CreateTappletAsset) -> Result<TappletAsset, Error> {
use crate::database::schema::tapplet_asset;

diesel
::insert_into(tapplet_asset::table)
.values(item)
.get_result(self.get_connection().deref_mut())
.map_err(|_|
DatabaseError(FailedToCreate {
entity_name: "Tapplet asset".to_string(),
})
)
}

fn update(&mut self, old: TappletAsset, new: &UpdateTappletAsset) -> Result<usize, Error> {
use crate::database::schema::tapplet_asset::dsl::*;

diesel
::update(tapplet_asset.filter(id.eq(old.id)))
.set(new)
.execute(self.get_connection().deref_mut())
.map_err(|_| DatabaseError(FailedToUpdate { entity_name: "Tapplet asset".to_string() }))
}

fn delete(&mut self, entity: TappletAsset) -> Result<usize, Error> {
use crate::database::schema::tapplet_asset::dsl::*;

diesel
::delete(tapplet_asset.filter(id.eq(entity.id)))
.execute(self.get_connection().deref_mut())
.map_err(|_| DatabaseError(FailedToDelete { entity_name: "Tapplet asset".to_string() }))
}
}
6 changes: 6 additions & 0 deletions src-tauri/src/interface/tapplet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,9 @@ pub struct RegisteredTappletWithVersion {
pub registered_tapp: Tapplet,
pub tapp_version: TappletVersion,
}

#[derive(Serialize)]
pub struct TappletAssets {
pub icon_url: String,
pub background_url: String,
}
14 changes: 14 additions & 0 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use constants::TAPPLETS_ASSETS_DIR;
use diesel::SqliteConnection;
use fs::{ get_config_file, get_data_dir, get_log_dir };
use tapplet_server::start;
use std::{ collections::HashMap, sync::{ Arc, Mutex }, thread::sleep, time::Duration };
use tauri::{ self, Manager };
use tokio_util::sync::CancellationToken;
Expand All @@ -21,6 +23,7 @@ use commands::{
calculate_and_validate_tapp_checksum,
launch_tapplet,
close_tapplet,
get_assets_server_addr,
download_and_extract_tapp,
get_balances,
get_free_coins,
Expand Down Expand Up @@ -49,6 +52,10 @@ pub struct Tokens {
#[derive(Default)]
pub struct ShutdownTokens(Arc<tokio::sync::Mutex<HashMap<i32, CancellationToken>>>);
pub struct DatabaseConnection(Arc<Mutex<SqliteConnection>>);
pub struct AssetServer {
pub addr: String,
pub cancel_token: CancellationToken,
}

async fn try_get_tokens() -> (String, String) {
loop {
Expand Down Expand Up @@ -88,6 +95,12 @@ fn setup_tari_universe(app: &mut tauri::App) -> Result<(), Box<dyn std::error::E
.map_err(|_| error::Error::FailedToObtainAuthTokenLock)?
.replace_range(.., &auth_token);

let app_path = app.path().app_data_dir().unwrap().to_path_buf();
let tapplet_assets_path = app_path.join(TAPPLETS_ASSETS_DIR);
let handle_start = tauri::async_runtime::spawn(async move { start(tapplet_assets_path).await });
let (addr, cancel_token) = tauri::async_runtime::block_on(handle_start)?.unwrap();
app.manage(AssetServer { addr, cancel_token });

Ok(())
}

Expand Down Expand Up @@ -117,6 +130,7 @@ pub fn run() {
get_balances,
launch_tapplet,
close_tapplet,
get_assets_server_addr,
call_wallet,
insert_installed_tapp_db,
read_installed_tapp_db,
Expand Down
Loading

0 comments on commit cd92a22

Please sign in to comment.