diff --git a/app/builders/learning_object_builder.rb b/app/builders/learning_object_builder.rb
index 9428e079637a53b7c2319fc4cb9167dba42f4f78..8b5dcc077c5455bcf15599e20bc2a07bf3f73151 100644
--- a/app/builders/learning_object_builder.rb
+++ b/app/builders/learning_object_builder.rb
@@ -18,7 +18,7 @@
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
 
 class LearningObjectBuilder
-  def self.build_from_dspace(item)
+  def self.build_from_dspace(item, publisher)
     lo = LearningObject.new(
       name: item.name,
       id_dspace: item.id,
@@ -27,16 +27,18 @@ class LearningObjectBuilder
     )
 
     lo.curator = lo.get_metadata_value_of('dc.curator')
-    institution = lo.get_metadata_value_of('dc.creator')
-    institution = 'Desconhecido' if institution.blank?
-    lo.publisher = Institution.where(name: institution).first_or_create
+    # institution = lo.get_metadata_value_of('dc.creator')
+    # institution = 'Desconhecido' if institution.blank?
+    # lo.publisher = Institution.where(name: institution).first_or_create
+    lo.publisher = publisher
 
     object_type = lo.get_metadata_value_of('dc.type')
     object_type = 'Desconhecido' if object_type.blank?
     lo.object_type = ObjectType.where(name: object_type).first_or_create
 
-    date = lo.get_metadata_value_of('dc.date.issued')
-    lo.published_at = Time.iso8601(date) unless date.nil?
+    # date = lo.get_metadata_value_of('dc.date.issued')
+    # lo.published_at = Time.iso8601(date) unless date.nil?
+    lo.published_at = Time.current
 
     code = lo.get_metadata_value_of('dc.language')
     code = 'pt' if code.blank?
diff --git a/app/controllers/concerns/sociable_controller.rb b/app/controllers/concerns/sociable_controller.rb
index 82a96c83234c9582d091923146c53e115c78fef1..022ff389096935fb798386a6b05c267d39cc1288 100644
--- a/app/controllers/concerns/sociable_controller.rb
+++ b/app/controllers/concerns/sociable_controller.rb
@@ -18,7 +18,8 @@
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
 
 ## This concern has +like+, +unlike+ controller actions
-## When you use it, be sure that +set_sociable+ method is implemented in your controller, otherwise an fatal error will raise.
+## When you use it, be sure that +set_sociable+ method is implemented in your controller, otherwise a fatal error will raise.
+
 module SociableController
   extend ActiveSupport::Concern
 
@@ -55,7 +56,8 @@ module SociableController
   end
 
   def view_object!
-    sociable.view current_user if user_signed_in?
+    # Change request.remote_ip to req.env["HTTP_X_REAL_IP"] in production
+    sociable.view(current_user, request.remote_ip)
   end
 
 end
diff --git a/app/mailers/dspace_mailer.rb b/app/mailers/dspace_mailer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9226aabf5116fbdb893e3c020f8de7e14b6a4024
--- /dev/null
+++ b/app/mailers/dspace_mailer.rb
@@ -0,0 +1,27 @@
+
+# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
+# Departamento de Informatica - Universidade Federal do Parana
+#
+# This file is part of portalmec.
+#
+# portalmec is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# portalmec is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
+
+class DspaceMailer < ApplicationMailer
+  default to: 'portalmec_tec@inf.ufpr.br'
+
+  def dspace_info_updated(partner)
+    @partner = partner
+    mail(subject: "Dados para OAI harvest atualizados")
+  end
+end
diff --git a/app/models/concerns/sociable.rb b/app/models/concerns/sociable.rb
index e199ac7bc1bcb1d3b457ab938478469665f14f79..3dfaaebf7aaec6ded03626a3e074f6eaaedf1b33 100644
--- a/app/models/concerns/sociable.rb
+++ b/app/models/concerns/sociable.rb
@@ -46,8 +46,8 @@ module Sociable
     !Share.where(user: user, shareable: self).blank?
   end
 
-  def view(user)
-    View.create(user: user, viewable: self)
+  def view(user, ip)
+    View.create(user: user, ip: ip, viewable: self)
   end
 
   def viewed?(user)
diff --git a/app/models/learning_object.rb b/app/models/learning_object.rb
index 5b0b8426b1c4b776cc2422453408b6f004f4eb2e..547636e65042441f8d31476de95badba19596e55 100644
--- a/app/models/learning_object.rb
+++ b/app/models/learning_object.rb
@@ -117,17 +117,19 @@ class LearningObject < ApplicationRecord
   end
 
   def default_attachment
-    return attachment unless attachment.nil?
+    #return attachment unless attachment.nil?
 
     unless attachments.blank?
       if object_type.try(:name) == 'Vídeo'
         at = attachments.where("name LIKE '%.mp4'").first
         return at unless at.nil?
       end
-      at = attachments.find_by(bundle_name: 'ORIGINAL')
-      at = attachments.first if at.nil?
-      update(attachment: at)
-      return attachment
+      at = attachments.where("name NOT LIKE '%.torrent' AND bundle_name = 'ORIGINAL'")
+      # at = attachments.first if at.nil?
+      unless at.blank?
+          update(attachment: at.first)
+          return attachment
+      end
     end
     nil
   end
@@ -141,6 +143,7 @@ class LearningObject < ApplicationRecord
     return thumbnail unless thumbnail.blank?
     return nil if attachments.blank?
     return default_attachment.thumbnail unless default_attachment.thumbnail.blank?
+    ThumbnailGenerateWorker.perform_async(default_attachment.id)
     attachments.each { |a| return a.thumbnail unless a.thumbnail.blank? }
     nil
   end
diff --git a/app/models/user.rb b/app/models/user.rb
index a8befa530f2b3f6cdace98f1372f7285289fee5e..1b717bf606a5f5e078737c7f7281ef8c466c335b 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -88,6 +88,7 @@ class User < ApplicationRecord
   has_many :applications
 
   after_create :default_role
+  after_save :verify_dspace_info
 
   has_attached_file :avatar, styles: { medium: '300x300>', thumb: '60x60>' }, default_url: ''
   validates_attachment_content_type :avatar, content_type: ['image/jpg', 'image/jpeg', 'image/png', 'image/gif']
@@ -159,6 +160,13 @@ class User < ApplicationRecord
     false
   end
 
+  def is_publisher?
+    roles.each do |role|
+      return true if role.name == 'publisher'
+    end
+    false
+  end
+
   def is_partner?
     roles.each do |role|
       return true if role.name == 'partner'
@@ -274,6 +282,12 @@ class User < ApplicationRecord
     )
   end
 
+  def verify_dspace_info
+    if roles.include?(Role.find_by_name("partner")) && !(changed & ["dspace_url", "dspace_handle", "dspace_sets"]).empty?
+      DspaceMailer.dspace_info_updated(self).deliver_now
+    end
+  end
+
   def activity_owner
     self
   end
@@ -284,7 +298,7 @@ class User < ApplicationRecord
 
   def update_tracked_fields(request)
     super
-    # Change request.remote_ip to req.env["HTTP_X_REAL_IP"] in production
+    # Change request.remote_ip to request.env["HTTP_X_REAL_IP"] in production
     self.current_sign_in_ip = request.remote_ip
   end
 end
diff --git a/app/models/view.rb b/app/models/view.rb
index 2e2d995e58d8e375c5126767510c1eef16feae3d..c6e4f9f1fc93726f5d0c2723080ace7bed326853 100644
--- a/app/models/view.rb
+++ b/app/models/view.rb
@@ -27,6 +27,7 @@
 #  user_id       :integer
 #  created_at    :datetime         not null
 #  updated_at    :datetime         not null
+#  ip            :string
 #
 
 class View < ApplicationRecord
@@ -34,14 +35,12 @@ class View < ApplicationRecord
   include Trackable
 
   belongs_to :viewable, polymorphic: true, counter_cache: true
-  belongs_to :user
+  belongs_to :user, optional: true
 
-  validates_presence_of :user, :viewable
+  validates_presence_of :viewable, :ip
 
   before_create :current_time_greater_than_last
 
-  scope :created_last, ->(user) { where(user: user).order('created_at DESC').limit(1) }
-
   def recipient
     viewable
   end
@@ -49,7 +48,7 @@ class View < ApplicationRecord
   private
 
   def current_time_greater_than_last
-    last_view = viewable.views.created_last(user).first
+    last_view = viewable.views.where(user: user, ip: ip).order('created_at DESC').limit(1).first
 
     unless last_view.blank?
       return false if Time.current < (last_view.created_at + 1.day)
diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb
index 3924bd854db6a0638ce3d4082db9e8d63591c7c4..62709b8f622701484ba0590822e9dd91673cd885 100644
--- a/app/policies/application_policy.rb
+++ b/app/policies/application_policy.rb
@@ -74,12 +74,20 @@ class ApplicationPolicy
     raise 'You must implement this method!'
   end
 
+  def user_can_create?
+    (user_exists? && user.is_submitter?) || (user_exists? && user.is_publisher?)
+  end
+
   def user_can_edit?
     user.is_admin? || user.is_editor?
   end
 
   def user_can_update?
-    (owns? && user.is_submitter?) || (owns? && user.is_partner?) || user.is_admin?
+    (owns? && user.is_publisher?) || (owns? && user.is_submitter?) || (owns? && user.is_partner?) || user.is_admin?
+  end
+
+  def user_can_publish?
+    (user_can_curate? && record.submitted?) || (owns? && user.is_publisher?)
   end
 
   def user_can_curate?
diff --git a/app/policies/learning_object_policy.rb b/app/policies/learning_object_policy.rb
index c37f238e19568ce58d8d08065457361cbf1934fb..a3a49e091ecc5c586abf7a9c48833470b0f12970 100644
--- a/app/policies/learning_object_policy.rb
+++ b/app/policies/learning_object_policy.rb
@@ -38,7 +38,7 @@ class LearningObjectPolicy < ApplicationPolicy
   end
 
   def create?
-    record if (user_exists? && user.is_submitter?)
+    record if user_can_create?
   end
 
   def update?
@@ -46,7 +46,7 @@ class LearningObjectPolicy < ApplicationPolicy
   end
 
   def publish?
-    record if (user_can_curate? && record.submitted?)
+    record if user_can_publish?
   end
 
   def destroy?
diff --git a/app/services/dspace/learning_object_importer.rb b/app/services/dspace/learning_object_importer.rb
index 1031196614c5063d63938a139ae0e6b19cc15cf4..5b200c69d7502611eb610f4a3a697d9e6dab02a8 100644
--- a/app/services/dspace/learning_object_importer.rb
+++ b/app/services/dspace/learning_object_importer.rb
@@ -19,8 +19,9 @@
 
 class Dspace::LearningObjectImporter
 
-  def initialize(items)
+  def initialize(items, publisher)
     @items = items
+    @publisher = publisher
   end
 
   def import
@@ -28,14 +29,14 @@ class Dspace::LearningObjectImporter
 
     @items.each do |item|
       next if item_exists? item
-      learning_object = LearningObjectBuilder.build_from_dspace(item)
+      learning_object = LearningObjectBuilder.build_from_dspace(item, @publisher)
       next if learning_object.blank?
       create_attachments(learning_object, item.bit_streams)
       items << learning_object
       yield(learning_object) if block_given?
     end
 
-    LearningObject.import items, recursive: true
+    LearningObject.import items, recursive: true unless items.empty?
   end
 
   private
@@ -44,6 +45,7 @@ class Dspace::LearningObjectImporter
     bitstreams = JSON.parse bitstreams if bitstreams.class == String
     bitstreams.each do |bitstream|
       learning_object.attachments.new ::Dspace::AttachmentMapper.call(bitstream)
+      ThumbnailGenerateWorker.perform_async(learning_object.attachments.last)
     end
   end
 
diff --git a/app/services/learning_object_publisher.rb b/app/services/learning_object_publisher.rb
index 5b4554333f16e0b4d83fba9401fdca7b891829f4..4d1b439ee894915efc72effd817224deed32d863 100644
--- a/app/services/learning_object_publisher.rb
+++ b/app/services/learning_object_publisher.rb
@@ -51,7 +51,11 @@ class LearningObjectPublisher
 
     learning_object.state = LearningObject.states[:published]
     learning_object.published_at = Time.current
-    ThumbnailGenerateWorker.perform_async learning_object.id, learning_object.link if learning_object.link?
+    if learning_object.link?
+      att = LearningObject::Attachment.new
+      ThumbnailGenerateWorker.perform_async(att.id, learning_object.link)
+    end
+    # ThumbnailGenerateWorker.perform_async learning_object.id, learning_object.link if learning_object.link?
     learning_object.save
   end
 
diff --git a/app/views/dspace_mailer/dspace_info_updated.erb b/app/views/dspace_mailer/dspace_info_updated.erb
new file mode 100644
index 0000000000000000000000000000000000000000..a99129bae771d75b6493245cf9e1978bea1621c9
--- /dev/null
+++ b/app/views/dspace_mailer/dspace_info_updated.erb
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <style>/* Email styles need to be inline */</style>
+  </head>
+  <body>
+  <h2>ID do usuário: <%= @partner.id %></h1>
+  <h2>Nome do usuário: <%= @partner.name %></h1>
+  <h2>URL do DSpace: <%= @partner.dspace_url %></h1>
+  <h2>Handle: <%= @partner.dspace_url %></h1>
+  <h2>Sets: <%= @partner.dspace_sets.join(",") %></h1>
+  </body>
+</html>
diff --git a/app/workers/package_worker.rb b/app/workers/package_worker.rb
index 20a2fd34b9e9a7c5ef3615d4291c8f08308c48f3..4e2130da73ad7b4d46ba529b6b9a8c0a457eb61f 100644
--- a/app/workers/package_worker.rb
+++ b/app/workers/package_worker.rb
@@ -70,6 +70,7 @@ class PackageWorker
     Zip::File.open(PackageService.file_root(filename), Zip::File::CREATE) do |zipfile|
       files.each { |file| zipfile.add(File.basename(file.path), file.path) }
     end
+    FileUtils.chown_R 'portalmec', 'portalmec', PackageService.file_root.to_s, verbose: true
   rescue => e
     file = PackageService.file_root(filename)
     FileUtils.rm(file) if File.exist?(file)
diff --git a/db/migrate/20180406125006_add_ip_to_views.rb b/db/migrate/20180406125006_add_ip_to_views.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1af87bf47696a4ad206b7bd98d071d2106f52639
--- /dev/null
+++ b/db/migrate/20180406125006_add_ip_to_views.rb
@@ -0,0 +1,24 @@
+
+# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
+# Departamento de Informatica - Universidade Federal do Parana
+#
+# This file is part of portalmec.
+#
+# portalmec is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# portalmec is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
+
+class AddIpToViews < ActiveRecord::Migration[5.0]
+  def change
+    add_column :views, :ip, :string
+  end
+end
diff --git a/db/seeds.rb b/db/seeds.rb
index 108a59c06e460185ea97f6937356391770c138b2..7b991bd611c001ac58647ac40922323703191f51 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -33,6 +33,7 @@ Role.create(name: 'supervisor', description: 'This role represents an user Super
 Role.create(name: 'editor', description: 'This role represents a content Supervisor in Portal MEC, with less privileges than admin.')
 Role.create(name: 'submitter', description: 'This role represents a content submitter in Portal MEC.')
 Role.create(name: 'partner', description: 'This role represents a partner Portal MEC.')
+Role.create(name: 'publisher', description: 'This role represents a content publisher without supervision in Portal MEC.')
 
 # create the default admin
 User.create(
diff --git a/lib/tasks/import/learning_objects.rake b/lib/tasks/import/learning_objects.rake
index 0b9ae5583f74e64751ec058249810c320d493775..9b0947086efb3161a02f3fa00143c4f6951f7b46 100644
--- a/lib/tasks/import/learning_objects.rake
+++ b/lib/tasks/import/learning_objects.rake
@@ -17,9 +17,51 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
 
+require 'openssl'
+
 namespace :import do
   desc 'import learning objects from dspace'
 
+  task :sync_learning_objects => :environment do
+    desc 'Synchronize Learning Objects with DSpace Items'
+    OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
+
+    # IDEA: create DSpace collections once dspace_sets are updated
+    #       and then search for items based on the collection id
+    # TODO: Deal with already existing item/LO
+    # TODO: Deal with deleted items
+    params = {
+      q: "search.resourcetype:2", # AND location.coll:4
+      fq: "dc.date.accessioned_dt:[NOW-1DAY TO NOW]",
+      wt: "json",
+      indent: "true"
+    }
+    uri = URI(DspaceService.link + "/solr/search/select")
+
+    users = User.joins(:roles).where(roles: {name: "partner"}).where.not(dspace_url: [nil, ""], dspace_handle: [nil, ""])
+    users.each do |user|
+      user_params = params
+      user_params[:q] += " AND handle: #{user.dspace_handle}/*"
+
+      uri.query = URI.encode_www_form(user_params)
+      response = JSON.parse(Net::HTTP.get(uri))
+      items = []
+      response["response"]["docs"].each do |doc|
+        item = dspace_client.items.find(
+          id: doc["search.resourceid"],
+          expand: "metadata,bitstreams,parentCollection"
+        )
+        if items.is_a? String
+          logger.warn "Received a string instead of item: #{item}"
+          next
+        end
+        items << item
+      end
+      importer = Dspace::LearningObjectImporter.new(items, user)
+      importer.import
+    end
+  end
+
   task :learning_object, [:log] => [:environment] do |_t, args|
     desc 'Importing Learning Objects from Dspace items'
 
diff --git a/spec/acceptance/learning_objects_spec.rb b/spec/acceptance/learning_objects_spec.rb
index 44e7b5e57bf59cad3df21df09ff1667f4d82868a..6a1b16c8b1b5452f99110f242f9b0e2336ef2474 100644
--- a/spec/acceptance/learning_objects_spec.rb
+++ b/spec/acceptance/learning_objects_spec.rb
@@ -60,7 +60,7 @@ resource 'Learning Objects' do
   end
 
   post '/v1/learning_objects' do
-    include_context "authenticate_user_submitter"
+    include_context "authenticate_user_publisher"
 
     parameter :author, 'The author of a educational content', scope: :learning_object
     parameter :name, 'The name of the learning object', scope: :learning_object
@@ -98,7 +98,7 @@ resource 'Learning Objects' do
   end
 
   put '/v1/learning_objects/:id' do
-    include_context "authenticate_user_submitter"
+    include_context "authenticate_user_publisher"
 
     parameter :author, 'The author of a educational content'
     parameter :name, 'The name of the learning object'
@@ -178,7 +178,7 @@ resource 'Learning Objects' do
    end
 
   post '/v1/learning_objects/:id/publish' do
-    include_context "authenticate_user_curator"
+    include_context "authenticate_user_publisher"
 
     let(:id) { @learning_object.id }
 
diff --git a/spec/shared/contexts.rb b/spec/shared/contexts.rb
index 90ba69ca40ca86993b00c2e59a274f92e42f34e3..3d72a5ff205dbe901de7ac1698e32ac5f267e9d6 100644
--- a/spec/shared/contexts.rb
+++ b/spec/shared/contexts.rb
@@ -61,6 +61,19 @@ RSpec.shared_context "authenticate_user_submitter", shared_context: :metadata do
 
 end
 
+RSpec.shared_context "authenticate_user_publisher", shared_context: :metadata do
+  let(:auth_client) { @auth_headers['client'] }
+  let(:uid) { @auth_headers['uid'] }
+  let(:access_token) { @auth_headers['access-token'] }
+  let(:role) { Role.all }
+
+  before do
+    @user = create(:user, roles: [role.find_by(name: 'publisher')])
+    @auth_headers = @user.create_new_auth_token
+  end
+
+end
+
 RSpec.shared_context "authenticate_user_curator", shared_context: :metadata do
   let(:auth_client) { @auth_headers['client'] }
   let(:uid) { @auth_headers['uid'] }