canvadocs annotations

closes CNVS-20189
closes CNVS-19902

Test plan:
  * enable canvadocs and crocodoc
    * enable annotations for canvadocs
  * homework submissions should be submitted to canvadocs (not crocodoc)
    (you can tell the difference by the unicycling panda)
  * disable crocodoc
  * annotations should still work (through canvadocs)
  * annotations should work the same as they did through crocodoc (but
    now more doc types are supported)

Change-Id: I041b40d2545545c7766b57f98ea194b777fdef30
Reviewed-on: https://gerrit.instructure.com/59697
Tested-by: Jenkins
Reviewed-by: Josh Simpson <jsimpson@instructure.com>
QA-Review: Jason Carter <jcarter@instructure.com>
Product-Review: Cameron Matheson <cameron@instructure.com>
This commit is contained in:
Cameron Matheson 2015-07-14 15:10:08 -06:00
parent fc90918df4
commit 2a1b1ccbe0
7 changed files with 87 additions and 16 deletions

View File

@ -31,7 +31,7 @@ class CanvadocSessionsController < ApplicationController
if attachment.canvadocable?
attachment.submit_to_canvadocs unless attachment.canvadoc_available?
url = attachment.canvadoc.session_url
url = attachment.canvadoc.session_url(user: @current_user)
redirect_to url
else
render :text => "Not found", :status => :not_found

View File

@ -1198,7 +1198,10 @@ class Attachment < ActiveRecord::Base
# ... or crocodoc (this will go away soon)
return if Attachment.skip_3rd_party_submits?
if opts[:wants_annotation] && crocodocable?
submit_to_crocodoc_instead = opts[:wants_annotation] &&
crocodocable? &&
!Canvadocs.annotations_supported?
if submit_to_crocodoc_instead
# get crocodoc off the canvadocs strand
# (maybe :wants_annotation was a dumb idea)
send_later_enqueue_args :submit_to_crocodoc, {
@ -1208,12 +1211,12 @@ class Attachment < ActiveRecord::Base
}, attempt
elsif canvadocable?
doc = canvadoc || create_canvadoc
doc.upload
doc.upload annotatable: opts[:wants_annotation]
update_attribute(:workflow_state, 'processing')
end
rescue => e
update_attribute(:workflow_state, 'errored')
Canvas::Errors.capture(e, type: :canvadocs, attachment_id: id)
Canvas::Errors.capture(e, type: :canvadocs, attachment_id: id, annotatable: opts[:wants_annotation])
if attempt <= Setting.get('max_canvadocs_attempts', '5').to_i
send_later_enqueue_args :submit_to_canvadocs, {

View File

@ -21,17 +21,20 @@ class Canvadoc < ActiveRecord::Base
belongs_to :attachment
def upload
def upload(opts = {})
return if document_id.present?
url = attachment.authenticated_s3_url(:expires => 1.day)
response = Canvas.timeout_protection("canvadocs") {
canvadocs_api.upload(url)
canvadocs_api.upload(url, opts)
}
if response && response['id']
update_attributes document_id: response['id'], process_state: response['status']
self.document_id = response['id']
self.process_state = response['status']
self.has_annotations = opts[:annotatable]
self.save!
elsif response.nil?
raise "no response received (request timed out?)"
else
@ -39,13 +42,48 @@ class Canvadoc < ActiveRecord::Base
end
end
def session_url
def session_url(opts = {})
user = opts.delete(:user)
opts.merge! annotation_opts(user)
Canvas.timeout_protection("canvadocs", raise_on_timeout: true) do
session = canvadocs_api.session(document_id)
session = canvadocs_api.session(document_id, opts)
canvadocs_api.view(session["id"])
end
end
def annotation_opts(user)
return {} if !user || !has_annotations?
opts = {
annotation_context: "default",
permissions: "readwrite",
user_id: user.global_id,
user_name: user.short_name.gsub(",", ""),
user_role: "",
user_filter: user.global_id,
}
submissions = attachment.attachment_associations.
where(:context_type => 'Submission').
preload(context: [:assignment]).
map(&:context)
return opts if submissions.empty?
if submissions.any? { |s| s.grants_right? user, :read_grade }
opts.delete :user_filter
end
# no commenting when anonymous peer reviews are enabled
if submissions.map(&:assignment).any? { |a| a.peer_reviews? && a.anonymouis_peer_reviews? }
opts = {}
end
opts
end
private :annotation_opts
def available?
!!(document_id && process_state != 'error' && Canvadocs.enabled?)
end

View File

@ -14,6 +14,9 @@
<td><%= f.blabel :base_url, :en => "Base URL" %></td>
<td><%= f.text_field :base_url %></td>
</tr>
<tr>
<td><%= f.blabel :annotations_supported, :en => "Annotations Supported" %></td>
<td><%= f.check_box :annotations_supported %></td>
</table>
<% end %>

View File

@ -0,0 +1,7 @@
class AddHasAnnotationsToCanvadocs < ActiveRecord::Migration
tag :predeploy
def change
add_column :canvadocs, :has_annotations, :bool
end
end

View File

@ -35,6 +35,7 @@ module Canvadocs
# Public: Create a document with the file at the given url.
#
# obj - a url string
# params - other post params
#
# Examples
#
@ -42,12 +43,12 @@ module Canvadocs
# # => { "id": 1234, "status": "queued" }
#
# Returns a hash containing the document's id and status
def upload(obj)
def upload(obj, extra_params = {})
params = if obj.is_a?(File)
{ :file => obj }
{ :file => obj }.merge(extra_params)
raise Canvadocs::Error, "TODO: support raw files"
else
{ :url => obj.to_s }
{ :url => obj.to_s }.merge(extra_params)
end
raw_body = api_call(:post, "documents", params)
@ -175,4 +176,8 @@ module Canvadocs
def self.enabled?
!!config
end
def self.annotations_supported?
Canvas::Plugin.value_to_boolean config["annotations_supported"]
end
end

View File

@ -69,6 +69,15 @@ describe Attachment do
Crocodoc::API.any_instance.stubs(:upload).returns 'uuid' => '1234567890'
end
def configure_canvadocs(opts = {})
ps = PluginSetting.where(name: "canvadocs").first_or_create
ps.update_attribute :settings, {
"api_key" => "blahblahblahblahblah",
"base_url" => "http://example.com",
"annotations_supported" => true
}.merge(opts)
end
context "crocodoc" do
include HmacHelper
let_once(:user) { user_model }
@ -148,9 +157,7 @@ describe Attachment do
context "canvadocs" do
before :once do
PluginSetting.create! :name => 'canvadocs',
:settings => {"api_key" => "blahblahblahblahblah",
"base_url" => "http://example.com"}
configure_canvadocs
end
before :each do
@ -183,8 +190,16 @@ describe Attachment do
}
end
it "prefers crocodoc when annotation is requested" do
it "sends annotatable documents to canvadocs if supported" do
configure_crocodoc
a = crocodocable_attachment_model
a.submit_to_canvadocs 1, wants_annotation: true
expect(a.canvadoc).not_to be_nil
end
it "prefers crocodoc when annotation is requested and canvadocs can't annotate" do
configure_crocodoc
configure_canvadocs "annotations_supported" => false
Setting.set('canvadoc_mime_types',
(Canvadoc.mime_types << "application/blah").to_json)