From c6366231251542547b2a2d2807e2328bd8474451 Mon Sep 17 00:00:00 2001
From: Mauricio Giacomini Girardello <mgg12@inf.ufpr.br>
Date: Fri, 29 Jan 2016 11:45:14 -0200
Subject: [PATCH] raise exceptions when attachment already exists

---
 app/controllers/chunks_controller.rb          | 11 +++++++---
 .../duplicate_attachment_checker.rb           | 20 +++++++++++++++++++
 .../duplicate_attachment_error.rb             |  1 +
 app/services/learning_object_publisher.rb     |  7 +++++++
 .../_file_upload_form.html.erb                |  4 ++++
 app/workers/dspace_upload_worker.rb           | 12 +++++++++--
 6 files changed, 50 insertions(+), 5 deletions(-)
 create mode 100644 app/models/learning_object/duplicate_attachment_checker.rb
 create mode 100644 app/models/learning_object/duplicate_attachment_error.rb

diff --git a/app/controllers/chunks_controller.rb b/app/controllers/chunks_controller.rb
index 31fe75b84..b3c1c4023 100644
--- a/app/controllers/chunks_controller.rb
+++ b/app/controllers/chunks_controller.rb
@@ -59,11 +59,16 @@ class ChunksController < ApplicationController
         puts "File saved to #{resumable_filename}"
       end
 
-      publisher = LearningObjectPublisher.new(DspaceService.create_client)
-      publisher.post @learning_object, resumable_filename
+      begin
+        status = 200
+        publisher = LearningObjectPublisher.new(DspaceService.create_client)
+        publisher.post @learning_object, resumable_filename
+      rescue LearningObject::DuplicateAttachmentError => e
+        status = 406
+      end
     end
 
-    render :nothing => true, :status => 200
+    render :nothing => true, :status => status
   end
 
   private
diff --git a/app/models/learning_object/duplicate_attachment_checker.rb b/app/models/learning_object/duplicate_attachment_checker.rb
new file mode 100644
index 000000000..7f750666b
--- /dev/null
+++ b/app/models/learning_object/duplicate_attachment_checker.rb
@@ -0,0 +1,20 @@
+module LearningObject::DuplicateAttachmentChecker
+
+  def self.check_duplicates(learning_object, media_path)
+    file_size = File.size media_path
+    file_name = File.basename media_path
+
+    learning_object.attachments.each do |learning_object|
+      if attachment.size == file_size && attachment.name == file_name
+        return true
+      end
+    end
+  end
+
+  def self.check_duplicates!(learning_object, media_path)
+    if check_duplicates learning_object, media_path
+      raise DuplicateAttachmentError, 'The attachment already exists!'
+    end
+  end
+
+end
diff --git a/app/models/learning_object/duplicate_attachment_error.rb b/app/models/learning_object/duplicate_attachment_error.rb
new file mode 100644
index 000000000..39970c5e2
--- /dev/null
+++ b/app/models/learning_object/duplicate_attachment_error.rb
@@ -0,0 +1 @@
+class LearningObject::DuplicateAttachmentError < StandardError; end
\ No newline at end of file
diff --git a/app/services/learning_object_publisher.rb b/app/services/learning_object_publisher.rb
index bc41269d6..0711f3113 100644
--- a/app/services/learning_object_publisher.rb
+++ b/app/services/learning_object_publisher.rb
@@ -13,7 +13,10 @@ class LearningObjectPublisher
     learning_object_repository.create draft
   end
 
+  #post *media_path* to *learning_object* on dspace
+  #raise LearningObject::DuplicateAttachmentError if *media_path* already exists
   def post(learning_object, media_path)
+    check_duplicate_attachments! learning_object, media_path
     DspaceUploadWorker.perform_async learning_object.id, learning_object.id_dspace, media_path
   end
 
@@ -25,6 +28,10 @@ class LearningObjectPublisher
 
   private
 
+  def check_duplicate_attachments!(learning_object, media_path)
+    LearningObject::DuplicateAttachmentChecker.check_duplicates! learning_object, media_path
+  end
+
   # change *learning_object* status to active
   def activate!(learning_object)
     learning_object.status = 'active'
diff --git a/app/views/learning_objects/_file_upload_form.html.erb b/app/views/learning_objects/_file_upload_form.html.erb
index 5b32cd89f..50f7c3a3d 100644
--- a/app/views/learning_objects/_file_upload_form.html.erb
+++ b/app/views/learning_objects/_file_upload_form.html.erb
@@ -144,6 +144,10 @@
       $('[data-uniqueId=' + file.uniqueIdentifier + ']').find('.progress-bar').addClass('progress-bar-success');
     });
 
+    r.on('fileError', function (file, message) {
+      $('[data-uniqueId=' + file.uniqueIdentifier + ']').find('.progress-bar').addClass('progress-bar-danger');
+      $('[data-uniqueId=' + file.uniqueIdentifier + ']').find('.progress-bar').html('&nbsp;' + messages);
+    });
 
     r.on('uploadStart', function () {
       $('#upload_message').text('Enviando, aguarde...');
diff --git a/app/workers/dspace_upload_worker.rb b/app/workers/dspace_upload_worker.rb
index fda4dd7ea..0c582c3ee 100644
--- a/app/workers/dspace_upload_worker.rb
+++ b/app/workers/dspace_upload_worker.rb
@@ -4,12 +4,12 @@ class DspaceUploadWorker
 
   @@dspace= nil
 
-  def perform(learning_object_id, item_id, media_path)
+  def perform(learning_object_id, item_id, media_path, *options)
     # create file instance
     file = File.new(media_path, 'r')
 
     #create bitstream in dspace
-    bitstream = dspace.items.add_bitstream(file, id: item_id, name: File.basename(media_path), description: 'beta upload')
+    bitstream = dspace.items.add_bitstream(file, id: item_id, name: File.basename(media_path), description: get_description(options))
 
     #find learning object
     learning_object = learning_object_repository.find learning_object_id
@@ -35,4 +35,12 @@ class DspaceUploadWorker
     @@dspace ||= DspaceService.create_client
   end
 
+  def get_description(*options)
+    description = nil
+    if options.has_key? :description
+      description = options[:description]
+    end
+    description
+  end
+
 end
-- 
GitLab