create the media object for submissions and comments if it doesn't exist

Check Kaltura to verify the media id is valid, then create the object,
so that we can track it as we normally do.

fixes #5775

also update some of the submission api documentation around media
comments and file uploads.

test plan: there isn't a UI to show media objects yet, so you'll have to
have console/db access. submit a video/audio submission comment through
the API, then verify that after jobs run, a MediaObject exists for the
media id you gave.

Change-Id: Id0f5b4cdc23330ea952e674df4fc0d1f1c81bf23
Reviewed-on: https://gerrit.instructure.com/12245
Reviewed-by: Simon Williams <simon@instructure.com>
Tested-by: Jenkins <jenkins@instructure.com>
This commit is contained in:
Brian Palmer 2012-07-13 15:51:26 -06:00
parent 1edc78ea73
commit 6c8efd8322
8 changed files with 92 additions and 16 deletions

View File

@ -181,7 +181,7 @@ class SubmissionsApiController < ApplicationController
end
end
# @API Grade a submission
# @API Grade or comment on a submission
#
# Comment on and/or update the grading for a student's assignment submission.
# If any submission or rubric_assessment arguments are provided, the user
@ -192,6 +192,13 @@ class SubmissionsApiController < ApplicationController
#
# @argument comment[group_comment] [Boolean] Whether or not this comment should be sent to the entire group (defaults to false). Ignored if this is not a group assignment or if no text_comment is provided.
#
# @argument comment[media_comment_id] Add an audio/video comment to the submission.
# Media comments can be added via this API, however, note that there
# is not yet an API to generate or list existing media comments, so this
# functionality is currently of limited use.
#
# @argument comment[media_comment_type] ["audio"|"video"] The type of media comment being added.
#
# @argument submission[posted_grade] Assign a score to the submission,
# updating both the "score" and "grade" fields on the submission record.
# This parameter can be passed in a few different formats:
@ -278,11 +285,6 @@ class SubmissionsApiController < ApplicationController
if comment.is_a?(Hash)
comment = {
:comment => comment[:text_comment], :author => @current_user }.merge(
# Undocumented API feature: adding media comments given the kaltura
# media id. Eventually we'll expose a public API for media comments,
# but we need to implement a way to abstract it away from kaltura and
# make it generic. This will probably involve a proxy outside of
# rails.
comment.slice(:media_comment_id, :media_comment_type, :group_comment)
).with_indifferent_access
@assignment.update_submission(@submission.user, comment)

View File

@ -239,8 +239,7 @@ class SubmissionsController < ApplicationController
# one or more previously uploaded files residing in the submitting user's
# files section (or the group's files section, for group assignments).
#
# There is not yet an API for listing a user's or group's files, or
# uploading files for submission. This API is coming soon.
# To upload a new file to submit, see the submissions {api:SubmissionsApiController#create_file Upload a file API}.
#
# Requires a submission_type of "online_upload".
#

View File

@ -155,7 +155,27 @@ class MediaObject < ActiveRecord::Base
build_media_objects(res, root_account_id)
end
end
def self.media_id_exists?(media_id)
client = Kaltura::ClientV3.new
client.startSession(Kaltura::SessionType::ADMIN)
info = client.mediaGet(media_id)
return !!info[:id]
end
def self.ensure_media_object(media_id, create_opts = {})
if !by_media_id(media_id).any?
self.send_later_enqueue_args(:create_if_id_exists, { :priority => Delayed::LOW_PRIORITY }, media_id, create_opts)
end
end
# typically call this in a delayed job, since it has to contact kaltura
def self.create_if_id_exists(media_id, create_opts = {})
if media_id_exists?(media_id) && !by_media_id(media_id).any?
create!(create_opts.merge(:media_id => media_id))
end
end
def update_title_on_kaltura
client = Kaltura::ClientV3.new
client.startSession(Kaltura::SessionType::ADMIN)
@ -251,7 +271,6 @@ class MediaObject < ActiveRecord::Base
def data
self.read_attribute(:data) || self.write_attribute(:data, {})
end
def viewed!
send_later(:updated_viewed_at_and_retrieve_details, Time.now) if !self.data[:last_viewed_at] || self.data[:last_viewed_at] > 1.hour.ago

View File

@ -106,6 +106,7 @@ class Submission < ActiveRecord::Base
after_save :update_final_score
after_save :submit_to_turnitin_later
after_save :update_admins_if_just_submitted
after_save :check_for_media_object
after_save :update_quiz_submission
def self.needs_grading_trigger_sql
@ -481,6 +482,15 @@ class Submission < ActiveRecord::Base
end
true
end
def check_for_media_object
if self.media_comment_id.present? && self.media_comment_id_changed?
MediaObject.ensure_media_object(self.media_comment_id, {
:user => self.user,
:context => self.user,
})
end
end
def submission_history
res = []

View File

@ -27,8 +27,6 @@ class SubmissionComment < ActiveRecord::Base
has_many :associated_attachments, :class_name => 'Attachment', :as => :context
has_many :submission_comment_participants, :dependent => :destroy
has_many :messages, :as => :context, :dependent => :destroy
# too bad, this wont work.
# has_many :comments_in_group, :class_name => "SubmissionComment", :foreign_key => "group_comment_id", :primary_key => "group_comment_id", :dependent => :destroy, :conditions => lambda{|sc| "id !=#{sc.id}"}
validates_length_of :comment, :maximum => maximum_text_length, :allow_nil => true, :allow_blank => true
validates_length_of :comment, :minimum => 1, :allow_nil => true, :allow_blank => true
@ -37,6 +35,7 @@ class SubmissionComment < ActiveRecord::Base
before_save :infer_details
after_save :update_submission
after_save :check_for_media_object
after_destroy :delete_other_comments_in_this_group
after_create :update_participants
after_create { |c| c.submission.create_or_update_conversations!(:create) if c.send_to_conversations? }
@ -62,6 +61,15 @@ class SubmissionComment < ActiveRecord::Base
self.media_comment_id && self.media_comment_type
end
def check_for_media_object
if self.media_comment? && self.media_comment_id_changed?
MediaObject.ensure_media_object(self.media_comment_id, {
:user => self.author,
:context => self.author,
})
end
end
on_create_send_to_streams do
if self.submission
if self.author_id == self.submission.user_id
@ -209,8 +217,4 @@ class SubmissionComment < ActiveRecord::Base
named_scope :for_context, lambda{|context|
{:conditions => ['submission_comments.context_id = ? AND submission_comments.context_type = ?', context.id, context.class.to_s] }
}
# protected :infer_details
# named_scope :for, lambda {|user|
# {:conditions => ['(submission_comments.recipient_id IS NULL OR submission_comments.recipient_id = ?)', (user ? user.id : 0)]}
# }
end

View File

@ -50,4 +50,31 @@ describe MediaObject do
@a2.reload.file_state.should == 'available'
end
end
describe ".ensure_media_object" do
it "should not create if the media object exists already" do
MediaObject.create!(:context => user, :media_id => "test")
expect {
MediaObject.ensure_media_object("test", {})
}.to change(Delayed::Job, :count).by(0)
end
it "should not create if the media id doesn't exist in kaltura" do
MediaObject.expects(:media_id_exists?).with("test").returns(false)
expect {
MediaObject.ensure_media_object("test", {})
run_jobs
}.to change(MediaObject, :count).by(0)
end
it "should create the media object" do
MediaObject.expects(:media_id_exists?).with("test").returns(true)
expect {
MediaObject.ensure_media_object("test", { :context => user })
run_jobs
}.to change(MediaObject, :count).by(1)
obj = MediaObject.by_media_id("test").first
obj.context.should == @user
end
end
end

View File

@ -158,6 +158,14 @@ This text has a http://www.google.com link in it...
@item.data.submission_comments[0].formatted_body.should eql(@comment.formatted_body(250))
end
it "should ensure the media object exists" do
assignment_model
se = @course.enroll_student(user)
@submission = @assignment.submit_homework(se.user, :body => 'some message')
MediaObject.expects(:ensure_media_object).with("fake", { :context => se.user, :user => se.user })
@comment = @submission.add_comment(:author => se.user, :media_comment_type => 'audio', :media_comment_id => 'fake')
end
context "conversations" do
before do
assignment_model

View File

@ -104,6 +104,13 @@ describe Submission do
@submission.conversation_groups.should eql @submission.conversation_groups.uniq
end
it "should ensure the media object exists" do
assignment_model
se = @course.enroll_student(user)
MediaObject.expects(:ensure_media_object).with("fake", { :context => se.user, :user => se.user })
@submission = @assignment.submit_homework(se.user, :media_comment_id => "fake", :media_comment_type => "audio")
end
context "Discussion Topic" do
it "should use correct date for its submitted_at value" do
course_with_student_logged_in(:active_all => true)