del_all_unused_labels.sh
· 1.5 KiB · Bash
Raw
#!/usr/bin/bash
set -euo pipefail
TMP_JSON_FILE=/tmp/todoist.json.tmp
TMP_ALL_LABELS_FILE=/tmp/all.labels.tmp
TMP_USED_LABELS_FILE=/tmp/used.labels.tmp
TMP_UNUSED_LABELS_FILE=/tmp/unused.labels.tmp
TMP_UNUSED_LABEL_IDS_FILE=/tmp/unused.label.ids.tmp
if [[ -z "${TODOIST_TOKEN:-}" ]]; then
echo "Error: set TODOIST_TOKEN to your Todoist API token" >&2
exit 1
fi
curl https://api.todoist.com/api/v1/sync \
-H "Authorization: Bearer $TODOIST_TOKEN" \
-d sync_token='*' \
-d resource_types='["items", "labels"]' \
> $TMP_JSON_FILE
cat $TMP_JSON_FILE \
| jq -r '.labels[].name' \
| sort \
> $TMP_ALL_LABELS_FILE
cat $TMP_JSON_FILE \
| jq -r '.items[].labels[]' \
| uniq \
| sort \
> $TMP_USED_LABELS_FILE
comm -3 $TMP_ALL_LABELS_FILE $TMP_USED_LABELS_FILE > $TMP_UNUSED_LABELS_FILE
while IFS= read -r name; do
jq -r --arg name "$name" '.labels[] | select(.name == $name) | .id' $TMP_JSON_FILE
done < $TMP_UNUSED_LABELS_FILE > $TMP_UNUSED_LABEL_IDS_FILE
while IFS= read -r id; do
if [ -z "$id" ]; then
continue
fi
echo "Processing ID: $id"
curl https://api.todoist.com/api/v1/sync \
-H "Authorization: Bearer $TODOIST_TOKEN" \
-d commands='[
{
"type": "label_delete",
"uuid": "'"$(uuidgen)"'",
"args": {
"id": "'"$id"'",
"cascade": "none"
}
}]'
done < $TMP_UNUSED_LABEL_IDS_FILE
rm $TMP_JSON_FILE
rm $TMP_ALL_LABELS_FILE
rm $TMP_USED_LABELS_FILE
rm $TMP_UNUSED_LABELS_FILE
rm $TMP_UNUSED_LABEL_IDS_FILE
1 | #!/usr/bin/bash |
2 | set -euo pipefail |
3 | |
4 | TMP_JSON_FILE=/tmp/todoist.json.tmp |
5 | TMP_ALL_LABELS_FILE=/tmp/all.labels.tmp |
6 | TMP_USED_LABELS_FILE=/tmp/used.labels.tmp |
7 | TMP_UNUSED_LABELS_FILE=/tmp/unused.labels.tmp |
8 | TMP_UNUSED_LABEL_IDS_FILE=/tmp/unused.label.ids.tmp |
9 | |
10 | |
11 | if [[ -z "${TODOIST_TOKEN:-}" ]]; then |
12 | echo "Error: set TODOIST_TOKEN to your Todoist API token" >&2 |
13 | exit 1 |
14 | fi |
15 | |
16 | curl https://api.todoist.com/api/v1/sync \ |
17 | -H "Authorization: Bearer $TODOIST_TOKEN" \ |
18 | -d sync_token='*' \ |
19 | -d resource_types='["items", "labels"]' \ |
20 | > $TMP_JSON_FILE |
21 | |
22 | cat $TMP_JSON_FILE \ |
23 | | jq -r '.labels[].name' \ |
24 | | sort \ |
25 | > $TMP_ALL_LABELS_FILE |
26 | |
27 | cat $TMP_JSON_FILE \ |
28 | | jq -r '.items[].labels[]' \ |
29 | | uniq \ |
30 | | sort \ |
31 | > $TMP_USED_LABELS_FILE |
32 | |
33 | comm -3 $TMP_ALL_LABELS_FILE $TMP_USED_LABELS_FILE > $TMP_UNUSED_LABELS_FILE |
34 | |
35 | while IFS= read -r name; do |
36 | jq -r --arg name "$name" '.labels[] | select(.name == $name) | .id' $TMP_JSON_FILE |
37 | done < $TMP_UNUSED_LABELS_FILE > $TMP_UNUSED_LABEL_IDS_FILE |
38 | |
39 | while IFS= read -r id; do |
40 | if [ -z "$id" ]; then |
41 | continue |
42 | fi |
43 | echo "Processing ID: $id" |
44 | curl https://api.todoist.com/api/v1/sync \ |
45 | -H "Authorization: Bearer $TODOIST_TOKEN" \ |
46 | -d commands='[ |
47 | { |
48 | "type": "label_delete", |
49 | "uuid": "'"$(uuidgen)"'", |
50 | "args": { |
51 | "id": "'"$id"'", |
52 | "cascade": "none" |
53 | } |
54 | }]' |
55 | done < $TMP_UNUSED_LABEL_IDS_FILE |
56 | |
57 | rm $TMP_JSON_FILE |
58 | rm $TMP_ALL_LABELS_FILE |
59 | rm $TMP_USED_LABELS_FILE |
60 | rm $TMP_UNUSED_LABELS_FILE |
61 | rm $TMP_UNUSED_LABEL_IDS_FILE |
62 |