diff --git a/common_cartridge.gemspec b/common_cartridge.gemspec index 918dc20..a1505ae 100644 --- a/common_cartridge.gemspec +++ b/common_cartridge.gemspec @@ -2,26 +2,28 @@ lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'common_cartridge/version' + Gem::Specification.new do |spec| - spec.name = "common_cartridge" - spec.version = "1.0.1" - spec.authors = ["Josh Simpson"] - spec.email = ["jsimpson@instructure.com"] + spec.name = 'common_cartridge' + spec.version = CommonCartridge::VERSION + spec.authors = ['Josh Simpson', 'Remy Obein'] + spec.email = ['jsimpson@instructure.com', 'remy@cassia.tech'] spec.summary = %q{CommonCartridge} - spec.description = "Parse IMS Common Cartridge packages" - spec.homepage = "http://www.instructure.com/" - spec.license = "MIT" + spec.description = 'Parse IMS Common Cartridge packages' + spec.homepage = 'http://www.instructure.com/' + spec.license = 'MIT' spec.files = Dir.glob("{lib,spec}/**/*") spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) - spec.require_paths = ["lib"] + spec.require_paths = ['lib'] - spec.add_dependency "sax-machine", "~> 1.3.2" - spec.add_dependency "nokogiri", "~> 1.8.1" - spec.add_dependency "rubyzip", "~> 1.2.1" + spec.add_dependency 'sax-machine', '~> 1.3.2' + spec.add_dependency 'nokogiri', '~> 1.8.1' + spec.add_dependency 'rubyzip', '~> 1.2.1' - spec.add_development_dependency "bundler" - spec.add_development_dependency "rake" - spec.add_development_dependency "rspec", "~> 3.0" + spec.add_development_dependency 'bundler' + spec.add_development_dependency 'rake' + spec.add_development_dependency 'rspec', '~> 3.0' end diff --git a/lib/common_cartridge.rb b/lib/common_cartridge.rb index b359b2e..781a557 100644 --- a/lib/common_cartridge.rb +++ b/lib/common_cartridge.rb @@ -1,5 +1,4 @@ require 'sax-machine' -require 'sax_machine/sax_handler' module CommonCartridge def self.parse_from_zip(zipfile) @@ -38,3 +37,4 @@ def initialize require 'common_cartridge/elements/manifest' require 'common_cartridge/package' require 'common_cartridge/parsers/parser' +require 'common_cartridge/version' diff --git a/lib/common_cartridge/elements/lom.rb b/lib/common_cartridge/elements/lom.rb index 33943c0..b22c3c6 100644 --- a/lib/common_cartridge/elements/lom.rb +++ b/lib/common_cartridge/elements/lom.rb @@ -1,11 +1,28 @@ module CommonCartridge module Elements module Lom + class LanguageString + include SAXMachine + + attribute :language + value :value + end + class Title include SAXMachine - element :string, as: :value - element :string, value: :language, as: :language + # http://www.imsglobal.org/profile/cc/ccv1p3/LOM/ccv1p3_lommanifest_v1p0.xsd + elements 'lomimscc:string', as: :strings, class: CommonCartridge::Elements::Lom::LanguageString + + # backward compatibility + def value; strings.first.value; end + def language; strings.first.language; end + + def values + strings.map do |str| + [str.language, str.value] + end.to_h + end def to_s; string; end end @@ -13,8 +30,8 @@ def to_s; string; end class Description include SAXMachine - element :string, as: :value - element :string, value: :language, as: :language + element 'lomimscc:string', as: :value + element 'lomimscc:string', value: :language, as: :language def to_s; string; end end @@ -22,8 +39,8 @@ def to_s; string; end class Keyword include SAXMachine - element :string, as: :value - element :string, value: :language, as: :language + element 'lomimscc:string', as: :value + element 'lomimscc:string', value: :language, as: :language def to_s; string; end end @@ -37,22 +54,22 @@ class CopyrightAndOtherRestrictions class Rights include SAXMachine - element :description, class: CommonCartridge::Elements::Lom::Description + element 'lomimscc:description', as: :description, class: CommonCartridge::Elements::Lom::Description element :copyrightAndOtherRestrictions, class: CommonCartridge::Elements::Lom::CopyrightAndOtherRestrictions end class General include SAXMachine - element :title, class: CommonCartridge::Elements::Lom::Title - element :description, class: CommonCartridge::Elements::Lom::Description - elements :keyword, as: :keywords, class: CommonCartridge::Elements::Lom::Keyword + element 'lomimscc:title', as: :title, class: CommonCartridge::Elements::Lom::Title + element 'lomimscc:description', as: :description, class: CommonCartridge::Elements::Lom::Description + elements 'lomimscc:keyword', as: :keywords, class: CommonCartridge::Elements::Lom::Keyword end class Lom include SAXMachine - element :general, class: CommonCartridge::Elements::Lom::General + element 'lomimscc:general', as: :general, class: CommonCartridge::Elements::Lom::General element :rights, class: CommonCartridge::Elements::Lom::Rights end end diff --git a/lib/common_cartridge/elements/manifest.rb b/lib/common_cartridge/elements/manifest.rb index 178c4ac..b80e1f4 100644 --- a/lib/common_cartridge/elements/manifest.rb +++ b/lib/common_cartridge/elements/manifest.rb @@ -6,6 +6,12 @@ class Manifest element :metadata, class: CommonCartridge::Elements::Metadata element :organizations, class: CommonCartridge::Elements::Organizations::RootOrganization, as: :root_organization element :resources, class: CommonCartridge::Elements::Resources::RootResource, as: :root_resource + attribute :identifier, required: true + attribute :xmlns + attribute 'xmlns:lomimscc', as: :xmlns_lomimscc + attribute 'xmlns:lom', as: :xmlns_lom + attribute 'xmlns:xsi', as: :xmlns_xsi + attribute 'xsi:schemaLocation', as: :xsi_schema_location def organizations root_organization.organizations diff --git a/lib/common_cartridge/elements/metadata.rb b/lib/common_cartridge/elements/metadata.rb index 073c5ee..22fa461 100644 --- a/lib/common_cartridge/elements/metadata.rb +++ b/lib/common_cartridge/elements/metadata.rb @@ -6,7 +6,7 @@ class Metadata element :schema element :schemaversion - element :lom, class: CommonCartridge::Elements::Lom::Lom + element 'lomimscc:lom', as: :lom, class: CommonCartridge::Elements::Lom::Lom end end end diff --git a/lib/common_cartridge/elements/organizations.rb b/lib/common_cartridge/elements/organizations.rb index 45c81e4..7fd7cbf 100644 --- a/lib/common_cartridge/elements/organizations.rb +++ b/lib/common_cartridge/elements/organizations.rb @@ -17,8 +17,6 @@ class RootItem include SAXMachine attribute :identifier - attribute :identifierref - elements :item, class: Item, as: :items # todo: implement 'find_by' method here to quickly scan for particular items diff --git a/lib/common_cartridge/elements/resources.rb b/lib/common_cartridge/elements/resources.rb index 43e19a3..f6a0897 100644 --- a/lib/common_cartridge/elements/resources.rb +++ b/lib/common_cartridge/elements/resources.rb @@ -4,6 +4,7 @@ require 'common_cartridge/elements/resources/assignment' require 'common_cartridge/elements/resources/assessment' require 'common_cartridge/elements/resources/page' +require 'common_cartridge/elements/resources/basic_lti_link' module CommonCartridge module Elements @@ -15,7 +16,8 @@ def self.type_mappings WebLink.pattern => WebLink, Assignment.pattern => Assignment, Assessment.pattern => Assessment, - Page.pattern => Page + Page.pattern => Page, + BasicLtiLink::BasicLtiLink.pattern => BasicLtiLink::BasicLtiLink } end diff --git a/lib/common_cartridge/elements/resources/attachments.rb b/lib/common_cartridge/elements/resources/attachments.rb index a48eb73..a1fcabd 100644 --- a/lib/common_cartridge/elements/resources/attachments.rb +++ b/lib/common_cartridge/elements/resources/attachments.rb @@ -12,7 +12,7 @@ class Attachment class RootAttachment include SAXMachine - elements :attachment, class: Attachment, as: :attachments + elements :'dt:attachment', class: Attachment, as: :attachments end end end diff --git a/lib/common_cartridge/elements/resources/basic_lti_link.rb b/lib/common_cartridge/elements/resources/basic_lti_link.rb new file mode 100644 index 0000000..7e81d24 --- /dev/null +++ b/lib/common_cartridge/elements/resources/basic_lti_link.rb @@ -0,0 +1,66 @@ +module CommonCartridge + module Elements + module Resources + module BasicLtiLink + class VendorContact + include SAXMachine + + element 'lticp:email', as: :email + end + + class Vendor + include SAXMachine + + element 'lticp:code', as: :code + element 'lticp:name', as: :name + element 'lticp:description', as: :description + element 'lticp:url', as: :url + element 'lticp:contact', class: VendorContact, as: :contact + end + + class ExtensionProperty + include SAXMachine + + attribute :name + value :value + end + + class Extension + include SAXMachine + + attribute :platform + elements 'lticm:property', class: ExtensionProperty, as: :properties + end + + class BasicLtiLink + attr_accessor :identifier + + include SAXMachine + + attribute :xmlns + attribute 'xmlns:blti', as: :xmlns_blti + attribute 'xmlns:lticm', as: :xmlns_lticm + attribute 'xmlns:lticp', as: :xmlns_lticp + attribute 'xmlns:xsi', as: :xmlns_xsi + attribute 'xsi:schemaLocation', as: :xsi_schema_location + + element 'blti:title', as: :title + element 'blti:description', as: :description + element 'blti:secure_launch_url', as: :secure_launch_url + element 'blti:launch_url', as: :launch_url + element 'blti:vendor', class: Vendor, as: :vendor + + elements 'blti:extensions', class: Extension, as: :extensions + + def self.type + :basic_lti_link + end + + def self.pattern + /imsbasiclti_xmlv1p/ + end + end + end + end + end +end diff --git a/lib/common_cartridge/elements/resources/topic.rb b/lib/common_cartridge/elements/resources/topic.rb index faffa35..de6e770 100644 --- a/lib/common_cartridge/elements/resources/topic.rb +++ b/lib/common_cartridge/elements/resources/topic.rb @@ -6,10 +6,10 @@ class Topic include SAXMachine - element :title - element :text - element :text, value: :texttype, as: :text_type - element :attachments, class: Attachments::RootAttachment, as: :attachment_root + element 'dt:title', as: :title + element 'dt:text', as: :text + element 'dt:text', value: :texttype, as: :text_type + element 'dt:attachments', class: Attachments::RootAttachment, as: :attachment_root def attachments attachment_root.attachments diff --git a/lib/common_cartridge/parsers/parser.rb b/lib/common_cartridge/parsers/parser.rb index 1d5b27b..043dd82 100644 --- a/lib/common_cartridge/parsers/parser.rb +++ b/lib/common_cartridge/parsers/parser.rb @@ -9,6 +9,12 @@ module CommonCartridge module Parsers class Parser + class ManifestDocument + include SAXMachine + + element :manifest, class: CommonCartridge::Elements::Manifest, required: true + end + def self.use_file(zipfile, path) Zip::File.open(File.join(CommonCartridge.config.import_directory, zipfile)) do |file| f = file.glob(path).first @@ -25,7 +31,7 @@ def initialize(zipfile) def parse Parser.use_file(@zipfile, 'imsmanifest.xml') do |xml| - @package.manifest = CommonCartridge::Elements::Manifest.parse(xml) + @package.manifest = ManifestDocument.parse(xml).manifest end parse_content! diff --git a/lib/common_cartridge/version.rb b/lib/common_cartridge/version.rb new file mode 100644 index 0000000..c51aa99 --- /dev/null +++ b/lib/common_cartridge/version.rb @@ -0,0 +1,3 @@ +module CommonCartridge + VERSION = '2.0.0'.freeze +end diff --git a/lib/sax_machine/sax_handler.rb b/lib/sax_machine/sax_handler.rb deleted file mode 100644 index 7db3cc7..0000000 --- a/lib/sax_machine/sax_handler.rb +++ /dev/null @@ -1,11 +0,0 @@ -module SAXMachine - module SAXAbstractHandler - # Not a great solution; will be solved gracefully with CNVS-13964 - remove_method :normalize_name - def normalize_name(name) - # strip namespaces - name = name.split(":").last - name.gsub(/\-/, '_') - end - end -end diff --git a/spec/elements/manifest_spec.rb b/spec/elements/manifest_spec.rb index 13333c8..5346578 100644 --- a/spec/elements/manifest_spec.rb +++ b/spec/elements/manifest_spec.rb @@ -22,6 +22,10 @@ module Elements it "has resources" do expect(@manifest.root_resource).to be_kind_of(CommonCartridge::Elements::Resources::RootResource) end + + it "has identifier" do + expect(@manifest.identifier).to eq('if33b9cbc13c56657b05bec722d30b84f') + end end end end diff --git a/spec/elements/resources/basic_lti_link_spec.rb b/spec/elements/resources/basic_lti_link_spec.rb new file mode 100644 index 0000000..565e105 --- /dev/null +++ b/spec/elements/resources/basic_lti_link_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' + +module CommonCartridge + module Elements + module Resources + describe BasicLtiLink do + before(:all) do + manifest = CommonCartridge.parse_from_zip('canvas_small_1.1.imscc').manifest + @resource = manifest.resources.detect { |r| r.identifier =~ /I_00015_R/ } + end + + it 'is parsed correctly' do + expect(@resource.files.first.content).to be_kind_of( + CommonCartridge::Elements::Resources::BasicLtiLink::BasicLtiLink + ) + end + + it 'has a title' do + expect(@resource.files.first.content.title).to eq('Semester 1 Overview') + end + + it 'has a secure_launch_url' do + expect(@resource.files.first.content.secure_launch_url).to eq('https://fakecollege.com/activity_lists/student-resources--122/activities/semester-1-overview--17?custom_course_id=275') + end + end + end + end +end + diff --git a/spec/files/canvas_small_1.1.imscc b/spec/files/canvas_small_1.1.imscc index 8083764..45bc90a 100644 Binary files a/spec/files/canvas_small_1.1.imscc and b/spec/files/canvas_small_1.1.imscc differ