Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 1 addition & 30 deletions taskoo-cli/src/commands/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,7 @@ pub struct Delete;
impl Delete {
pub fn delete(delete_config: &Vec<String>) -> Result<String, CoreError> {
info!("Process delete command!");
let mut task_ids: Vec<i64> = vec![];

if delete_config.len() == 1 {
if delete_config[0].contains("..") {
let ranged_selection = delete_config[0].split("..").collect::<Vec<&str>>();
if ranged_selection.len() != 2 {
eprintln!("Invalid range provided {}", delete_config[0]);
}
let start = ranged_selection[0]
.parse::<i64>()
.expect("Can't find valid start from provided range");
let end = ranged_selection[1]
.parse::<i64>()
.expect("Can't find valid end from provided range");
task_ids = (start..=end).collect::<Vec<i64>>();
} else {
task_ids.push(delete_config[0].parse().expect("Invalid task id provided"));
}
} else {
for item in delete_config.iter() {
task_ids.push(item.parse().expect("Invalid task id provided"));
}
}

debug!("Running DeleteOperation with {:?}", task_ids);
let mut operation = DeleteOperation {
database_manager: None,
task_ids: task_ids,
result: None
};
let mut operation = DeleteOperation::new(delete_config)?;

execute(&mut operation)?;
Ok(String::new())
Expand Down
77 changes: 52 additions & 25 deletions taskoo-cli/src/commands/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use anyhow::Result;

use taskoo_core::core::Operation;
use taskoo_core::operation::{execute, Get as GetOp};
use taskoo_core::command::{SimpleCommand, TagCommand};

use crate::error::ClientError;

Expand All @@ -15,8 +16,18 @@ impl Info {
Info
}

pub fn run(&self, task_id: &u64, attribute: &Option<String>) -> Result<String, ClientError> {
pub fn run(
&self,
task_id: &Option<u64>,
attribute: &Option<String>,
) -> Result<String, ClientError> {
info!("Running info command");
if task_id.is_none() && attribute.is_none() {
return Err(ClientError::MissingAttrError {
attr: String::from("None of task_id or attribute is provided"),
backtrace: Backtrace::capture(),
});
}
// let task_id = match matches.value_of("task_id") {
// Some(raw_task_id) => raw_task_id.parse::<i64>().map_err(|_error| {
// ClientError::ParseError(String::from(raw_task_id), String::from("i64"))
Expand All @@ -29,33 +40,49 @@ impl Info {
// }
// };

let id: i64 = if *task_id > std::i64::MAX as u64 {
return Err(ClientError::MissingAttrError {
attr: String::from(""),
backtrace: Backtrace::capture(),
});
} else {
*task_id as i64
};
info!("Task id: {:?}", task_id);
let mut operation = GetOp::new();
operation.task_id = Some(id);
execute(&mut operation)?;

let tasks = &operation.get_result();
if tasks.is_empty() {
return Err(ClientError::UnexpectedFailure(
String::from(format!("Unable to find task with id : {}", task_id)),
Backtrace::capture(),
));
}
if let Some(id) = task_id {
if *id > std::i64::MAX as u64 {
return Err(ClientError::MissingAttrError {
attr: String::from("Provided task_id is greater than i64::MAX"),
backtrace: Backtrace::capture(),
});
}

let real_id = *id as i64;
info!("Task id: {:?}", real_id);
let mut operation = GetOp::new();
operation.task_id = Some(real_id);
execute(&mut operation)?;

assert_eq!(tasks.len(), 1);
let tasks = &operation.get_result();
if tasks.is_empty() {
return Err(ClientError::UnexpectedFailure(
String::from(format!("Unable to find task with id : {}", real_id)),
Backtrace::capture(),
));
}

assert_eq!(tasks.len(), 1);

if let Some(attr) = attribute {
println!("{}", tasks[0].get_property_value(attr)?);
} else {
println!("{:?}", tasks[0]);
}
return Ok(String::new());
}

if let Some(attr) = attribute {
println!("{}", tasks[0].get_property_value(attr)?);
} else {
println!("{:?}", tasks[0]);
match attr.as_str() {
"tag" => {
let mut tag_command = TagCommand::new()?;
let tags = tag_command.get_all()?;
println!("{:?}", tags);
}
_ => {
// Should crash
}
}
}
Ok(String::new())
}
Expand Down
37 changes: 23 additions & 14 deletions taskoo-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ fn handle_result(result: Result<String, anyhow::Error>) {
}
}

#[derive(Debug)]
struct InfoCommand {
task_id: Option<u64>,
attribute: Option<String>,
}

// Note: this requires the `derive` feature
use clap::Parser;
#[derive(Parser)]
Expand Down Expand Up @@ -104,14 +110,9 @@ enum Commands {
end_day: Option<String>,
},
/// Show information about the given task
Info {
task_id: u64,
attribute: Option<String>,
},
Info { input: String },
/// Clean context, tag or state
Clean {
provided_type: String
},
Clean { provided_type: String },
/// Change the state of the given tasks to 'start'
Start { task_ids: Vec<u64> },
/// Change the state of the given tasks to 'complete'
Expand Down Expand Up @@ -159,18 +160,26 @@ fn main() -> Result<(), ClientError> {
.agenda(&start_day, &end_day)
.context("agenda command failed to operate"),
),
Commands::Info { task_id, attribute } => {
Commands::Info { input } => {
let mut info_command = InfoCommand {
task_id: None,
attribute: None,
};

// Try to parse the input as a task_id (u64), otherwise treat it as an attribute
if let Ok(task_id) = input.parse::<u64>() {
info_command.task_id = Some(task_id);
} else {
info_command.attribute = Some(input.clone());
}
let info = Info::new();
handle_result(
info.run(task_id, attribute)
info.run(&info_command.task_id, &info_command.attribute)
.context("info command failed to operate"),
);
},
}
Commands::Clean { provided_type } => {
handle_result(
Clean::run(provided_type)
.context("clean command failed to operate"),
);
handle_result(Clean::run(provided_type).context("clean command failed to operate"));
}
Commands::Start { task_ids } => handle_result(
StateChanger::to_started()
Expand Down
1 change: 1 addition & 0 deletions taskoo-core/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ impl<'a> SimpleCommand<'a> for TagCommand<'a> {
}

fn delete(&mut self, names: Vec<String>) -> Result<(), CoreError> {
println!("got here with names {:?}", names);
let tx = match self.db_manager.as_mut() {
Some(manager) => manager.conn.transaction()?,
None => match self.db_manager_for_test.as_mut() {
Expand Down
4 changes: 2 additions & 2 deletions taskoo-core/src/operation/agenda.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use crate::db::task_helper::Task;
use crate::db::task_manager::TaskManager;
use crate::error::*;

/* Some of the view functionalities are overlap with list, however,
* view should provide better API for clients */
/* Some of the Agenda functionalities are overlap with list, however,
* Agenda should provide better API for clients */
pub struct Agenda {
pub start_day: String,
pub end_day: Option<String>,
Expand Down
20 changes: 20 additions & 0 deletions taskoo-core/src/operation/delete.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::core::{ConfigManager, Operation};
use crate::db::task_helper::Task;
use crate::db::task_manager::TaskManager;
use crate::option_parser::parse_command_option;
use crate::error::*;

pub struct DeleteOperation {
Expand All @@ -9,6 +10,24 @@ pub struct DeleteOperation {
pub result: Option<Vec<Task>>,
}

impl DeleteOperation {
pub fn new(input_str: &Vec<String>) -> Result<DeleteOperation, CoreError> {
let option = parse_command_option(
&input_str.iter().map(|s| &**s).collect(),
false,
false,
true,
)
.unwrap();

Ok(DeleteOperation {
task_ids: option.task_ids,
database_manager: None,
result: None,
})
}
}

impl Operation for DeleteOperation {
fn init(&mut self) -> Result<(), InitialError> {
self.database_manager = Some(TaskManager::new(
Expand All @@ -21,6 +40,7 @@ impl Operation for DeleteOperation {
}
fn set_result(&mut self, _result: Vec<Task>) {}
fn get_result(&mut self) -> &Vec<Task> {
// TODO: Store the deleted task ids
return &self.result.as_ref().unwrap();
}
}
37 changes: 33 additions & 4 deletions taskoo-core/src/wasm/exports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,25 @@ pub unsafe fn list(ptr: *mut u8, len: usize) -> *mut c_char {
let data = read_data_from_js(ptr, len);
let mut operations = operation::Get::new2(&data).expect("Failed to create the get operation");

let mut ret: Vec<(String, String)> = vec![];
let mut ret: Vec<(String, &Vec<Task>)> = vec![];

for operation_tuple in operations.iter_mut() {
let serded_string: String = match operation::execute(&mut operation_tuple.1) {
Ok(_) => serde_json::to_string(&operation_tuple.1.get_result()).unwrap(),
Err(e) => e.to_string(),
Ok(_) => {
println!("got ok here");
serde_json::to_string(&operation_tuple.1.get_result()).unwrap()
}
Err(e) => {
println!("got err here");
e.to_string()
}
};

ret.push((operation_tuple.0.to_owned(), serded_string));
println!("serded_string {} ", serded_string);
ret.push((operation_tuple.0.to_owned(), operation_tuple.1.get_result()));
}
let serded_ret: String = serde_json::to_string(&ret).unwrap();
println!("serded_ret {} ", serded_ret);
unsafe { LENGTH = serded_ret.len() }
let s = CString::new(serded_ret).unwrap();
return s.into_raw();
Expand Down Expand Up @@ -113,6 +121,7 @@ pub unsafe fn agenda(ptr: *mut u8, len: usize) -> *mut c_char {
Err(e) => e.to_string(),
};

println!("serded_ret for agenda {} ", serded_string);
unsafe { LENGTH = serded_string.len() }
let s = CString::new(serded_string).unwrap();
return s.into_raw();
Expand All @@ -134,3 +143,23 @@ pub unsafe fn state_change(ptr: *mut u8, len: usize) -> *mut c_char {
let s = CString::new(serded_string).unwrap();
return s.into_raw();
}

// Delete Operation
#[no_mangle]
pub unsafe fn delete(ptr: *mut u8, len: usize) {
println!("delete in wasm");
let data = read_data_from_js(ptr, len);
let mut operation =
operation::DeleteOperation::new(&data).expect("Failed to create the DeleteOperation");
operation::execute(&mut operation).expect("Failed to execute the operation");

// The following doesn't work because taskoo-core doesn't store the delete task ids

// let deleted_tasks = &operation.get_result();
// let serded_ret: String = serde_json::to_string(&deleted_tasks).unwrap();
// println!("serded_ret {} for delete", serded_ret);
// unsafe { LENGTH = serded_ret.len() }
// let s = CString::new(serded_ret).unwrap();
// Return the delete tasks back to clients
// return s.into_raw();
}
10 changes: 10 additions & 0 deletions taskoo-web/server/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,16 @@ export class Endpoints {
instance.exports.add(allocated.ptr, allocated.bytes.length);
}

static Delete(input) {
const allocated = allocateInput(input);
const offset = instance.exports.delete(allocated.ptr, allocated.bytes.length);
const len = instance.exports.get_shared_buffer_size();
const buffer = new Uint8Array(instance.exports.memory.buffer, offset, len);
const data = new TextDecoder().decode(buffer);
instance.exports.free_shared_buffer(offset);
return data;
}

static StateChange(input) {
const allocated = allocateInput(input);

Expand Down
16 changes: 16 additions & 0 deletions taskoo-web/server/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*'); // Allow from any origin
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});

const ENDPOINTS = {};
const server = app.listen(7001, () => {
Expand All @@ -20,19 +25,25 @@ app.get('/today', (req, res) => {
});

app.post('/list', (req, res) => {
console.log("Taskoo server: list endpoint");
const data = Endpoints.List(req.body.data);
console.log("Taskoo server: list endpoint, got data");
console.log(data);
let ret;
try {
ret = JSON.parse(data);
console.log("parsed success");
} catch(e) {
ret = {"error": data};
console.log("parsed failed");
}
res.send(ret);
});

app.post('/agenda', (req, res) => {
console.log("Taskoo server: agenda endpoint");
const data = Endpoints.Agenda(req.body.data);
console.log(data);
let ret;
try {
ret = JSON.parse(data);
Expand Down Expand Up @@ -61,3 +72,8 @@ app.post('/state_change', createPost, (req, res) => {
console.log("state_change endpoint");
Endpoints.StateChange(req.body.data);
});

app.post('/delete', createPost, (req, res) => {
console.log("delete endpoint");
Endpoints.Delete(req.body.data);
});
Binary file modified taskoo-web/server/taskoo_core.wasm
Binary file not shown.
Loading
Loading