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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 838d1d2500ee03946b3363f19168d62181e4c40f0456cd6b27d2f6ace817c46d
4
- data.tar.gz: e3686d60c231069856722e4f69e436efedd2531aa5cfc156093b2850918d7384
3
+ metadata.gz: b03a701351cd4f8484cd257bdbbb3e4437ada4d39988d97230e48093e6a8c2a9
4
+ data.tar.gz: 2fadff9dc0f3a7c0d07ef2d7e79bd20f2e8c9ee14ccf71e4951c89417aa35659
5
5
  SHA512:
6
- metadata.gz: 45520836a340a6a0f111057360299af93bfc39ac241ba31ab5f6c132dec98f75a32443fd4664e1f879f426d43b43e3ad7ee19a7b8eb89a52d2f595a856172b1e
7
- data.tar.gz: 5c0fd8cdf1b2ea2c3d8a4e4e7ddf72d6ae8bae51178a9432ffbca3841c4576c18022da5f0802dc9579b37a53a68803e4e08935080dc344950faa56c93baf6f2d
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
- link[:new_value] = "/files/#{file_id}#{rest}"
127
- else
128
- link[:new_value] = "#{context_path}/files/#{file_id}#{rest}"
129
- link[:new_value] = "/media_objects_iframe?mediahref=#{link[:new_value]}" if link[:in_media_iframe]
130
- end
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 node["data-is-media-attachment"]
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="$CANVAS_OBJECT_REFERENCE$/media_attachments_iframe/E?type=video" 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-stuff" src="/media_attachments_iframe/5?type=video"></iframe>)
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 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="$CANVAS_OBJECT_REFERENCE$/media_attachments_iframe/E?type=audio" 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-stuff" src="/media_attachments_iframe/5?type=audio"></iframe>)
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 source tags to RCE media attachment iframes when link is untranslated" 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-stuff"><source src="/media_attachments_iframe/5?type=video" data-media-id="m-stuff" 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-stuff" src="/media_attachments_iframe/5?type=video"></iframe>)
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 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="/media_attachments_iframe/5?type=audio" data-media-id="m-stuff" data-media-type="audio"></video>)
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-stuff" src="/media_attachments_iframe/5?type=audio"></iframe>)
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 "converters other links" do
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
- "media_entry_id": "m-stuff"
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.2.1
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-08-22 00:00:00.000000000 Z
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