-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtodoist2org_convert.py
110 lines (93 loc) · 3.86 KB
/
todoist2org_convert.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/usr/bin/python3
#
# MIT License
#
# Copyright (c) 2016 Dane Finlay
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
"""
todoist2org_convert
This program retrieves Todoist projects, sections and items using the 'Sync' API
(v9) and converts them into Org mode headings. Each heading is written to stdout or
to the specified output file. An Org mode file header is written before the headings.
"""
import argparse
import logging
import os
import sys
import todoist2org
def _valid_api_token(string): # argparse helper function
if len(string) != 40:
msg = "%r is not a valid API token" % string
raise argparse.ArgumentTypeError(msg)
return string
def _main():
# Define command-line arguments.
parser = argparse.ArgumentParser(
description="Retrieve and convert Todoist projects, sections and items into "
"Org mode headings and write them to stdout or to the specified "
"output file."
)
parser.add_argument(
"api_token", type=_valid_api_token,
help="40 character Todoist API token found under Settings->Integrations."
)
parser.add_argument(
"-o", "--output-file", type=argparse.FileType("w"),
help="Output file path."
)
parser.add_argument(
"-a", "--include-archived", default=False, action="store_true",
help="Included archived projects in the output."
)
# Parse command-line arguments from sys.argv.
args = parser.parse_args()
# Set up logging.
logging.basicConfig(format="%(levelname)s: %(message)s")
log = logging.getLogger()
# Use the API token to sync user resources (state).
todoist_state = todoist2org.sync_todoist_state(args.api_token)
# Check if the sync was unsuccessful. This can happen if the API token was
# invalid.
if "sync_token" not in todoist_state:
log.error("Failed to sync Todoist data. Please check your API token.")
log.error("Data received: %r", todoist_state)
exit(1)
# If a file path was specified, then write to that file. Otherwise, write to
# stdout.
output_file = args.output_file
if output_file and output_file.name != "<stdout>":
# Get the title to use in the file header.
base = os.path.basename(output_file.name)
title = os.path.splitext(base)[0]
else:
title = "Converted Todoist Projects"
output_file = sys.stdout
# Use the retrieved data to generate an Org mode file header followed by each
# heading.
with output_file as out:
for line in todoist2org.generate_file_header(todoist_state, title):
out.write(line + "\n")
out.write("\n")
for heading in todoist2org.generate_all_headings(todoist_state,
args.include_archived):
out.write(heading + "\n")
if __name__ == '__main__':
_main()