Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable calendar deletion #8

Open
wants to merge 27 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9366713
Run `cargo fmt` with default settings
Aug 3, 2024
8bf4af6
cargo clippy --fix
Aug 13, 2024
9aa05e8
Resolve most (but not all) lints
Aug 13, 2024
e380986
Back out one "fix" that caused a compile error in an example
Aug 13, 2024
f317181
Add thiserror dependency
Aug 14, 2024
52bf7c8
Use an error enum for cached calendar; use an expect in place of retu…
Aug 14, 2024
a3fa36e
Use error enum in remote calendar
Aug 14, 2024
89ce44f
Replace almost all remaining String errors with custom error enums us…
Aug 14, 2024
1275a09
Allow calendar name to be set
Aug 15, 2024
b9a8a05
Make get_cal_home_set public
Aug 15, 2024
1e111f5
Begin moving away from Box<dyn Error> to explicit errors built using …
Aug 17, 2024
ea50531
Another burst of Box<dyn Error> -> thiserror-based-error transition
Aug 17, 2024
a541fbd
get_item_version_tags -> KFResult
Aug 17, 2024
b045a29
Remove unused import
Aug 17, 2024
04e4d01
Remove superflous .into's
Aug 17, 2024
65a7d56
get_item_by_url -> KFResult
Aug 17, 2024
80a0a85
get_items_by_url -> KFResult
Aug 17, 2024
f007789
get_item_urls -> KFResult
Aug 17, 2024
9d6f201
Fix some lints
Aug 17, 2024
17015af
Finish initial move away from Box<dyn Error>
Aug 17, 2024
aae4b27
Eliminate no-longer-needed GenericError in hopes of becoming Send
Aug 17, 2024
fcfb199
Allow deletion of calendars
Aug 17, 2024
2c01042
Adapt calendar deletion to KFResult / KFError
Aug 17, 2024
718b07a
mark_for_deletion -> mark_item_for_deletion to disambiguate
Aug 17, 2024
38fd246
Adopt the more sensible strategy of marking a calendar for deletion, …
Aug 17, 2024
22ca508
Delete the .cal file in cache when the corresponding calendar is dele…
Aug 18, 2024
34e56b5
Support relationships (including parents) in tasks
Aug 20, 2024
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
51 changes: 35 additions & 16 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ serde_json = "1.0"
async-trait = "0.1"
uuid = { version = "0.8", features = ["v4"] }
sanitize-filename = "0.3"
http = "0.2.6"
ical-daladim = { version = "0.8", features = ["serde-derive"] }
ics = "0.5"
chrono = { version = "0.4", features = ["serde"] }
csscolorparser = { version = "0.5", features = ["serde"] }
once_cell = "1.8"
itertools = "0.10"
thiserror = "1.0.63"
118 changes: 82 additions & 36 deletions examples/provider-sync.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,45 @@
//! This is an example of how kitchen-fridge can be used

use chrono::{Utc};
use chrono::Utc;
use url::Url;

use kitchen_fridge::traits::CalDavSource;
use kitchen_fridge::calendar::SupportedComponents;
use kitchen_fridge::Item;
use kitchen_fridge::Task;
use kitchen_fridge::task::CompletionStatus;
use kitchen_fridge::CalDavProvider;
use kitchen_fridge::traits::BaseCalendar;
use kitchen_fridge::traits::CalDavSource;
use kitchen_fridge::traits::CompleteCalendar;
use kitchen_fridge::utils::pause;
use kitchen_fridge::CalDavProvider;
use kitchen_fridge::Item;
use kitchen_fridge::Task;

mod shared;
use shared::initial_sync;
use shared::{URL, USERNAME, EXAMPLE_EXISTING_CALENDAR_URL, EXAMPLE_CREATED_CALENDAR_URL};
use shared::{EXAMPLE_CREATED_CALENDAR_URL, EXAMPLE_EXISTING_CALENDAR_URL, URL, USERNAME};

const CACHE_FOLDER: &str = "test_cache/provider_sync";


#[tokio::main]
async fn main() {
env_logger::init();

println!("This example show how to sync a remote server with a local cache, using a Provider.");
println!("Make sure you have edited the constants in the 'shared.rs' file to include correct URLs and credentials.");
println!("You can also set the RUST_LOG environment variable to display more info about the sync.");
println!("");
println!(
"You can also set the RUST_LOG environment variable to display more info about the sync."
);
println!();
println!("This will use the following settings:");
println!(" * URL = {}", URL);
println!(" * USERNAME = {}", USERNAME);
println!(" * EXAMPLE_EXISTING_CALENDAR_URL = {}", EXAMPLE_EXISTING_CALENDAR_URL);
println!(" * EXAMPLE_CREATED_CALENDAR_URL = {}", EXAMPLE_CREATED_CALENDAR_URL);
println!(
" * EXAMPLE_EXISTING_CALENDAR_URL = {}",
EXAMPLE_EXISTING_CALENDAR_URL
);
println!(
" * EXAMPLE_CREATED_CALENDAR_URL = {}",
EXAMPLE_CREATED_CALENDAR_URL
);
pause();

let mut provider = initial_sync(CACHE_FOLDER).await;
Expand All @@ -47,32 +54,56 @@ async fn add_items_and_sync_again(provider: &mut CalDavProvider) {
// Create a new calendar...
let new_calendar_url: Url = EXAMPLE_CREATED_CALENDAR_URL.parse().unwrap();
let new_calendar_name = "A brave new calendar".to_string();
if let Err(_err) = provider.local_mut()
.create_calendar(new_calendar_url.clone(), new_calendar_name.clone(), SupportedComponents::TODO, Some("#ff8000".parse().unwrap()))
.await {
println!("Unable to add calendar, maybe it exists already. We're not adding it after all.");
if let Err(_err) = provider
.local_mut()
.create_calendar(
new_calendar_url.clone(),
new_calendar_name.clone(),
SupportedComponents::TODO,
Some("#ff8000".parse().unwrap()),
)
.await
{
println!("Unable to add calendar, maybe it exists already. We're not adding it after all.");
}

// ...and add a task in it
let new_name = "This is a new task in a new calendar";
let new_task = Task::new(String::from(new_name), true, &new_calendar_url);
provider.local().get_calendar(&new_calendar_url).await.unwrap()
.lock().unwrap().add_item(Item::Task(new_task)).await.unwrap();

provider
.local()
.get_calendar(&new_calendar_url)
.await
.unwrap()
.lock()
.unwrap()
.add_item(Item::Task(new_task))
.await
.unwrap();

// Also create a task in a previously existing calendar
let changed_calendar_url: Url = EXAMPLE_EXISTING_CALENDAR_URL.parse().unwrap();
let new_task_name = "This is a new task we're adding as an example, with ÜTF-8 characters";
let new_task = Task::new(String::from(new_task_name), false, &changed_calendar_url);
let new_url = new_task.url().clone();
provider.local().get_calendar(&changed_calendar_url).await.unwrap()
.lock().unwrap().add_item(Item::Task(new_task)).await.unwrap();


if provider.sync().await == false {
provider
.local()
.get_calendar(&changed_calendar_url)
.await
.unwrap()
.lock()
.unwrap()
.add_item(Item::Task(new_task))
.await
.unwrap();

if !(provider.sync().await) {
log::warn!("Sync did not complete, see the previous log lines for more info. You can safely start a new sync. The new task may not have been synced.");
} else {
println!("Done syncing the new task '{}' and the new calendar '{}'", new_task_name, new_calendar_name);
println!(
"Done syncing the new task '{}' and the new calendar '{}'",
new_task_name, new_calendar_name
);
}
provider.local().save_to_folder().unwrap();

Expand All @@ -82,18 +113,26 @@ async fn add_items_and_sync_again(provider: &mut CalDavProvider) {
async fn complete_item_and_sync_again(
provider: &mut CalDavProvider,
changed_calendar_url: &Url,
url_to_complete: &Url)
{
url_to_complete: &Url,
) {
println!("\nNow, we'll mark this last task as completed, and run the sync again.");
pause();

let completion_status = CompletionStatus::Completed(Some(Utc::now()));
provider.local().get_calendar(changed_calendar_url).await.unwrap()
.lock().unwrap().get_item_by_url_mut(url_to_complete).await.unwrap()
provider
.local()
.get_calendar(changed_calendar_url)
.await
.unwrap()
.lock()
.unwrap()
.get_item_by_url_mut(url_to_complete)
.await
.unwrap()
.unwrap_task_mut()
.set_completion_status(completion_status);

if provider.sync().await == false {
if !(provider.sync().await) {
log::warn!("Sync did not complete, see the previous log lines for more info. You can safely start a new sync. The new task may not have been synced.");
} else {
println!("Done syncing the completed task");
Expand All @@ -106,17 +145,24 @@ async fn complete_item_and_sync_again(
async fn remove_items_and_sync_again(
provider: &mut CalDavProvider,
changed_calendar_url: &Url,
id_to_remove: &Url)
{
id_to_remove: &Url,
) {
println!("\nNow, we'll delete this last task, and run the sync again.");
pause();

// Remove the task we had created
provider.local().get_calendar(changed_calendar_url).await.unwrap()
.lock().unwrap()
.mark_for_deletion(id_to_remove).await.unwrap();

if provider.sync().await == false {
provider
.local()
.get_calendar(changed_calendar_url)
.await
.unwrap()
.lock()
.unwrap()
.mark_item_for_deletion(id_to_remove)
.await
.unwrap();

if !(provider.sync().await) {
log::warn!("Sync did not complete, see the previous log lines for more info. You can safely start a new sync. The new task may not have been synced.");
} else {
println!("Done syncing the deleted task");
Expand Down
Loading