canvas_link_migrator 0.1.2 → 0.2.1

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: 814327ff4502ff2b1187f0b817659cff573bb272ee7e85ae32685297f985ce55
4
- data.tar.gz: e8fa4255d9200988f052ddc9b6a4087b72709ce5443c9bbff4558279be38c4c6
3
+ metadata.gz: 838d1d2500ee03946b3363f19168d62181e4c40f0456cd6b27d2f6ace817c46d
4
+ data.tar.gz: e3686d60c231069856722e4f69e436efedd2531aa5cfc156093b2850918d7384
5
5
  SHA512:
6
- metadata.gz: fc23256c7587decc42dfe9b5677f6299c7ba31cc4aa14e2bda8aca60233ba5ffdc143b205419f4d9fd101b13a52e54a2de896dbd1f038a3d25a44e7d631f54cf
7
- data.tar.gz: fd8ac04adf9829f958297818be79bff39910259cb9e8bb233689b117deb22cbce21df0c875c8d756e9dfa5c4dafb1ab4b5aaba717cfb10aa1a22d8b9574b52a5
6
+ metadata.gz: 45520836a340a6a0f111057360299af93bfc39ac241ba31ab5f6c132dec98f75a32443fd4664e1f879f426d43b43e3ad7ee19a7b8eb89a52d2f595a856172b1e
7
+ data.tar.gz: 5c0fd8cdf1b2ea2c3d8a4e4e7ddf72d6ae8bae51178a9432ffbca3841c4576c18022da5f0802dc9579b37a53a68803e4e08935080dc344950faa56c93baf6f2d
@@ -18,9 +18,14 @@
18
18
  # with this program. If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
20
  require "active_support/core_ext/object"
21
+ require "rack"
21
22
 
22
23
  module CanvasLinkMigrator
23
24
  class LinkResolver
25
+ attr_accessor :migration_id_converter
26
+
27
+ delegate :context_path, :attachment_path_id_lookup, to: :migration_id_converter
28
+
24
29
  def initialize(migration_id_converter)
25
30
  @migration_id_converter = migration_id_converter
26
31
  end
@@ -35,8 +40,8 @@ module CanvasLinkMigrator
35
40
  end
36
41
  end
37
42
 
38
- def context_path
39
- @migration_id_converter.context_path
43
+ def attachment_path_id_lookup_lower
44
+ @attachment_path_id_lookup_lower ||= attachment_path_id_lookup&.transform_keys(&:downcase)
40
45
  end
41
46
 
42
47
  # finds the :new_value to use to replace the placeholder
@@ -63,7 +68,8 @@ module CanvasLinkMigrator
63
68
  type = "pages" if type == "wiki"
64
69
  if type == "pages"
65
70
  query = resolve_module_item_query(nil, link[:query])
66
- 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}"
67
73
  elsif type == "attachments"
68
74
  att_id = @migration_id_converter.convert_attachment_migration_id(migration_id)
69
75
  if att_id
@@ -150,13 +156,13 @@ module CanvasLinkMigrator
150
156
  # This is for backward-compatibility: canvas attachment filenames are escaped
151
157
  # with '+' for spaces and older exports have files with that instead of %20
152
158
  alt_rel_path = rel_path.tr("+", " ")
153
- if @migration_id_converter.attachment_path_id_lookup
154
- mig_id ||= @migration_id_converter.attachment_path_id_lookup[rel_path]
155
- mig_id ||= @migration_id_converter.attachment_path_id_lookup[alt_rel_path]
159
+ if attachment_path_id_lookup
160
+ mig_id ||= attachment_path_id_lookup[rel_path]
161
+ mig_id ||= attachment_path_id_lookup[alt_rel_path]
156
162
  end
157
- if !mig_id && @migration_id_converter.attachment_path_id_lookup_lower
158
- mig_id ||= @migration_id_converter.attachment_path_id_lookup_lower[rel_path.downcase]
159
- mig_id ||= @migration_id_converter.attachment_path_id_lookup_lower[alt_rel_path.downcase]
163
+ if !mig_id && attachment_path_id_lookup_lower
164
+ mig_id ||= attachment_path_id_lookup_lower[rel_path.downcase]
165
+ mig_id ||= attachment_path_id_lookup_lower[alt_rel_path.downcase]
160
166
  end
161
167
 
162
168
  # This md5 comparison is here to handle faulty cartridges with the migration_id equivalent of an empty string
@@ -182,7 +188,7 @@ module CanvasLinkMigrator
182
188
  while new_url.nil? && !rel_path_parts.empty?
183
189
  sub_path = File.join(rel_path_parts)
184
190
  if (file = find_file_in_context(sub_path))
185
- new_url = "#{context_path}/files/#{file.id}"
191
+ new_url = "#{context_path}/files/#{file["id"]}"
186
192
  # support other params in the query string, that were exported from the
187
193
  # original path components and query string. see
188
194
  # CCHelper::file_query_string
@@ -219,13 +225,13 @@ module CanvasLinkMigrator
219
225
 
220
226
  def resolve_media_comment_data(node, rel_path)
221
227
  if (file = find_file_in_context(rel_path[/^[^?]+/])) # strip query string for this search
222
- media_id = (file.media_object&.media_id || file.media_entry_id)
228
+ media_id = file.try(:media_object)&.media_id || file["media_entry_id"]
223
229
  if media_id && media_id != "maybe"
224
230
  if ["iframe", "source"].include?(node.name)
225
231
  node["data-media-id"] = media_id
226
232
  if node["data-is-media-attachment"]
227
233
  node.delete("data-is-media-attachment")
228
- return media_attachment_iframe_url(file.id, node["data-media-type"])
234
+ return media_attachment_iframe_url(file["id"], node["data-media-type"])
229
235
  else
230
236
  return media_iframe_url(media_id, node["data-media-type"])
231
237
  end
@@ -52,9 +52,9 @@ module CanvasLinkMigrator
52
52
  migration_data["destination_hosts"]
53
53
  end
54
54
 
55
- def attachment_path_id_lookup; end
56
-
57
- def attachment_path_id_lookup_lower; end
55
+ def attachment_path_id_lookup
56
+ migration_data["attachment_path_id_lookup"]
57
+ end
58
58
 
59
59
  def root_folder_name
60
60
  migration_data["destination_root_folder"]
@@ -102,5 +102,9 @@ module CanvasLinkMigrator
102
102
  # we'll check both here
103
103
  convert_announcement_migration_id(migration_id) if type == "discussion_topics"
104
104
  end
105
+
106
+ def lookup_attachment_by_migration_id(migration_id)
107
+ resources.dig("files", migration_id, "destination")
108
+ end
105
109
  end
106
110
  end
@@ -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
 
@@ -56,62 +63,55 @@ describe CanvasLinkMigrator::ImportedHtmlConverter do
56
63
  end
57
64
  end
58
65
 
59
- # it "finds an attachment by migration id" do
60
- # test_string = %{<p>This is an image: <br /><img src="%24CANVAS_OBJECT_REFERENCE%24/attachments/F" alt=":(" /></p>}
61
- # expect(@converter.convert_exported_html(test_string)).to eq([%{<p>This is an image: <br><img src="#{@path}files/6/preview" alt=":("></p>}, nil])
62
- # end
63
-
64
- # it "finds an attachment by path" do
65
- # test_string = %{<p>This is an image: <br /><img src="%24IMS_CC_FILEBASE%24/test.png" alt=":(" /></p>}
66
-
67
- # # if there isn't a path->migration id map it'll be a relative course file path
68
- # expect(@converter.convert_exported_html(test_string)).to eq %{<p>This is an image: <br><img src="#{@path}file_contents/course%20files/test.png" alt=":("></p>}
69
-
70
- # @migration.attachment_path_id_lookup = { "test.png" => att.migration_id }
71
- # expect(@converter.convert_exported_html(test_string)).to eq %{<p>This is an image: <br><img src="#{@path}files/#{att.id}/preview" alt=":("></p>}
72
- # end
66
+ it "finds an attachment by migration id" do
67
+ test_string = %{<p>This is an image: <br /><img src="%24CANVAS_OBJECT_REFERENCE%24/attachments/F" alt=":(" /></p>}
68
+ expect(@converter.convert_exported_html(test_string)).to eq([%{<p>This is an image: <br><img src="#{@path}files/6/preview" alt=":("></p>}, nil])
69
+ end
73
70
 
74
- # it "finds an attachment by a path with a space" do
75
- # att = make_test_att
76
- # @migration.attachment_path_id_lookup = { "subfolder/with a space/test.png" => att.migration_id }
71
+ it "finds an attachment by path" do
72
+ test_string = %{<p>This is an image: <br /><img src="%24IMS_CC_FILEBASE%24/test.png" alt=":(" /></p>}
77
73
 
78
- # test_string = %(<img src="subfolder/with%20a%20space/test.png" alt="nope" />)
79
- # expect(@converter.convert_exported_html(test_string)).to eq %(<img src="#{@path}files/#{att.id}/preview" alt="nope">)
74
+ # if there isn't a path->migration id map it'll be a relative course file path
75
+ expect(@converter.link_resolver).to receive(:attachment_path_id_lookup).exactly(4).times.and_return({})
76
+ html, bad_links = @converter.convert_exported_html(test_string)
77
+ expect(html).to eq %{<p>This is an image: <br><img src="#{@path}file_contents/course%20files/test.png" alt=":("></p>}
78
+ expect(bad_links[0]).to include({ link_type: :file, missing_url: "/courses/2/file_contents/course%20files/test.png" })
80
79
 
81
- # test_string = %(<img src="subfolder/with+a+space/test.png" alt="nope" />)
82
- # expect(@converter.convert_exported_html(test_string)).to eq %(<img src="#{@path}files/#{att.id}/preview" alt="nope">)
83
- # end
80
+ expect(@converter.link_resolver).to receive(:attachment_path_id_lookup).twice.and_call_original
81
+ expect(@converter.convert_exported_html(test_string)).to eq([%{<p>This is an image: <br><img src="#{@path}files/5/preview" alt=":("></p>}, nil])
82
+ end
84
83
 
85
- # it "finds an attachment even if the link has an extraneous folder" do
86
- # att = make_test_att
87
- # @migration.attachment_path_id_lookup = { "subfolder/test.png" => att.migration_id }
84
+ it "finds an attachment by a path with a space" do
85
+ test_string = %(<img src="subfolder/with%20a%20space/test.png" alt="nope" />)
86
+ expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/6/preview" alt="nope">), nil])
88
87
 
89
- # test_string = %(<img src="anotherfolder/subfolder/test.png" alt="nope" />)
90
- # expect(@converter.convert_exported_html(test_string)).to eq %(<img src="#{@path}files/#{att.id}/preview" alt="nope">)
91
- # end
88
+ test_string = %(<img src="subfolder/with+a+space/test.png" alt="nope" />)
89
+ expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/6/preview" alt="nope">), nil])
90
+ end
92
91
 
93
- # it "finds an attachment by path if capitalization is different" do
94
- # att = make_test_att
95
- # @migration.attachment_path_id_lookup = { "subfolder/withCapital/test.png" => "wrong!" }
96
- # @migration.attachment_path_id_lookup_lower = { "subfolder/withcapital/test.png" => att.migration_id }
92
+ it "finds an attachment even if the link has an extraneous folder" do
93
+ test_string = %(<img src="anotherfolder/subfolder/test.png" alt="nope" />)
94
+ expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/7/preview" alt="nope">), nil])
95
+ end
97
96
 
98
- # test_string = %(<img src="subfolder/WithCapital/TEST.png" alt="nope" />)
99
- # expect(@converter.convert_exported_html(test_string)).to eq %(<img src="#{@path}files/#{att.id}/preview" alt="nope">)
100
- # end
97
+ it "finds an attachment by path if capitalization is different" do
98
+ expect(@converter.link_resolver).to receive(:attachment_path_id_lookup).twice.and_return({ "subfolder/withCapital/test.png" => "wrong!" })
99
+ expect(@converter.link_resolver).to receive(:attachment_path_id_lookup).twice.and_return({ "subfolder/withcapital/test.png" => "F" })
101
100
 
102
- # it "finds an attachment with query params" do
103
- # att = make_test_att
104
- # @migration.attachment_path_id_lookup = { "test.png" => att.migration_id }
101
+ test_string = %(<img src="subfolder/WithCapital/TEST.png" alt="nope" />)
102
+ expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/6/preview" alt="nope">), nil])
103
+ end
105
104
 
106
- # test_string = %(<img src="%24IMS_CC_FILEBASE%24/test.png?canvas_customaction=1&canvas_qs_customparam=1" alt="nope" />)
107
- # expect(@converter.convert_exported_html(test_string)).to eq %(<img src="#{@path}files/#{att.id}/customaction?customparam=1" alt="nope">)
105
+ it "finds an attachment with query params" do
106
+ test_string = %(<img src="%24IMS_CC_FILEBASE%24/test.png?canvas_customaction=1&canvas_qs_customparam=1" alt="nope" />)
107
+ expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/5/customaction?customparam=1" alt="nope">), nil])
108
108
 
109
- # test_string = %(<img src="%24IMS_CC_FILEBASE%24/test.png?canvas_qs_customparam2=3" alt="nope" />)
110
- # expect(@converter.convert_exported_html(test_string)).to eq %(<img src="#{@path}files/#{att.id}/preview?customparam2=3" alt="nope">)
109
+ test_string = %(<img src="%24IMS_CC_FILEBASE%24/test.png?canvas_qs_customparam2=3" alt="nope" />)
110
+ expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/5/preview?customparam2=3" alt="nope">), nil])
111
111
 
112
- # test_string = %(<img src="%24IMS_CC_FILEBASE%24/test.png?notarelevantparam" alt="nope" />)
113
- # expect(@converter.convert_exported_html(test_string)).to eq %(<img src="#{@path}files/#{att.id}/preview" alt="nope">)
114
- # end
112
+ test_string = %(<img src="%24IMS_CC_FILEBASE%24/test.png?notarelevantparam" alt="nope" />)
113
+ expect(@converter.convert_exported_html(test_string)).to eq([%(<img src="#{@path}files/5/preview" alt="nope">), nil])
114
+ end
115
115
  end
116
116
 
117
117
  it "converts picture source srcsets" do
@@ -81,4 +81,10 @@ describe CanvasLinkMigrator::LinkResolver do
81
81
  expect(link[:new_value]).to eq("/courses/2/assignments/12#fie")
82
82
  end
83
83
  end
84
+
85
+ describe "attachment_path_id_lookup_lower" do
86
+ it "shows correct lowercase paths" do
87
+ expect(resolver.attachment_path_id_lookup_lower).to include({ "subfolder/withcapital/test.png" => "migration_id!" })
88
+ end
89
+ end
84
90
  end
@@ -1,4 +1,10 @@
1
1
  {
2
+ "attachment_path_id_lookup": {
3
+ "subfolder/test.png": "G",
4
+ "subfolder/with a space/test.png": "F",
5
+ "subfolder/withCapital/test.png": "migration_id!",
6
+ "test.png": "E"
7
+ },
2
8
  "contains_migration_ids": true,
3
9
  "destination_course": "2",
4
10
  "destination_hosts": [
@@ -57,6 +63,16 @@
57
63
  "id": "4",
58
64
  "media_entry_id": "m-stuff"
59
65
  }
66
+ },
67
+ "G": {
68
+ "destination": {
69
+ "id": "7",
70
+ "media_entry_id": "m-stuff"
71
+ },
72
+ "source": {
73
+ "id": "2",
74
+ "media_entry_id": "m-stuff"
75
+ }
60
76
  }
61
77
  },
62
78
  "module_items": {
@@ -92,12 +108,6 @@
92
108
  }
93
109
  }
94
110
  },
95
- "file_tree": {
96
- "folder 1": {
97
- "id": "1",
98
- "sub_folders": {}
99
- }
100
- },
101
111
  "source_course": "1",
102
112
  "source_host": "pineapple.edu"
103
- }
113
+ }
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.1.2
4
+ version: 0.2.1
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-07-31 00:00:00.000000000 Z
13
+ date: 2023-08-22 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: activesupport
@@ -39,6 +40,20 @@ dependencies:
39
40
  - - ">="
40
41
  - !ruby/object:Gem::Version
41
42
  version: '0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: rack
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
42
57
  - !ruby/object:Gem::Dependency
43
58
  name: bundler
44
59
  requirement: !ruby/object:Gem::Requirement
@@ -99,6 +114,7 @@ description:
99
114
  email:
100
115
  - mysti@instructure.com
101
116
  - james.logan@instructure.com
117
+ - sarah.gerard@instructure.com
102
118
  executables: []
103
119
  extensions: []
104
120
  extra_rdoc_files: []