canvas_link_migrator 0.1.2 → 0.2.1

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 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: []