@@ -8,6 +8,7 @@ import Protolude as P
8
8
9
9
import Data.Hourglass
10
10
import Data.Text as T
11
+ import qualified Data.Time.ISO8601.Duration as Iso8601
11
12
import Data.ULID
12
13
import Data.Coerce
13
14
import Data.Yaml as Yaml
@@ -421,6 +422,133 @@ parseIsoDuration isoDuration =
421
422
else Nothing
422
423
423
424
425
+ createNextRepetition
426
+ :: Config -> Connection -> Task -> IO (Maybe (Doc ann ))
427
+ createNextRepetition conf connection task = do
428
+ newUlidText <- formatUlid getULID
429
+ let
430
+ taskUlid = primaryKey task
431
+ nowMaybe = ulidTextToDateTime newUlidText
432
+ dueUtcMb = (Task. due_utc task) >>= parseUtc
433
+ showDateTime = pack . timePrint (utcFormat conf)
434
+ repIsoDur = (Task. repetition_duration task) >>= parseIsoDuration
435
+ nextDueMb = liftA2 timeAdd
436
+ (if nowMaybe < dueUtcMb then dueUtcMb else nowMaybe)
437
+ repIsoDur
438
+
439
+ -- TODO: Investigate why this isn't working and replace afterwards
440
+ -- runBeamSqlite connection $ runInsert $
441
+ -- insert (_tldbTasks taskLiteDb) $
442
+ -- insertValues [ task
443
+ -- { Task.ulid = val_ newUlidText
444
+ -- , Task.due_utc = nowMaybe + (Task.repetition_duration task)
445
+ -- }
446
+ -- ]
447
+
448
+ runBeamSqlite connection $ do
449
+ runInsert $ insert (_tldbTasks taskLiteDb) $ insertFrom $ do
450
+ originalTask <- filter_
451
+ (\ theTask -> primaryKey theTask ==. val_ taskUlid)
452
+ (all_ $ _tldbTasks taskLiteDb)
453
+
454
+ pure originalTask
455
+ { Task. ulid = val_ newUlidText
456
+ , Task. due_utc = val_ $ fmap showDateTime nextDueMb
457
+ , Task. awake_utc = val_ $
458
+ fmap showDateTime $ liftA2 timeAdd
459
+ ((Task. awake_utc task) >>= parseUtc)
460
+ repIsoDur
461
+ , Task. ready_utc = val_ $
462
+ fmap showDateTime $ liftA2 timeAdd
463
+ ((Task. ready_utc task) >>= parseUtc)
464
+ repIsoDur
465
+ }
466
+
467
+ -- Duplicate tags
468
+ tags <- runSelectReturningList $ select $
469
+ filter_ (\ tag -> TaskToTag. task_ulid tag ==. val_ taskUlid) $
470
+ all_ (_tldbTaskToTag taskLiteDb)
471
+
472
+ liftIO $ insertTags
473
+ connection
474
+ Nothing
475
+ (TaskUlid newUlidText)
476
+ (fmap TaskToTag. tag tags)
477
+
478
+ liftIO $ pure $ Just $ " ➡️ Created next task"
479
+ <+> dquotes (pretty $ Task. body task)
480
+ <+> " in repetition series" <+> dquotes (pretty $ Task. group_ulid task)
481
+ <+> " with id" <+> dquotes (pretty newUlidText)
482
+
483
+
484
+ createNextRecurrence
485
+ :: Config -> Connection -> Task -> IO (Maybe (Doc ann ))
486
+ createNextRecurrence conf connection task = do
487
+ newUlidText <- formatUlid getULID
488
+ let
489
+ taskUlid = primaryKey task
490
+ dueUtcMb = (Task. due_utc task) >>= parseUtc
491
+
492
+ showDateTime :: DateTime -> Text
493
+ showDateTime = pack . timePrint (utcFormat conf)
494
+
495
+ durTextEither = maybeToEither
496
+ " Task has no recurrence duration"
497
+ (Task. recurrence_duration task)
498
+ isoDurEither =
499
+ durTextEither
500
+ <&> encodeUtf8
501
+ >>= Iso8601. parseDuration
502
+
503
+ showEither e = e
504
+ & (either (const Nothing ) Just )
505
+ <&> utcTimeToDateTime
506
+ <&> showDateTime
507
+
508
+ nextDueMb = liftA2 Iso8601. addDuration isoDurEither
509
+ (maybeToEither " Task has no due UTC" (dueUtcMb <&> dateTimeToUtcTime))
510
+
511
+ runBeamSqlite connection $ do
512
+ runInsert $ insert (_tldbTasks taskLiteDb) $ insertFrom $ do
513
+ originalTask <- filter_
514
+ (\ theTask -> primaryKey theTask ==. val_ taskUlid)
515
+ (all_ $ _tldbTasks taskLiteDb)
516
+
517
+ pure originalTask
518
+ { Task. ulid = val_ newUlidText
519
+ , Task. due_utc = val_ $ nextDueMb & showEither
520
+
521
+ , Task. awake_utc = val_ $
522
+ (liftA2 Iso8601. addDuration isoDurEither
523
+ (maybeToEither " Task has no awake UTC"
524
+ ((Task. awake_utc task) >>= parseUtc <&> dateTimeToUtcTime)))
525
+ & showEither
526
+
527
+ , Task. ready_utc = val_ $
528
+ (liftA2 Iso8601. addDuration isoDurEither
529
+ (maybeToEither " Task has no ready UTC"
530
+ ((Task. ready_utc task) >>= parseUtc <&> dateTimeToUtcTime)))
531
+ & showEither
532
+
533
+ }
534
+
535
+ -- Duplicate tags
536
+ tags <- runSelectReturningList $ select $
537
+ filter_ (\ tag -> TaskToTag. task_ulid tag ==. val_ taskUlid) $
538
+ all_ (_tldbTaskToTag taskLiteDb)
539
+
540
+ liftIO $ insertTags
541
+ connection
542
+ Nothing
543
+ (TaskUlid newUlidText)
544
+ (fmap TaskToTag. tag tags)
545
+
546
+ liftIO $ pure $ Just $ " ➡️ Created next task"
547
+ <+> dquotes (pretty $ Task. body task)
548
+ <+> " in recurrence series" <+> dquotes (pretty $ Task. group_ulid task)
549
+ <+> " with id" <+> dquotes (pretty newUlidText)
550
+
551
+
424
552
doTasks :: Config -> Connection -> Maybe [Text ] -> [Text ] -> IO (Doc AnsiStyle )
425
553
doTasks conf connection noteWordsMaybe ids = do
426
554
docs <- forM ids $ \ idSubstr -> do
@@ -432,61 +560,12 @@ doTasks conf connection noteWordsMaybe ids = do
432
560
then pure $ " ⚠️ Task" <+> dquotes (pretty idText) <+> " is already done"
433
561
else do
434
562
logMessageMaybe <-
435
- if Task. repetition_duration task == Nothing
436
- then pure Nothing
437
- else do
438
- newUlid <- formatUlid getULID
439
- let
440
- nowMaybe = ulidTextToDateTime newUlid
441
- dueUtc = (Task. due_utc task) >>= parseUtc
442
- showDateTime = pack . timePrint (utcFormat conf)
443
- nextDue = liftA2 timeAdd
444
- (if nowMaybe < dueUtc then dueUtc else nowMaybe)
445
- ((Task. repetition_duration task) >>= parseIsoDuration)
446
-
447
- -- TODO: Investigate why this isn't working and replace afterwards
448
- -- runBeamSqlite connection $ runInsert $
449
- -- insert (_tldbTasks taskLiteDb) $
450
- -- insertValues [ task
451
- -- { Task.ulid = val_ newUlid
452
- -- , Task.due_utc = nowMaybe + (Task.repetition_duration task)
453
- -- }
454
- -- ]
455
-
456
- runBeamSqlite connection $ do
457
- runInsert $ insert (_tldbTasks taskLiteDb) $ insertFrom $ do
458
- originalTask <- filter_
459
- (\ theTask -> primaryKey theTask ==. val_ taskUlid)
460
- (all_ $ _tldbTasks taskLiteDb)
461
-
462
- pure originalTask
463
- { Task. ulid = val_ newUlid
464
- , Task. due_utc = val_ $ fmap showDateTime nextDue
465
- , Task. awake_utc = val_ $
466
- fmap showDateTime $ liftA2 timeAdd
467
- ((Task. awake_utc task) >>= parseUtc)
468
- ((Task. repetition_duration task) >>= parseIsoDuration)
469
- , Task. ready_utc = val_ $
470
- fmap showDateTime $ liftA2 timeAdd
471
- ((Task. ready_utc task) >>= parseUtc)
472
- ((Task. repetition_duration task) >>= parseIsoDuration)
473
- }
474
-
475
- -- Duplicate tags
476
- tags <- runSelectReturningList $ select $
477
- filter_ (\ tag -> TaskToTag. task_ulid tag ==. val_ taskUlid) $
478
- all_ (_tldbTaskToTag taskLiteDb)
479
-
480
- liftIO $ insertTags
481
- connection
482
- Nothing
483
- (TaskUlid newUlid)
484
- (fmap TaskToTag. tag tags)
485
-
486
- liftIO $ pure $ Just $ " ➡️ Created next task"
487
- <+> dquotes (pretty $ Task. body task)
488
- <+> " in repetition series"
489
- <+> dquotes (pretty $ Task. group_ulid task)
563
+ if Task. repetition_duration task /= Nothing
564
+ then createNextRepetition conf connection task
565
+ else
566
+ if Task. recurrence_duration task /= Nothing
567
+ then createNextRecurrence conf connection task
568
+ else pure Nothing
490
569
491
570
noteMessageMaybe <- case noteWordsMaybe of
492
571
Nothing -> pure Nothing
@@ -610,6 +689,34 @@ repeatTasks conf connection duration ids = do
610
689
pure $ vsep docs
611
690
612
691
692
+ recurTasks ::
693
+ Config -> Connection -> Iso8601. Duration -> [IdText ] -> IO (Doc AnsiStyle )
694
+ recurTasks conf connection duration ids = do
695
+ docs <- forM ids $ \ idSubstr ->
696
+ execWithTask conf connection idSubstr $ \ task -> do
697
+ let
698
+ taskUlid@ (TaskUlid idText) = primaryKey task
699
+ prettyBody = dquotes (pretty $ Task. body task)
700
+ prettyId = dquotes (pretty idText)
701
+ durationIsoText = decodeUtf8 $ Iso8601. formatDuration duration
702
+
703
+ groupUlid <- formatUlid getULID
704
+
705
+ runBeamSqlite connection $ runUpdate $
706
+ update (_tldbTasks taskLiteDb)
707
+ (\ task_ -> mconcat
708
+ [ (Task. recurrence_duration task_) <-. val_ (Just durationIsoText)
709
+ , (Task. group_ulid task_) <-. val_ (Just groupUlid)
710
+ ])
711
+ (\ task_ -> primaryKey task_ ==. val_ taskUlid)
712
+
713
+ pure $ " 📅 Set recurrence duration of task" <+> prettyBody
714
+ <+> " with id" <+> prettyId
715
+ <+> " to" <+> dquotes (pretty $ durationIsoText)
716
+
717
+ pure $ vsep docs
718
+
719
+
613
720
adjustPriority :: Config -> Float -> [IdText ] -> IO (Doc AnsiStyle )
614
721
adjustPriority conf adjustment ids = do
615
722
dbPath <- getDbPath conf
0 commit comments