canvas_link_migrator 0.2.0 → 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: 989d0e7044ece5d052b909fa121de7f205906c733908a8dcf4a26d619cf67caf
4
- data.tar.gz: a065d7f5ad6ad400cbd7cf448f5d42c5b69d400d9123837d2517950059d4a70e
3
+ metadata.gz: b03a701351cd4f8484cd257bdbbb3e4437ada4d39988d97230e48093e6a8c2a9
4
+ data.tar.gz: 2fadff9dc0f3a7c0d07ef2d7e79bd20f2e8c9ee14ccf71e4951c89417aa35659
5
5
  SHA512:
6
- metadata.gz: 50b673e7a91c0f345455c0ef0027b9e05a84c973f35d75f5659d336dfb70a3385d04d3360bead41b16a5101e3f8ee5e054f881cab88ac3f7c3ec0d5387cb7c6c
7
- data.tar.gz: 8519365222facd8c05af020e7c6734db5c61e386cfd1fd0097f1a0815924c2c622929c217bfa4772d37fcd3acadd118019672cd9958ad76951512acd4bd8c4ba
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
@@ -68,7 +68,8 @@ module CanvasLinkMigrator
68
68
  type = "pages" if type == "wiki"
69
69
  if type == "pages"
70
70
  query = resolve_module_item_query(nil, link[:query])
71
- link[:new_value] = "#{context_path}/pages/#{migration_id}#{query}"
71
+ linked_wiki_url = @migration_id_converter.convert_wiki_page_migration_id_to_slug(migration_id) || migration_id
72
+ link[:new_value] = "#{context_path}/pages/#{linked_wiki_url}#{query}"
72
73
  elsif type == "attachments"
73
74
  att_id = @migration_id_converter.convert_attachment_migration_id(migration_id)
74
75
  if att_id
@@ -91,7 +92,7 @@ module CanvasLinkMigrator
91
92
  # see LinkParser for details
92
93
  rel_path = link[:rel_path]
93
94
  node = Nokogiri::HTML5.fragment(link[:old_value]).children.first
94
- new_url = resolve_media_comment_data(node, rel_path)
95
+ new_url = resolve_media_comment_data(node, rel_path, link[:media_attachment])
95
96
  new_url ||= resolve_relative_file_url(rel_path)
96
97
 
97
98
  unless new_url
@@ -121,12 +122,15 @@ module CanvasLinkMigrator
121
122
  # context prepended to the URL. This prevents
122
123
  # redirects to non cross-origin friendly urls
123
124
  # during a file fetch
124
- if rest.include?("icon_maker_icon=1")
125
- link[:new_value] = "/files/#{file_id}#{rest}"
126
- else
127
- link[:new_value] = "#{context_path}/files/#{file_id}#{rest}"
128
- link[:new_value] = "/media_objects_iframe?mediahref=#{link[:new_value]}" if link[:in_media_iframe]
129
- 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
130
134
  end
131
135
  else
132
136
  raise "unrecognized link_type (#{link[:link_type]}) in unresolved link"
@@ -222,14 +226,13 @@ module CanvasLinkMigrator
222
226
  url
223
227
  end
224
228
 
225
- def resolve_media_comment_data(node, rel_path)
229
+ def resolve_media_comment_data(node, rel_path, media_attachment)
226
230
  if (file = find_file_in_context(rel_path[/^[^?]+/])) # strip query string for this search
227
231
  media_id = file.try(:media_object)&.media_id || file["media_entry_id"]
228
232
  if media_id && media_id != "maybe"
229
233
  if ["iframe", "source"].include?(node.name)
230
234
  node["data-media-id"] = media_id
231
- if node["data-is-media-attachment"]
232
- node.delete("data-is-media-attachment")
235
+ if media_attachment
233
236
  return media_attachment_iframe_url(file["id"], node["data-media-type"])
234
237
  else
235
238
  return media_iframe_url(media_id, node["data-media-type"])
@@ -37,6 +37,13 @@ describe CanvasLinkMigrator::ImportedHtmlConverter do
37
37
  expect(bad_links).to be_nil
38
38
  end
39
39
 
40
+ it "converts a wiki reference with migration id" do
41
+ test_string = %(<a href="%24WIKI_REFERENCE%24/pages/A?query=blah">Test Wiki Page</a>)
42
+ html, bad_links = @converter.convert_exported_html(test_string)
43
+ expect(html).to eq %(<a href="#{@path}pages/slug-a?query=blah">Test Wiki Page</a>)
44
+ expect(bad_links).to be_nil
45
+ end
46
+
40
47
  context "when course attachments exist" do
41
48
  subject { @converter.convert_exported_html(test_string) }
42
49
 
@@ -214,22 +221,22 @@ describe CanvasLinkMigrator::ImportedHtmlConverter do
214
221
  end
215
222
 
216
223
  it "converts source tags to RCE media attachment iframes" do
217
- 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>)
218
- 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>)
219
226
  expect(@converter.convert_exported_html(test_string)).to eq([converted_string, nil])
220
227
 
221
- 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>)
222
- 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>)
223
230
  expect(@converter.convert_exported_html(test_string)).to eq([converted_string, nil])
224
231
  end
225
232
 
226
- it "converts source tags to RCE media attachment iframes when link is untranslated" do
227
- 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>)
228
- 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>)
229
236
  expect(@converter.convert_exported_html(test_string)).to eq([converted_string, nil])
230
237
 
231
- 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>)
232
- 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>)
233
240
  expect(@converter.convert_exported_html(test_string)).to eq([converted_string, nil])
234
241
  end
235
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,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canvas_link_migrator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mysti Lilla
8
8
  - James Logan
9
+ - Sarah Gerard
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2023-08-01 00:00:00.000000000 Z
13
+ date: 2023-11-02 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: activesupport
@@ -53,6 +54,20 @@ dependencies:
53
54
  - - ">="
54
55
  - !ruby/object:Gem::Version
55
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'
56
71
  - !ruby/object:Gem::Dependency
57
72
  name: bundler
58
73
  requirement: !ruby/object:Gem::Requirement
@@ -113,6 +128,7 @@ description:
113
128
  email:
114
129
  - mysti@instructure.com
115
130
  - james.logan@instructure.com
131
+ - sarah.gerard@instructure.com
116
132
  executables: []
117
133
  extensions: []
118
134
  extra_rdoc_files: []