canvas_link_migrator 0.2.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/canvas_link_migrator/link_parser.rb +10 -2
- data/lib/canvas_link_migrator/link_resolver.rb +12 -10
- data/spec/canvas_link_migrator/imported_html_converter_spec.rb +9 -9
- data/spec/canvas_link_migrator/link_resolver_spec.rb +1 -1
- data/spec/fixtures/canvas_resource_map.json +24 -4
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b03a701351cd4f8484cd257bdbbb3e4437ada4d39988d97230e48093e6a8c2a9
|
4
|
+
data.tar.gz: 2fadff9dc0f3a7c0d07ef2d7e79bd20f2e8c9ee14ccf71e4951c89417aa35659
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12d6e3e37c9d8115ce1e47712b0f6192a9d4d6617ec038d8d1b94eb3ec27996f4062d60c75b0b1f26b25675be1738a3dbe121fdc5707c182ca78751f7b47010d
|
7
|
+
data.tar.gz: e9fb1a26ea2aa9b9a24e799f407a05792b26c5743cd919e221e32309d20c49e603a51ec967bf28de51aba60954842793196024d74cae26f232ded871bb55725e
|
@@ -19,6 +19,7 @@
|
|
19
19
|
|
20
20
|
require "nokogiri"
|
21
21
|
require "digest"
|
22
|
+
require "addressable"
|
22
23
|
|
23
24
|
module CanvasLinkMigrator
|
24
25
|
class LinkParser
|
@@ -181,6 +182,12 @@ module CanvasLinkMigrator
|
|
181
182
|
|
182
183
|
# returns a hash with resolution status and data to hold onto if unresolved
|
183
184
|
def parse_url(url, node, attr)
|
185
|
+
url = Addressable::URI.parse(url)
|
186
|
+
query_values = url.query_values || {}
|
187
|
+
media_attachment = query_values.delete("media_attachment") == "true"
|
188
|
+
url.query_values = query_values.present? ? query_values : nil
|
189
|
+
url = url.to_s
|
190
|
+
|
184
191
|
if url =~ /wiki_page_migration_id=(.*)/
|
185
192
|
unresolved(:wiki_page, migration_id: $1)
|
186
193
|
elsif url =~ /discussion_topic_migration_id=(.*)/
|
@@ -191,7 +198,8 @@ module CanvasLinkMigrator
|
|
191
198
|
unresolved(:file_ref,
|
192
199
|
migration_id: $1,
|
193
200
|
rest: $2,
|
194
|
-
in_media_iframe: attr == "src" && ["iframe", "source"].include?(node.name) && node["data-media-id"]
|
201
|
+
in_media_iframe: attr == "src" && ["iframe", "source"].include?(node.name) && node["data-media-id"],
|
202
|
+
media_attachment: media_attachment)
|
195
203
|
elsif url =~ %r{(?:\$CANVAS_OBJECT_REFERENCE\$|\$WIKI_REFERENCE\$)/([^/]*)/([^?]*)(\?.*)?}
|
196
204
|
if KNOWN_REFERENCE_TYPES.include?($1)
|
197
205
|
unresolved(:object, type: $1, migration_id: $2, query: $3)
|
@@ -207,7 +215,7 @@ module CanvasLinkMigrator
|
|
207
215
|
rel_path = URI::DEFAULT_PARSER.unescape($1)
|
208
216
|
if (attr == "href" && node["class"]&.include?("instructure_inline_media_comment")) ||
|
209
217
|
(attr == "src" && ["iframe", "source"].include?(node.name) && node["data-media-id"])
|
210
|
-
unresolved(:media_object, rel_path: rel_path)
|
218
|
+
unresolved(:media_object, rel_path: rel_path, media_attachment: media_attachment)
|
211
219
|
else
|
212
220
|
unresolved(:file, rel_path: rel_path)
|
213
221
|
end
|
@@ -92,7 +92,7 @@ module CanvasLinkMigrator
|
|
92
92
|
# see LinkParser for details
|
93
93
|
rel_path = link[:rel_path]
|
94
94
|
node = Nokogiri::HTML5.fragment(link[:old_value]).children.first
|
95
|
-
new_url = resolve_media_comment_data(node, rel_path)
|
95
|
+
new_url = resolve_media_comment_data(node, rel_path, link[:media_attachment])
|
96
96
|
new_url ||= resolve_relative_file_url(rel_path)
|
97
97
|
|
98
98
|
unless new_url
|
@@ -122,12 +122,15 @@ module CanvasLinkMigrator
|
|
122
122
|
# context prepended to the URL. This prevents
|
123
123
|
# redirects to non cross-origin friendly urls
|
124
124
|
# during a file fetch
|
125
|
-
if rest.include?("icon_maker_icon=1")
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
125
|
+
link[:new_value] = if rest.include?("icon_maker_icon=1")
|
126
|
+
"/files/#{file_id}#{rest}"
|
127
|
+
elsif link[:in_media_iframe] && link[:media_attachment]
|
128
|
+
"/media_attachments_iframe/#{file_id}#{rest}"
|
129
|
+
elsif link[:in_media_iframe]
|
130
|
+
"/media_objects_iframe?mediahref=#{link[:new_value]}"
|
131
|
+
else
|
132
|
+
"#{context_path}/files/#{file_id}#{rest}"
|
133
|
+
end
|
131
134
|
end
|
132
135
|
else
|
133
136
|
raise "unrecognized link_type (#{link[:link_type]}) in unresolved link"
|
@@ -223,14 +226,13 @@ module CanvasLinkMigrator
|
|
223
226
|
url
|
224
227
|
end
|
225
228
|
|
226
|
-
def resolve_media_comment_data(node, rel_path)
|
229
|
+
def resolve_media_comment_data(node, rel_path, media_attachment)
|
227
230
|
if (file = find_file_in_context(rel_path[/^[^?]+/])) # strip query string for this search
|
228
231
|
media_id = file.try(:media_object)&.media_id || file["media_entry_id"]
|
229
232
|
if media_id && media_id != "maybe"
|
230
233
|
if ["iframe", "source"].include?(node.name)
|
231
234
|
node["data-media-id"] = media_id
|
232
|
-
if
|
233
|
-
node.delete("data-is-media-attachment")
|
235
|
+
if media_attachment
|
234
236
|
return media_attachment_iframe_url(file["id"], node["data-media-type"])
|
235
237
|
else
|
236
238
|
return media_iframe_url(media_id, node["data-media-type"])
|
@@ -221,22 +221,22 @@ describe CanvasLinkMigrator::ImportedHtmlConverter do
|
|
221
221
|
end
|
222
222
|
|
223
223
|
it "converts source tags to RCE media attachment iframes" do
|
224
|
-
test_string = %(<video style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-stuff"><source src="$
|
225
|
-
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-
|
224
|
+
test_string = %(<video style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-stuff"><source src="$IMS-CC-FILEBASE$/subfolder/with a space/yodawg.mov?canvas_=1&canvas_qs_type=video&canvas_qs_amp=&canvas_qs_embedded=true&media_attachment=true" data-media-id="m-stuff" data-media-type="video"></video>)
|
225
|
+
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-yodawg" src="/media_attachments_iframe/9?type=video"></iframe>)
|
226
226
|
expect(@converter.convert_exported_html(test_string)).to eq([converted_string, nil])
|
227
227
|
|
228
|
-
test_string = %(<audio
|
229
|
-
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="audio" data-media-id="m-
|
228
|
+
test_string = %(<audio style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="audio" data-media-id="m-stuff"><source src="$IMS-CC-FILEBASE$/lolcat.mp3?canvas_=1&canvas_qs_type=audio&canvas_qs_amp=&canvas_qs_embedded=true&media_attachment=true" data-media-id="m-stuff" data-media-type="audio"></video>)
|
229
|
+
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="audio" data-media-id="m-lolcat" src="/media_attachments_iframe/8?type=audio"></iframe>)
|
230
230
|
expect(@converter.convert_exported_html(test_string)).to eq([converted_string, nil])
|
231
231
|
end
|
232
232
|
|
233
|
-
it "converts
|
234
|
-
test_string = %(<video style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-
|
235
|
-
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-
|
233
|
+
it "converts course copy style media attachmet iframe links" do
|
234
|
+
test_string = %(<video style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-yodawg"><source src="$CANVAS_COURSE_REFERENCE$/file_ref/I?media_attachment=true&type=video" data-media-id="m-yodawg" data-media-type="video"></video>)
|
235
|
+
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="video" allowfullscreen="allowfullscreen" allow="fullscreen" data-media-id="m-yodawg" src="/media_attachments_iframe/9?type=video"></iframe>)
|
236
236
|
expect(@converter.convert_exported_html(test_string)).to eq([converted_string, nil])
|
237
237
|
|
238
|
-
test_string = %(<audio
|
239
|
-
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="audio" data-media-id="m-
|
238
|
+
test_string = %(<audio style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="audio" data-media-id="m-lolcat"><source src="$CANVAS_COURSE_REFERENCE$/file_ref/H?media_attachment=true&type=audio" data-media-id="m-lolcat" data-media-type="audio"></audio>)
|
239
|
+
converted_string = %(<iframe style="width: 400px; height: 225px; display: inline-block;" title="this is a media comment" data-media-type="audio" data-media-id="m-lolcat" src="/media_attachments_iframe/8?type=audio"></iframe>)
|
240
240
|
expect(@converter.convert_exported_html(test_string)).to eq([converted_string, nil])
|
241
241
|
end
|
242
242
|
|
@@ -75,7 +75,7 @@ describe CanvasLinkMigrator::LinkResolver do
|
|
75
75
|
expect(link[:new_value]).to eq("/courses/2/modules/36?foo=bar")
|
76
76
|
end
|
77
77
|
|
78
|
-
it "
|
78
|
+
it "converts other links" do
|
79
79
|
link = { link_type: :object, type: "assignments", migration_id: "I", query: "#fie" }
|
80
80
|
resolver.resolve_link!(link)
|
81
81
|
expect(link[:new_value]).to eq("/courses/2/assignments/12#fie")
|
@@ -2,7 +2,9 @@
|
|
2
2
|
"attachment_path_id_lookup": {
|
3
3
|
"subfolder/test.png": "G",
|
4
4
|
"subfolder/with a space/test.png": "F",
|
5
|
+
"subfolder/with a space/yodawg.mov": "I",
|
5
6
|
"subfolder/withCapital/test.png": "migration_id!",
|
7
|
+
"lolcat.mp3": "H",
|
6
8
|
"test.png": "E"
|
7
9
|
},
|
8
10
|
"contains_migration_ids": true,
|
@@ -66,12 +68,30 @@
|
|
66
68
|
},
|
67
69
|
"G": {
|
68
70
|
"destination": {
|
69
|
-
"id": "7"
|
70
|
-
"media_entry_id": "m-stuff"
|
71
|
+
"id": "7"
|
71
72
|
},
|
72
73
|
"source": {
|
73
|
-
"id": "2"
|
74
|
-
|
74
|
+
"id": "2"
|
75
|
+
}
|
76
|
+
},
|
77
|
+
"H": {
|
78
|
+
"destination": {
|
79
|
+
"id": "8",
|
80
|
+
"media_entry_id": "m-lolcat"
|
81
|
+
},
|
82
|
+
"source": {
|
83
|
+
"id": "3",
|
84
|
+
"media_entry_id": "m-lolcat"
|
85
|
+
}
|
86
|
+
},
|
87
|
+
"I": {
|
88
|
+
"destination": {
|
89
|
+
"id": "9",
|
90
|
+
"media_entry_id": "m-yodawg"
|
91
|
+
},
|
92
|
+
"source": {
|
93
|
+
"id": "4",
|
94
|
+
"media_entry_id": "m-yodawg"
|
75
95
|
}
|
76
96
|
}
|
77
97
|
},
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: canvas_link_migrator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mysti Lilla
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2023-
|
13
|
+
date: 2023-11-02 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -54,6 +54,20 @@ dependencies:
|
|
54
54
|
- - ">="
|
55
55
|
- !ruby/object:Gem::Version
|
56
56
|
version: '0'
|
57
|
+
- !ruby/object:Gem::Dependency
|
58
|
+
name: addressable
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
type: :runtime
|
65
|
+
prerelease: false
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
57
71
|
- !ruby/object:Gem::Dependency
|
58
72
|
name: bundler
|
59
73
|
requirement: !ruby/object:Gem::Requirement
|