diff --git a/app/assets/javascripts/learning_object/chunks.coffee b/app/assets/javascripts/learning_object/chunks.coffee new file mode 100644 index 0000000000000000000000000000000000000000..24f83d18bbd38c24c4f7c3c2fc360cd68e857a2a --- /dev/null +++ b/app/assets/javascripts/learning_object/chunks.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/builders/learning_object/attachment_builder.rb b/app/builders/learning_object/attachment_builder.rb new file mode 100644 index 0000000000000000000000000000000000000000..4e2b3d175153802f5cdf8e2ac7947ccbf136d5c5 --- /dev/null +++ b/app/builders/learning_object/attachment_builder.rb @@ -0,0 +1,39 @@ +module LearningObject + class AttachmentBuilder < ::Builder + + ##disable method + # build attachments with id's is out of scope. + def self.build(objects = []) + raise NotImplementedError, 'LearningObject::AttachmentBuilder#build is out of scope.' + end + + def self.build_from_orientdb(args = {}) + args['retrieve_link'] = args.delete('retrieveLink') + args['mime_type'] = args.delete('mimeType') + build_from_cache args do + ::LearningObject::Attachment.new(args) + end + end + + private + + def self.build_from_cache(args={}) + object = nil + + unless args.nil? || !block_given? + # cache object when build + object = Rails.cache.fetch(cache_key(args['id'], args['link']), expires_in: 12.hours) { yield } + end + + object + end + + def self.permitted_args(args={}) + permitted = [:id, :name, :link, :retrieve_link, :description, :format, :mime_type, :size] + args.delete_if do |key, value| + !permitted.include? key.to_sym + end + end + + end +end \ No newline at end of file diff --git a/app/builders/learning_object_builder.rb b/app/builders/learning_object_builder.rb index 265b37861b6f653b768e30b57739488dedb79b13..10e6f22883c1642411eea54d8e683faec44caf58 100644 --- a/app/builders/learning_object_builder.rb +++ b/app/builders/learning_object_builder.rb @@ -17,7 +17,7 @@ class LearningObjectBuilder < Builder thumbnail: (args['thumbnail'] or ''), id_dspace: args['id_dspace'], type: args['type'], - attachment: LearningObject::Attachment.new(args['bitstreams']), + attachments: build_bitstreams_collection(args['bitstreams']), last_modified: args['last_modified'], metadata: args['metadata'] ) @@ -28,4 +28,10 @@ class LearningObjectBuilder < Builder end end + private + + def self.build_bitstreams_collection(bitstreams) + bitstreams.map {|bitstream| ::LearningObject::AttachmentBuilder.new(bitstream) } + end + end diff --git a/app/controllers/learning_object/chunks_controller.rb b/app/controllers/learning_object/chunks_controller.rb new file mode 100644 index 0000000000000000000000000000000000000000..4a7e2308a838dd553fb79de5502c1abd77449bfa --- /dev/null +++ b/app/controllers/learning_object/chunks_controller.rb @@ -0,0 +1,66 @@ +class LearningObject::ChunksController < ApplicationController + layout nil + + #GET /chunk + def show + #chunk folder path based on the parameters + dir = "/tmp/#{params[:resumableIdentifier]}" + #chunk path based on the parameters + chunk = "#{dir}/#{params[:resumableFilename]}.part#{params[:resumableChunkNumber]}" + + if File.exists?(chunk) + #Let resumable.js know this chunk already exists + render :nothing => true, :status => 200 + else + #Let resumable.js know this chunk doesnt exists and needs to be uploaded + render :nothing => true, :status => 404 + end + + end + + #POST /chunk + def create + + #chunk folder path based on the parameters + dir = "/tmp/#{params[:resumableIdentifier]}" + #chunk path based on the parameters + chunk = "#{dir}/#{params[:resumableFilename]}.part#{params[:resumableChunkNumber]}" + + #Create chunks directory when not present on system + if !File.directory?(dir) + FileUtils.mkdir(dir, :mode => 0700) + end + + #Move the uploaded chunk to the directory + FileUtils.mv params[:file].tempfile, chunk + + #Concatenate all the partial files into the original file + + currentSize = params[:resumableChunkNumber].to_i * params[:resumableChunkSize].to_i + filesize = params[:resumableTotalSize].to_i + + #When all chunks are uploaded + if (currentSize + params[:resumableCurrentChunkSize].to_i) >= filesize + + #Create a target file + File.open("#{dir}/#{params[:resumableFilename]}", "a") do |target| + #Loop trough the chunks + for i in 1..params[:resumableChunkNumber].to_i + #Select the chunk + chunk = File.open("#{dir}/#{params[:resumableFilename]}.part#{i}", 'r').read + + #Write chunk into target file + chunk.each_line do |line| + target << line + end + + #Deleting chunk + FileUtils.rm "#{dir}/#{params[:resumableFilename]}.part#{i}", :force => true + end + puts "File saved to #{dir}/#{params[:resumableFilename]}" + end + end + + render :nothing => true, :status => 200 + end +end diff --git a/app/models/learning_object.rb b/app/models/learning_object.rb index 98c24eecbf6eeba71112759b5be83e48a9404577..47b86e397fdf00933fd166e46f58a55d93961b63 100644 --- a/app/models/learning_object.rb +++ b/app/models/learning_object.rb @@ -5,20 +5,21 @@ class LearningObject attr_accessor :id, :id_dspace, :rid, :name, :author, :description, :published_at, :thumbnail, :created_at, :last_modified, - :type, :grade_level, :bitstreams, :metadata, :likes, :views, - :downloads, :subjects, :attributes, :score, :publisher, + :type, :grade_level, :metadata, :score, :school_level, :language, :source, :license, :copyright, - :country, :keywords, :file, - :grade_level, :attachment, :main_bitstream_id, + :country, :keywords, :grade_level, :attachments + # Relation attrs - :likes, :views, :downloads, :subjects, :attributes, :publisher + attr_accessor :likes, :views, :downloads, :subjects, :attributes, :publisher + + # Flags + attr_accessor :status validates_presence_of :name, :created_at, :type delegate :get_retrievelink, to: :attachment delegate :get_filename, to: :attachment - def initialize(params={}) super(params.merge(defaults)) end diff --git a/app/models/learning_object/attachment.rb b/app/models/learning_object/attachment.rb index ea56409fb23fc440979596d73ec999df7d6eadca..1aff7410484096c1d5a0551e2b2e897c92bb3ce8 100644 --- a/app/models/learning_object/attachment.rb +++ b/app/models/learning_object/attachment.rb @@ -1,32 +1,6 @@ class LearningObject::Attachment - attr_accessor :bitstreams - - def initialize(bitstreams) - @bitstreams = bitstreams - end - - def get_retrievelink - get_bitstream_retrievelink_of "ORIGINAL" - end - - def get_filename - get_bitstream_filename_of "ORIGINAL" - end - - private - - def get_bitstream_retrievelink_of name - values = @bitstreams.select { |v| v["bundleName"] == name } - unless values.empty? - return "#{DspaceService.link}#{values.first["retrieveLink"]}" - end - end - - def get_bitstream_filename_of name - values = @bitstreams.select { |v| v["bundleName"] == name } - unless values.empty? - return values.first["name"] - end - end + include ActiveModel::Model + #this attributes mirror Dspace bitstream values + attr_accessor :id, :name, :link, :retrieve_link, :description, :format, :mime_type, :size end diff --git a/config/routes.rb b/config/routes.rb index 67e975cbfc96f6fbad8ed47bcbd70c6843852bb7..f9d11ca1189474798f306ad25d27a31f9d646d91 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -66,6 +66,8 @@ Rails.application.routes.draw do post :like post :bookmarks get :collections + + resource :chunk, only: [:create, :show] end end diff --git a/test/controllers/learning_object/chunks_controller_test.rb b/test/controllers/learning_object/chunks_controller_test.rb new file mode 100644 index 0000000000000000000000000000000000000000..8ec754064fe875f7bbec6acf486f813b125f2073 --- /dev/null +++ b/test/controllers/learning_object/chunks_controller_test.rb @@ -0,0 +1,14 @@ +require 'test_helper' + +class LearningObject::ChunksControllerTest < ActionController::TestCase + test "should get show" do + get :show + assert_response :success + end + + test "should get create" do + get :create + assert_response :success + end + +end