Initial commit
@@ -0,0 +1,27 @@
|
||||
[package]
|
||||
name = "to-do-app"
|
||||
version = "0.0.0"
|
||||
description = "A Tauri App"
|
||||
authors = ["you"]
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "1", features = [] }
|
||||
|
||||
[dependencies]
|
||||
tauri = { version = "1", features = [ "window-show", "window-unminimize", "window-minimize", "window-maximize", "window-start-dragging", "window-hide", "window-close", "window-unmaximize", "shell-open"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
magic-crypt = "3.1.13"
|
||||
rust-fuzzy-search = "0.1.1"
|
||||
|
||||
[features]
|
||||
# This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!!
|
||||
custom-protocol = ["tauri/custom-protocol"]
|
||||
|
||||
[profile.release]
|
||||
lto = true # Enables link to optimizations
|
||||
opt-level = "z" # Optimize for binary size
|
||||
strip = true # Remove debug symbols
|
||||
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
tauri_build::build()
|
||||
}
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 974 B |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 903 B |
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,20 @@
|
||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
|
||||
#[path="tasks_functions.rs"] mod tasks;
|
||||
|
||||
fn main() {
|
||||
tauri::Builder::default()
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
tasks::check_or_create_tasks_file,
|
||||
tasks::get_tasks,
|
||||
tasks::search_tasks,
|
||||
tasks::add_task,
|
||||
tasks::edit_task,
|
||||
tasks::delete_task,
|
||||
tasks::set_task_field
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
use magic_crypt::{MagicCryptTrait, new_magic_crypt};
|
||||
use std::fs::{read_to_string, write};
|
||||
use std::path::PathBuf;
|
||||
use std::path::Path;
|
||||
use std::fs::File;
|
||||
use serde_json::{Value, json};
|
||||
use rust_fuzzy_search::fuzzy_search_best_n;
|
||||
|
||||
pub fn encrypt_n_save_file(path: PathBuf, content: String){
|
||||
let mc = new_magic_crypt!("7J?VKYJib`=NIOpapW+zP8wD_#lPjP77Z)Q:4QUlH4`0rpMz7]>EIC%$RV-9*iW9AZ>Qk!OmAuH`8GzJ93xR4`KTl*-#fuCKzDfrPe&-A0?^Mz<F8IJ((oe+X,73iG", 256);
|
||||
|
||||
let mut encrypted: String = String::new();
|
||||
|
||||
for line in content.lines() {
|
||||
encrypted = encrypted.to_owned() + mc.encrypt_str_to_base64(line).as_str() + "\n";
|
||||
}
|
||||
let res = write(path, encrypted);
|
||||
match res {
|
||||
Ok(_) => {},
|
||||
Err(_) => println!("File save error!")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decrypt_file(path: PathBuf) -> String {
|
||||
let mc = new_magic_crypt!("7J?VKYJib`=NIOpapW+zP8wD_#lPjP77Z)Q:4QUlH4`0rpMz7]>EIC%$RV-9*iW9AZ>Qk!OmAuH`8GzJ93xR4`KTl*-#fuCKzDfrPe&-A0?^Mz<F8IJ((oe+X,73iG", 256);
|
||||
|
||||
let mut decrypted: String = String::new();
|
||||
|
||||
let lines = read_to_string(path);
|
||||
match lines {
|
||||
Ok(lines) => {
|
||||
for line in lines.lines() {
|
||||
let dec_line = mc.decrypt_base64_to_string(&line);
|
||||
match dec_line {
|
||||
Ok(line) => {
|
||||
decrypted = decrypted.to_owned() + line.as_str() + "\n";
|
||||
return decrypted;
|
||||
},
|
||||
Err(_) => {
|
||||
println!("Что-то пошло не так!");
|
||||
}
|
||||
}
|
||||
}
|
||||
return String::new();
|
||||
},
|
||||
Err(_) => {
|
||||
println!("Что-то не так...");
|
||||
return String::new();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn check_or_create_tasks_file(app_handle: tauri::AppHandle) {
|
||||
let mut path = app_handle.path_resolver().app_local_data_dir().unwrap();
|
||||
path.push("ToDo");
|
||||
path.push("tasks");
|
||||
|
||||
path.set_extension("enc");
|
||||
|
||||
let exist: bool = Path::new(&path).exists();
|
||||
if exist{
|
||||
let content = read_to_string(path);
|
||||
return match content {
|
||||
Ok(_) => {},
|
||||
Err(_) => {
|
||||
println!("Не удалось открыть конфигурационный файл!");
|
||||
}
|
||||
}
|
||||
} else{
|
||||
let path = Path::new(&path);
|
||||
let prefix = path.parent().unwrap();
|
||||
let file = std::fs::create_dir_all(prefix);
|
||||
match file{
|
||||
Ok(_) => {},
|
||||
Err(err) => println!("Не удалось создать директории! \n{}", err)
|
||||
}
|
||||
let file = File::create(path);
|
||||
match file{
|
||||
Ok(_) => {
|
||||
let data = String::from("{\
|
||||
\"id\": 0,\
|
||||
\"tasks\": {}\
|
||||
}");
|
||||
encrypt_n_save_file(path.into(), data);
|
||||
},
|
||||
Err(err) => println!("Не удалось создать файл! \n{}", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_tasks(app_handle: tauri::AppHandle) -> Value {
|
||||
let mut path = app_handle.path_resolver().app_local_data_dir().unwrap();
|
||||
path.push("ToDo");
|
||||
path.push("tasks");
|
||||
|
||||
path.set_extension("enc");
|
||||
|
||||
let content = decrypt_file(path);
|
||||
let data: Value = serde_json::from_str(content.as_str()).unwrap();
|
||||
|
||||
let res = &data["tasks"];
|
||||
|
||||
return res.clone();
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn search_tasks(app_handle: tauri::AppHandle, value: String) -> Value {
|
||||
let mut path = app_handle.path_resolver().app_local_data_dir().unwrap();
|
||||
path.push("ToDo");
|
||||
path.push("tasks");
|
||||
|
||||
path.set_extension("enc");
|
||||
|
||||
let content = decrypt_file(path);
|
||||
let data: Value = serde_json::from_str(content.as_str()).unwrap();
|
||||
|
||||
let mut tasks = vec![];
|
||||
|
||||
let binding = data.clone();
|
||||
for (_key, value) in binding["tasks"].as_object().unwrap() {
|
||||
tasks.push(value["name"].as_str().unwrap().to_lowercase());
|
||||
}
|
||||
|
||||
let tasks_str: Vec<&str> = tasks.iter().map(|s| &**s).collect();
|
||||
|
||||
let n : usize = 5;
|
||||
let binding = value.to_lowercase();
|
||||
let res : Vec<(&str, f32)> = fuzzy_search_best_n(&binding, &tasks_str, n);
|
||||
|
||||
let mut result = json!({});
|
||||
|
||||
let res1 = res.clone();
|
||||
let binding1 = data.clone();
|
||||
for (name, score) in res1 {
|
||||
if score != 0.0 {
|
||||
for (key, value) in binding1["tasks"].as_object().unwrap() {
|
||||
if value.get("name").unwrap().as_str().unwrap().to_lowercase().as_str() == name {
|
||||
result[key] = binding1["tasks"].get(key).unwrap().clone();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn add_task(app_handle: tauri::AppHandle, date: String, time: String, name: String, description: String, priority: i32) {
|
||||
let mut path = app_handle.path_resolver().app_local_data_dir().unwrap();
|
||||
path.push("ToDo");
|
||||
path.push("tasks");
|
||||
|
||||
path.set_extension("enc");
|
||||
|
||||
let content = decrypt_file(path.clone());
|
||||
let mut data: Value = serde_json::from_str(content.as_str()).unwrap();
|
||||
|
||||
let pending = data.clone();
|
||||
let id = pending["id"].as_u64().unwrap();
|
||||
|
||||
let task = json!({
|
||||
"id": id.to_string(),
|
||||
"date": date,
|
||||
"time": time,
|
||||
"name": name,
|
||||
"description": description,
|
||||
"priority": priority,
|
||||
"completed": false
|
||||
});
|
||||
|
||||
data["id"] = (id + 1).into();
|
||||
|
||||
data["tasks"][id.to_string()] = task;
|
||||
encrypt_n_save_file(path.into(), data.to_string());
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn edit_task(app_handle: tauri::AppHandle, id_task: String, name: String, description: String) {
|
||||
let mut path = app_handle.path_resolver().app_local_data_dir().unwrap();
|
||||
path.push("ToDo");
|
||||
path.push("tasks");
|
||||
|
||||
path.set_extension("enc");
|
||||
|
||||
let content = decrypt_file(path.clone());
|
||||
let mut data: Value = serde_json::from_str(content.as_str()).unwrap();
|
||||
data["tasks"][id_task.clone()]["name"] = json!(name);
|
||||
data["tasks"][id_task]["description"] = json!(description);
|
||||
|
||||
encrypt_n_save_file(path.into(), data.to_string());
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn delete_task(app_handle: tauri::AppHandle, id_task: String) {
|
||||
let mut path = app_handle.path_resolver().app_local_data_dir().unwrap();
|
||||
path.push("ToDo");
|
||||
path.push("tasks");
|
||||
|
||||
path.set_extension("enc");
|
||||
|
||||
let content = decrypt_file(path.clone());
|
||||
let mut data: Value = serde_json::from_str(content.as_str()).unwrap();
|
||||
|
||||
let tasks = data["tasks"].as_object_mut().unwrap();
|
||||
let binding = tasks.clone();
|
||||
for (key, value) in binding{
|
||||
if id_task == value["id"] {
|
||||
tasks.remove(&key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
data["tasks"] = json!(tasks);
|
||||
encrypt_n_save_file(path.into(), data.to_string());
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn set_task_field(app_handle: tauri::AppHandle, id_task: String, field: String, value: String) {
|
||||
let mut path = app_handle.path_resolver().app_local_data_dir().unwrap();
|
||||
path.push("ToDo");
|
||||
path.push("tasks");
|
||||
|
||||
path.set_extension("enc");
|
||||
|
||||
let content = decrypt_file(path.clone());
|
||||
let mut data: Value = serde_json::from_str(content.as_str()).unwrap();
|
||||
data["tasks"][id_task][field] = json!(value);
|
||||
|
||||
encrypt_n_save_file(path.into(), data.to_string());
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"build": {
|
||||
"beforeDevCommand": "npm run dev",
|
||||
"beforeBuildCommand": "npm run build",
|
||||
"devPath": "http://localhost:1420",
|
||||
"distDir": "../dist"
|
||||
},
|
||||
"package": {
|
||||
"productName": "to-do-app",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"tauri": {
|
||||
"allowlist": {
|
||||
"all": false,
|
||||
"shell": {
|
||||
"all": false,
|
||||
"open": true
|
||||
},
|
||||
"window": {
|
||||
"all": false,
|
||||
"close": true,
|
||||
"hide": true,
|
||||
"show": true,
|
||||
"maximize": true,
|
||||
"minimize": true,
|
||||
"unmaximize": true,
|
||||
"unminimize": true,
|
||||
"startDragging": true
|
||||
}
|
||||
},
|
||||
"windows": [
|
||||
{
|
||||
"title": "To Do List",
|
||||
"width": 800,
|
||||
"height": 600,
|
||||
"decorations": false
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": null
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"identifier": "com.a-dot.dev",
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||