canvas_link_migrator 0.2.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|