mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-04 12:13:27 +00:00
fixed thumbnail gen
This commit is contained in:
parent
1d09081f71
commit
25324fb1f9
|
@ -1,9 +1,12 @@
|
|||
use std::time::Instant;
|
||||
|
||||
use anyhow::Result;
|
||||
use sdcorelib::db::connection::db_instance;
|
||||
use sdcorelib::file::{indexer, retrieve, retrieve::Directory};
|
||||
use sdcorelib::native;
|
||||
use sdcorelib::{AppConfig, CONFIG};
|
||||
use sdcorelib::AppConfig;
|
||||
use serde::Serialize;
|
||||
use std::fs;
|
||||
use swift_rs::types::SRObjectArray;
|
||||
|
||||
#[derive(Serialize)]
|
||||
|
@ -46,7 +49,7 @@ pub async fn get_files(path: String) -> Result<Directory, String> {
|
|||
}
|
||||
#[tauri::command(async)]
|
||||
pub async fn get_config() -> Result<&'static AppConfig, String> {
|
||||
Ok(CONFIG.get().unwrap())
|
||||
Ok(&sdcorelib::EXTERNAL_CLIENT.get().unwrap().config)
|
||||
}
|
||||
#[tauri::command]
|
||||
pub fn get_mounts() -> Result<SRObjectArray<native::methods::Mount>, String> {
|
||||
|
@ -77,3 +80,48 @@ pub async fn test_scan() -> Result<(), String> {
|
|||
|
||||
// // ....
|
||||
// }
|
||||
#[tauri::command(async)]
|
||||
pub async fn get_thumbs_for_directory(window: tauri::Window, path: &str) -> Result<(), String> {
|
||||
let config = &sdcorelib::EXTERNAL_CLIENT.get().unwrap().config;
|
||||
let dir = retrieve::get_dir_with_contents(&path).await?;
|
||||
// iterate over directory contents
|
||||
for file in dir.contents.into_iter() {
|
||||
let now = Instant::now();
|
||||
let icon_name = format!(
|
||||
"{}.png",
|
||||
if file.is_dir {
|
||||
"folder".to_owned()
|
||||
} else {
|
||||
file.extension
|
||||
}
|
||||
);
|
||||
let icon_path = config.file_type_thumb_dir.join(icon_name);
|
||||
// extract metadata from file
|
||||
let existing = fs::metadata(&icon_path).is_ok();
|
||||
// write thumbnail only if
|
||||
if !existing {
|
||||
// call swift to get thumbnail data
|
||||
let thumbnail_b64 =
|
||||
sdcorelib::native::methods::get_file_thumbnail_base64(&file.uri).to_string();
|
||||
fs::write(
|
||||
&icon_path,
|
||||
base64::decode(thumbnail_b64).unwrap_or_default(),
|
||||
)
|
||||
.map_err(|_| "thumb_cache_failure")?;
|
||||
}
|
||||
println!("cached thumb {:?} in {:?}", file.id, now.elapsed());
|
||||
|
||||
if !existing {
|
||||
reply(
|
||||
&window,
|
||||
GlobalEventKind::FileTypeThumb,
|
||||
GenFileTypeIconsResponse {
|
||||
icon_created: true,
|
||||
file_id: file.id,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
mod commands;
|
||||
mod menu;
|
||||
use futures::executor::block_on;
|
||||
use sdcorelib;
|
||||
use tauri::api::path;
|
||||
|
||||
fn main() {
|
||||
let data_dir = path::data_dir().unwrap_or(std::path::PathBuf::from("./"));
|
||||
block_on(sdcorelib::configure(data_dir));
|
||||
sdcorelib::configure(data_dir);
|
||||
|
||||
tauri::Builder::default()
|
||||
.setup(|_app| Ok(()))
|
||||
|
@ -17,6 +16,7 @@ fn main() {
|
|||
commands::get_config,
|
||||
commands::get_mounts,
|
||||
commands::test_scan,
|
||||
commands::get_thumbs_for_directory,
|
||||
])
|
||||
.menu(menu::get_menu())
|
||||
.run(tauri::generate_context!())
|
||||
|
|
|
@ -11,18 +11,18 @@ export const Shortcut: React.FC<ShortcutProps> = (props) => {
|
|||
<span
|
||||
className={clsx(
|
||||
`
|
||||
px-1
|
||||
py-0.5
|
||||
text-xs
|
||||
font-bold
|
||||
text-gray-400
|
||||
bg-gray-200
|
||||
border-gray-300
|
||||
dark:text-gray-400
|
||||
dark:bg-gray-600
|
||||
dark:border-gray-500
|
||||
border-t-2
|
||||
rounded-lg
|
||||
px-1
|
||||
py-0.5
|
||||
text-xs
|
||||
font-bold
|
||||
text-gray-400
|
||||
bg-gray-200
|
||||
border-gray-300
|
||||
dark:text-gray-400
|
||||
dark:bg-gray-600
|
||||
dark:border-gray-500
|
||||
border-t-2
|
||||
rounded-lg
|
||||
`,
|
||||
props.className
|
||||
)}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React from 'react';
|
||||
import { Button } from '../components/primitive';
|
||||
import { Tag } from '../components/primitive/Tag';
|
||||
|
||||
interface StatItemProps {
|
||||
|
@ -20,6 +21,7 @@ const StatItem: React.FC<StatItemProps> = (props) => {
|
|||
};
|
||||
|
||||
export const OverviewScreen: React.FC<{}> = (props) => {
|
||||
|
||||
return (
|
||||
<div className="flex flex-col w-full h-full p-5 bg-white dark:bg-gray-900">
|
||||
<h1 className="text-xl font-bold ">Jamie's Library</h1>
|
||||
|
@ -43,7 +45,6 @@ export const OverviewScreen: React.FC<{}> = (props) => {
|
|||
</div>
|
||||
<hr className="my-5 dark:border-gray-800" />
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::CONFIG;
|
||||
use crate::EXTERNAL_CLIENT;
|
||||
use anyhow::Result;
|
||||
use once_cell::sync::OnceCell;
|
||||
use rusqlite::Connection;
|
||||
|
@ -8,7 +8,7 @@ use sea_orm::{Database, DatabaseConnection, DbErr};
|
|||
// use std::str::FromStr;
|
||||
|
||||
pub async fn get_connection() -> Result<DatabaseConnection, DbErr> {
|
||||
let config = CONFIG.get().unwrap();
|
||||
let config = &EXTERNAL_CLIENT.get().unwrap().config;
|
||||
|
||||
let db_url = format!("{}{}", "sqlite://", config.primary_db.to_str().unwrap());
|
||||
|
||||
|
@ -29,7 +29,7 @@ pub async fn db_instance() -> Result<&'static DatabaseConnection, String> {
|
|||
}
|
||||
|
||||
pub async fn create_primary_db() -> Result<(), sqlx::Error> {
|
||||
let config = CONFIG.get().unwrap();
|
||||
let config = &EXTERNAL_CLIENT.get().unwrap().config;
|
||||
|
||||
let db_url = config.primary_db.to_str().unwrap();
|
||||
// establish connection, this is only used to create the db if missing
|
||||
|
|
45
packages/core/lib/file/icon.rs
Normal file
45
packages/core/lib/file/icon.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
|
||||
|
||||
pub async fn get_thumbs_for_directory(window: tauri::Window, path: &str) -> Result<(), String> {
|
||||
let config = config::get_config();
|
||||
let dir = filesystem::retrieve::get_dir_with_contents(&path).await?;
|
||||
// iterate over directory contents
|
||||
for file in dir.contents.into_iter() {
|
||||
let now = Instant::now();
|
||||
let icon_name = format!(
|
||||
"{}.png",
|
||||
if file.is_dir {
|
||||
"folder".to_owned()
|
||||
} else {
|
||||
file.extension
|
||||
}
|
||||
);
|
||||
let icon_path = config.file_type_thumb_dir.join(icon_name);
|
||||
// extract metadata from file
|
||||
let existing = fs::metadata(&icon_path).is_ok();
|
||||
// write thumbnail only if
|
||||
if !existing {
|
||||
// call swift to get thumbnail data
|
||||
let thumbnail_b64 = get_file_thumbnail_base64(&file.uri).to_string();
|
||||
fs::write(
|
||||
&icon_path,
|
||||
base64::decode(thumbnail_b64).unwrap_or_default(),
|
||||
)
|
||||
.map_err(|_| "thumb_cache_failure")?;
|
||||
}
|
||||
println!("cached thumb {:?} in {:?}", file.id, now.elapsed());
|
||||
|
||||
if !existing {
|
||||
reply(
|
||||
&window,
|
||||
GlobalEventKind::FileTypeThumb,
|
||||
GenFileTypeIconsResponse {
|
||||
icon_created: true,
|
||||
file_id: file.id,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -17,9 +17,31 @@ pub struct AppConfig {
|
|||
pub file_type_thumb_dir: std::path::PathBuf,
|
||||
}
|
||||
|
||||
pub static CONFIG: OnceCell<AppConfig> = OnceCell::new();
|
||||
// represents an event this library can emit
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub enum ClientEvent {
|
||||
NewFileTypeThumb,
|
||||
}
|
||||
|
||||
pub async fn configure(mut data_dir: std::path::PathBuf) {
|
||||
// represents an application or client instance to communicate with
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ExternalClient {
|
||||
pub config: AppConfig,
|
||||
}
|
||||
|
||||
trait Emitter {
|
||||
fn emit(&self, event: ClientEvent, data: &str) -> Result<(), String>;
|
||||
}
|
||||
|
||||
impl Emitter for ExternalClient {
|
||||
fn emit(&self, event: ClientEvent, _: &str) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub static EXTERNAL_CLIENT: OnceCell<ExternalClient> = OnceCell::new();
|
||||
|
||||
pub fn configure(mut data_dir: std::path::PathBuf) {
|
||||
data_dir = data_dir.join("spacedrive");
|
||||
|
||||
let config = AppConfig {
|
||||
|
@ -27,11 +49,16 @@ pub async fn configure(mut data_dir: std::path::PathBuf) {
|
|||
primary_db: data_dir.clone().join("primary.db3"),
|
||||
file_type_thumb_dir: data_dir.clone().join("file_icons"),
|
||||
};
|
||||
CONFIG.set(config).unwrap();
|
||||
|
||||
EXTERNAL_CLIENT.set(ExternalClient { config });
|
||||
|
||||
// EXTERNAL_CLIENT
|
||||
// .unwrap()
|
||||
// .emit(ClientEvent::NewFileTypeThumb, "...");
|
||||
|
||||
// create the data directories if not present
|
||||
fs::create_dir_all(&CONFIG.get().unwrap().data_dir).unwrap();
|
||||
fs::create_dir_all(&CONFIG.get().unwrap().file_type_thumb_dir).unwrap();
|
||||
fs::create_dir_all(&EXTERNAL_CLIENT.get().unwrap().config.data_dir).unwrap();
|
||||
fs::create_dir_all(&EXTERNAL_CLIENT.get().unwrap().config.file_type_thumb_dir).unwrap();
|
||||
|
||||
// create primary data base if not exists
|
||||
block_on(db::connection::create_primary_db()).unwrap();
|
||||
|
|
Loading…
Reference in a new issue