4 Commits
Author SHA1 Message Date
klemek aeeabe81c7 chore: 1.7.6
Python Lint CI / ruff (push) Successful in 2m38s
Python Lint CI / ruff-format-check (push) Successful in 3m51s
Python Lint CI / ty (push) Successful in 3m22s
Docker Build / build (push) Successful in 7m56s
TS Lint / ESLint (push) Successful in 4m50s
TS Lint / Oxlint (push) Successful in 3m40s
TS Lint / TypeScript (push) Successful in 3m44s
2026-08-02 09:48:32 +02:00
klemek 87eff715f6 fix: rrule detection 2026-08-02 09:48:28 +02:00
klemek 63c80f0bae chore: 1.7.5
Python Lint CI / ruff (push) Successful in 5m57s
Python Lint CI / ruff-format-check (push) Successful in 6m31s
Python Lint CI / ty (push) Successful in 6m31s
TS Lint / ESLint (push) Successful in 6m1s
TS Lint / Oxlint (push) Successful in 5m17s
Docker Build / build (push) Successful in 14m5s
TS Lint / TypeScript (push) Successful in 5m27s
2026-08-02 09:40:44 +02:00
klemek f36c8ba315 fix: sorting resets 2026-08-02 09:40:41 +02:00
5 changed files with 19 additions and 7 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "tout-doux", "name": "tout-doux",
"version": "1.7.4", "version": "1.7.6",
"private": true, "private": true,
"type": "module", "type": "module",
"engines": { "engines": {
+1 -1
View File
@@ -1,6 +1,6 @@
[project] [project]
name = "tout-doux" name = "tout-doux"
version = "1.7.4" version = "1.7.6"
description = "" description = ""
requires-python = ">=3.14" requires-python = ">=3.14"
dependencies = [ dependencies = [
+6 -2
View File
@@ -22,7 +22,7 @@ export function parseCron(cron: string | null): {
value: 0, value: 0,
date: null, date: null,
}; };
} else if (cron.startsWith("RRULE:") || cron.startsWith("DTSTART:")) { } else if (isRrule(cron)) {
return parseRrule(cron); return parseRrule(cron);
} else if ((value = /^0 (\d+) \* \* \*$/i.exec(cron)) !== null) { } else if ((value = /^0 (\d+) \* \* \*$/i.exec(cron)) !== null) {
return { return {
@@ -75,6 +75,10 @@ export function parseCron(cron: string | null): {
} }
} }
function isRrule(cron: string): boolean {
return cron.startsWith("RRULE:") || cron.startsWith("DTSTART:");
}
export function parseRrule(rule: string): { export function parseRrule(rule: string): {
type: CronType; type: CronType;
value: number; value: number;
@@ -193,7 +197,7 @@ export function nextCronReset(
return null; return null;
} }
try { try {
if (cron.startsWith("RRULE:")) { if (isRrule(cron)) {
try { try {
const rule = new RRule({ const rule = new RRule({
...RRule.parseString(cron), ...RRule.parseString(cron),
+10 -2
View File
@@ -50,6 +50,14 @@ export function taskFutureReset(task: Task): Date | null {
); );
} }
export function taskSortReset(task: Task): Date | null {
let resetDate = taskNextReset(task);
while (resetDate !== null && resetDate.getTime() < new Date().getTime()) {
resetDate = nextCronReset(resetDate, task.reset_cron, task.id);
}
return resetDate;
}
export function taskCompleted(task: Task): boolean { export function taskCompleted(task: Task): boolean {
if (task.check_date === null) { if (task.check_date === null) {
return false; return false;
@@ -94,8 +102,8 @@ export function taskSortFunction(
case SortType.RESET_DATE: case SortType.RESET_DATE:
return (a: Task, b: Task) => return (a: Task, b: Task) =>
(reverse ? -1 : 1) * (reverse ? -1 : 1) *
((taskNextReset(a) ?? fallbackDate(a)).getTime() - ((taskSortReset(a) ?? fallbackDate(a)).getTime() -
(taskNextReset(b) ?? fallbackDate(b)).getTime()); (taskSortReset(b) ?? fallbackDate(b)).getTime());
case SortType.NAME: case SortType.NAME:
return (a: Task, b: Task) => return (a: Task, b: Task) =>
(reverse ? -1 : 1) * a.name.localeCompare(b.name); (reverse ? -1 : 1) * a.name.localeCompare(b.name);
Generated
+1 -1
View File
@@ -323,7 +323,7 @@ asyncpg = [
[[package]] [[package]]
name = "tout-doux" name = "tout-doux"
version = "1.7.4" version = "1.7.6"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "flask", extra = ["async"] }, { name = "flask", extra = ["async"] },