-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathadd_to_module.py
194 lines (179 loc) · 8.88 KB
/
add_to_module.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import sys
import argparse
import os.path
from api import get_course, split_url, find_module, page_exists, get_file
from add_module import create_module, get_module_url, publish_module
def parse_args(args):
# help text and argument parser
# solution based on https://stackoverflow.com/a/24181138/462692
desc = '\n'.join(["Adds an existing file or page on Canvas, or a hyperlink, \
to a module in the same course.",
"An optional argument -c/--config_file can be used with the path to the config file. "
"Otherwise the default config file '~/.config/canvasapi.conf' will be used.\n"
])
parser = argparse.ArgumentParser(description=desc)
required_named = parser.add_argument_group('required named arguments')
required_named.add_argument("-u", "--url", help="The full url of the page \
on Canvas that will be added to the module.", required = True)
required_named.add_argument("-t", "--title", help="The title (name) of the \
module that will be updated, enclosed in quotation marks if it \
contains one or more spaces", required = True)
parser.add_argument("-lt", "--linktitle", help="The title (name) of the link to be added, enclosed in quotation marks if it \
contains one or more spaces.")
parser.add_argument("-lu", "--linkurl", help="The URL (hyperlink address) of the link to be added.")
parser.add_argument("-ext", "--externaltool", help="Add the URL as an \
External Tool (defaul: add as a regular hyperlink).", action='store_true')
parser.add_argument("--create", help="If the module does not exist yet, \
create it before adding the page (default: off, and warn instead)", action='store_true')
parser.add_argument("-p", "--publish", help="Publish the module on Canvas \
at the time of creation (default: leave unpublished)", action='store_true')
parser.add_argument("--force", help="If the page has already been added, \
add it another time to the module anyway (default: off)", action='store_true')
parser.add_argument("--ignore", help="If the page has already been added, \
ignore this fact and exit without error (default: off)", action='store_true')
parser.add_argument("-cf", "--config_file", help="Path to config file", \
default = '~/.config/canvasapi.conf')
args = parser.parse_args(args)
return args
def item_is_added_to_module(module, item, item_id, url_type):
"""
Tests whether an item has already been added to a module
item is a page, file or hyperlink (ExternalUrl or ExternalTool).
"""
for module_item in module.get_module_items():
# module_item.type is capitalised
module_item_type = module_item.type.lower()
# only compare items of same type
if module_item_type == url_type:
if module_item_type == 'page':
# pages have a unique title
module_item_id = module_item.title
# compare the IDs
if module_item.title == item_id:
return True
elif module_item_type in ["externalurl", "externaltool"]:
if module_item.title == item or module_item.external_url == item_id:
return True
else:
# FIXME change to elif probably elif module_item_type == 'file':
# files have a unique ID,
# which for a file in a module is the content_id
module_item_id = module_item.content_id
# compare the IDs
if module_item_id == item_id:
return True
# else: print(module_item.type.lower(), module_item.title)
return False
def main(args):
args = parse_args(args)
# extract course information from url and get course
API_URL, course_id, item_name, url_type = split_url(args.url)
course = get_course(API_URL, course_id, args.config_file)
# find the module, if any
module_name = args.title
module = find_module(course, module_name)
if url_type == 'page':
# check whether page to add actually exists
# if so, get it
if page_exists(course, item_name):
item_to_add = course.get_page(item_name)
# pages have a unique title
item_id = item_to_add.title
else:
sys.exit("Error: could not find page '%s' on Canvas.\nFull url: %s" % (item_name, args.url))
elif url_type == 'file':
# get file to add if it actually exists
# if not, becomes False
item_to_add = get_file(course, item_name)
if not item_to_add:
sys.exit("Error: could not find file '%s' on Canvas.\nFull url: %s" % (item_name, args.url))
# files have a unique ID
item_id = item_to_add.id
elif url_type == "url only" and args.linkurl:
# ignore existing links till later
pass
else:
sys.exit(f"Error: unexpected type of item to add: '{url_type}', expected 'file' or 'page': {args.url}")
# create the module if necessary
if not module:
# module does not exist
if not args.create:
sys.exit("Could not find module '%s' on Canvas" % module_name)
else:
# create module, publish if requested
module = create_module(course, module_name)
module_url = get_module_url(module.items_url)
print(f"Sucessfully added module '{module.name}'. Full url: {module_url}.")
if args.publish:
publish_module(module)
if url_type in ['page', 'file']:
# check whether page already added to module
if item_is_added_to_module(module, item_to_add, item_id, url_type):
if not args.force and not args.ignore:
message = f"Error: {url_type} '{item_name}' "
message += f"already added to module '{module.name}'.\n"
message += "To add anyway, use '--force'\n"
sys.exit(message)
elif args.ignore:
message = f"Warning: {url_type} '{item_name}' "
message += f"already added to module '{module.name}'.\n"
message += "Ignoring...\n"
print(message)
sys.exit(0)
elif url_type == "url only" and args.linkurl:
if args.externaltool:
url_type = "externaltool"
else:
url_type = "externalurl"
if item_is_added_to_module(module, item = args.linktitle, item_id = args.linkurl, url_type = url_type):
if not args.force and not args.ignore:
message = f"Error: URL {args.linkurl} with name '{args.linktitle}' "
message += f"already added to module '{module.name}'.\n"
message += "To add anyway, use '--force'\n"
sys.exit(message)
elif args.ignore:
message = f"Warning: URL {args.linkurl} with name '{args.linktitle}' "
message += f"already added to module '{module.name}'.\n"
message += "Ignoring...\n"
print(message)
sys.exit(0)
# update the module
if url_type == 'page':
try:
# not sure what to add for content_id but "" works
new_module_item = module.create_module_item(module_item = {
"type" : "Page",
"content_id" : "",
"page_url": item_to_add.url
})
print("Sucessfully added page '%s' to module '%s'." %(item_name, module_name))
except Exception as e:
sys.exit("Could not add page '%s' to module '%s':\n%s." %(item_name, module_name, str(e)))
elif url_type == 'file':
try:
new_module_item = module.create_module_item(module_item = {
"type" : "File",
"content_id":item_to_add.id,
})
print("Sucessfully added file '%s' to module '%s'." %(item_name, module_name))
except Exception as e:
sys.exit("Could not add file '%s' to module '%s':\n%s." %(item_name, module_name, str(e)))
elif url_type in ["externalurl", "externaltool"]:
module_item = {
"title" : args.linktitle,
"external_url" : args.linkurl,
"new_tab" : True,
}
if args.externaltool:
# not sure what to add for content_id but "" works
module_item["type"] = "ExternalTool"
module_item["content_id"] = ""
else:
module_item["type"] = "ExternalUrl"
try:
new_module_item = module.create_module_item(module_item = module_item)
print("Sucessfully added %s '%s' with title '%s' to module '%s'." %(module_item["type"], args.linkurl, args.linktitle, module_name))
except Exception as e:
sys.exit("Could not add url '%s' to module '%s':\n%s." %(args.linkurl, module_name, str(e)))
if __name__ == "__main__":
main(sys.argv[1:])