Add Tauri project files and update .gitignore
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -5,3 +5,7 @@ __pycache__
|
||||
.zipignore
|
||||
.gitignore
|
||||
.DS_Store
|
||||
node_modules
|
||||
dist
|
||||
src-tauri/target
|
||||
src-tauri/gen
|
||||
|
||||
9
src-tauri/capabilities/default.json
Normal file
9
src-tauri/capabilities/default.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"identifier": "default",
|
||||
"description": "Default capabilities",
|
||||
"permissions": [
|
||||
"core:default",
|
||||
"dialog:default",
|
||||
"run-python-action"
|
||||
]
|
||||
}
|
||||
BIN
src-tauri/icons/icon.png
Normal file
BIN
src-tauri/icons/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 99 KiB |
4
src-tauri/permissions/run-python-action.toml
Normal file
4
src-tauri/permissions/run-python-action.toml
Normal file
@@ -0,0 +1,4 @@
|
||||
[[permission]]
|
||||
identifier = "run-python-action"
|
||||
description = "Allow the UI to invoke the Python backend"
|
||||
commands.allow = ["run_python_action"]
|
||||
86
src-tauri/src/lib.rs
Normal file
86
src-tauri/src/lib.rs
Normal file
@@ -0,0 +1,86 @@
|
||||
use serde_json::Value;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
fn repo_root() -> PathBuf {
|
||||
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
manifest_dir.parent().unwrap_or(&manifest_dir).to_path_buf()
|
||||
}
|
||||
|
||||
fn run_python(script: &str, input: &str) -> Result<Vec<u8>, String> {
|
||||
let cwd = repo_root();
|
||||
let mut last_err: Option<String> = None;
|
||||
for candidate in ["python3", "python"] {
|
||||
let mut child = match Command::new(candidate)
|
||||
.arg(script)
|
||||
.current_dir(&cwd)
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
{
|
||||
Ok(child) => child,
|
||||
Err(err) => {
|
||||
last_err = Some(format!("{candidate}: {err}"));
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(mut stdin) = child.stdin.take() {
|
||||
if let Err(err) = stdin.write_all(input.as_bytes()) {
|
||||
return Err(format!("Failed to write to Python stdin: {err}"));
|
||||
}
|
||||
}
|
||||
|
||||
let output = match child.wait_with_output() {
|
||||
Ok(output) => output,
|
||||
Err(err) => {
|
||||
last_err = Some(format!("{candidate}: {err}"));
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
if !output.status.success() {
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
return Err(format!("Python backend failed: {stderr}"));
|
||||
}
|
||||
|
||||
return Ok(output.stdout);
|
||||
}
|
||||
|
||||
Err(last_err.unwrap_or_else(|| "Python not found".to_string()))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn run_python_action(action: String, payload: Value) -> Result<Value, String> {
|
||||
let script = repo_root().join("concept_api.py");
|
||||
if !script.exists() {
|
||||
return Err("concept_api.py not found".to_string());
|
||||
}
|
||||
|
||||
let req = serde_json::json!({
|
||||
"action": action,
|
||||
"payload": payload,
|
||||
});
|
||||
let input = serde_json::to_string(&req).map_err(|e| e.to_string())?;
|
||||
let stdout = run_python(script.to_string_lossy().as_ref(), &input)?;
|
||||
let resp: Value = serde_json::from_slice(&stdout).map_err(|e| e.to_string())?;
|
||||
if resp.get("ok") == Some(&Value::Bool(true)) {
|
||||
Ok(resp.get("data").cloned().unwrap_or(Value::Null))
|
||||
} else {
|
||||
let error = resp
|
||||
.get("error")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("Unknown backend error");
|
||||
Err(error.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.invoke_handler(tauri::generate_handler![run_python_action])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
3
src-tauri/src/main.rs
Normal file
3
src-tauri/src/main.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
concept_maker::run();
|
||||
}
|
||||
29
src-tauri/tauri.conf.json
Normal file
29
src-tauri/tauri.conf.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/tauri-apps/tauri/dev/tooling/cli/schema.json",
|
||||
"package": {
|
||||
"productName": "Concept Maker",
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"build": {
|
||||
"beforeDevCommand": "npm run dev",
|
||||
"beforeBuildCommand": "npm run build",
|
||||
"devUrl": "http://localhost:5173",
|
||||
"frontendDist": "../dist"
|
||||
},
|
||||
"app": {
|
||||
"windows": [
|
||||
{
|
||||
"title": "Idea -> Concept",
|
||||
"width": 1200,
|
||||
"height": 820,
|
||||
"minWidth": 900,
|
||||
"minHeight": 640
|
||||
}
|
||||
]
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"icon": ["icons/icon.png"]
|
||||
}
|
||||
}
|
||||
@@ -136,8 +136,8 @@ export default function App() {
|
||||
let unlisten: (() => void) | undefined;
|
||||
const attach = async () => {
|
||||
try {
|
||||
const current = getCurrent();
|
||||
unlisten = await current.onFileDropEvent((event) => {
|
||||
const current = getCurrent() as any;
|
||||
unlisten = await current.onFileDropEvent((event: any) => {
|
||||
if (event.payload.type === "drop") {
|
||||
const paths = event.payload.paths ?? [];
|
||||
if (paths.length) {
|
||||
|
||||
Reference in New Issue
Block a user