162 lines
4.4 KiB
Ruby
162 lines
4.4 KiB
Ruby
#
|
|
# Copyright (C) 2012 Instructure, Inc.
|
|
#
|
|
# This file is part of Canvas.
|
|
#
|
|
# Canvas 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, version 3 of the License.
|
|
#
|
|
# Canvas 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
class CrocodocDocument < ActiveRecord::Base
|
|
attr_accessible :uuid, :process_state, :attachment_id
|
|
|
|
belongs_to :attachment
|
|
has_many :crocodoc_annotations
|
|
|
|
MIME_TYPES = %w(
|
|
application/pdf
|
|
application/msword
|
|
application/vnd.openxmlformats-officedocument.wordprocessingml.document
|
|
application/vnd.ms-powerpoint
|
|
application/vnd.openxmlformats-officedocument.presentationml.presentation
|
|
application/excel
|
|
application/vnd.ms-excel
|
|
)
|
|
|
|
def upload
|
|
return if uuid.present?
|
|
|
|
url = attachment.authenticated_s3_url(:expires => 1.day)
|
|
|
|
response = Canvas.timeout_protection("crocodoc") {
|
|
crocodoc_api.upload(url)
|
|
}
|
|
|
|
if response['uuid']
|
|
update_attributes :uuid => response['uuid'], :process_state => 'QUEUED'
|
|
else
|
|
raise response.inspect
|
|
end
|
|
end
|
|
|
|
def session_url(opts = {})
|
|
defaults = {
|
|
:annotations => true,
|
|
:downloadable => true,
|
|
}.with_indifferent_access
|
|
|
|
opts = defaults.merge(opts)
|
|
|
|
annotations_on = opts.delete(:annotations)
|
|
|
|
user = opts.delete(:user)
|
|
if user
|
|
opts[:user] = user.crocodoc_user
|
|
end
|
|
|
|
opts.merge! permissions_for_user(user)
|
|
|
|
unless annotations_on
|
|
opts[:filter] = 'none'
|
|
opts[:editable] = false
|
|
end
|
|
|
|
Canvas.timeout_protection("crocodoc") do
|
|
response = crocodoc_api.session(uuid, opts)
|
|
session = response['session']
|
|
crocodoc_api.view(session)
|
|
end
|
|
end
|
|
|
|
def permissions_for_user(user)
|
|
opts = {
|
|
:filter => 'none',
|
|
:admin => false,
|
|
:editable => false,
|
|
}
|
|
|
|
if user.blank?
|
|
return opts
|
|
else
|
|
opts[:editable] = true
|
|
opts[:filter] = user.crocodoc_id!
|
|
end
|
|
|
|
submissions = attachment.attachment_associations.
|
|
where(:context_type => 'Submission').
|
|
includes(:context).
|
|
map(&:context)
|
|
|
|
return opts unless submissions
|
|
|
|
if submissions.any? { |s| s.grants_right? user, :read_grade }
|
|
opts[:filter] = 'all'
|
|
|
|
if submissions.any? { |s| s.grants_right? user, :grade }
|
|
opts[:admin] = true
|
|
end
|
|
end
|
|
|
|
opts
|
|
end
|
|
|
|
def available?
|
|
!!(uuid && process_state != 'ERROR' && Canvas::Crocodoc.config)
|
|
end
|
|
|
|
def crocodoc_api
|
|
raise "Crocodoc isn't configured" unless Canvas::Crocodoc.config
|
|
@api ||= CrocodocDocument.crocodoc_api
|
|
end
|
|
private :crocodoc_api
|
|
|
|
def self.crocodoc_api
|
|
Crocodoc::API.new(:token => Canvas::Crocodoc.config['api_key'])
|
|
end
|
|
|
|
def self.update_process_states
|
|
bs = Setting.get('crocodoc_status_check_batch_size', '45').to_i
|
|
Shackles.activate(:slave) do
|
|
CrocodocDocument.where(:process_state => %w(QUEUED PROCESSING)).find_in_batches do |docs|
|
|
Shackles.activate(:master) do
|
|
statuses = []
|
|
docs.each_slice(bs) do |sub_docs|
|
|
statuses.concat CrocodocDocument.crocodoc_api.status(sub_docs.map(&:uuid))
|
|
end
|
|
|
|
statuses.each do |status|
|
|
uuid, state = status['uuid'], status['status']
|
|
CrocodocDocument.
|
|
where(:uuid => status['uuid']).
|
|
update_all(:process_state => status['status'])
|
|
if status['status'] == 'ERROR'
|
|
error = status['error'] || 'No explanation given'
|
|
ErrorReport.log_error 'crocodoc', :message => error
|
|
end
|
|
end
|
|
|
|
error_uuids = statuses.select { |s|
|
|
s['status'] == 'ERROR'
|
|
}.map { |s| s['uuid'] }
|
|
if error_uuids.present?
|
|
error_docs = CrocodocDocument.where(:uuid => error_uuids)
|
|
attachment_ids = error_docs.map(&:attachment_id)
|
|
Attachment.send_later_enqueue_args :submit_to_scribd,
|
|
{:n_strand => 'scribd', :max_attempts => 1},
|
|
attachment_ids
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|