app/controllers/api/jobs_controller.rb
# = Jobs controller
#
# == States
# A job can be in one of the following states:
#
# <tt>scheduled</tt>:: Scheduled to be sent to the Transcoder instances
# <tt>processing</tt>:: Being processed by a Transcoder Instance
# <tt>\on_hold</tt>:: Waiting for a Transcoder to become responsive again
# <tt>success</tt>:: Successfully completed
# <tt>failed</tt>:: An error occurred
#
# == Pagination
# For methods that use pagination, a <tt>page</tt> parameters can be sent to display that particular page of jobs.
# Jobs are paginated with 25 jobs per page.
# For example, to get the 5th page of successfully completed jobs, use:
# http://host.com/api/jobs/completed?page=5
module Api
class JobsController < ApiController
respond_to :rss, only: [:index, :scheduled, :processing, :on_hold, :success, :failed]
# == Returns a list of jobs regardless of state.
# This method uses pagination.
def index
jobs_index(Job.all)
end
# == Returns a list of scheduled jobs
# Scheduled jobs are created, but not yet accepted by the transcoders.
# This method uses pagination.
def scheduled
jobs_index(Job.scheduled)
end
# == Returns a list of jobs being processed.
# Jobs being processed are being transcoded by a \Transcoder.
# This method uses pagination.
def processing
jobs_index(Job.processing)
end
# == Returns a list of jobs that are on hold
# Jobs will be put on hold when a \Transcoder instance is unavailable.
# This method uses pagination.
def on_hold
jobs_index(Job.on_hold)
end
# == Returns a list of successfully completed jobs
# These jobs have been successfully transcoded.
# This method uses pagination.
def success
jobs_index(Job.success)
end
alias_method :completed, :success
# == Returns a list of failed jobs
# Jobs become failed if the \Transcoder reports an error.
# This method uses pagination.
def failed
jobs_index(Job.failed)
end
# == Creates a job
#
# Creates a job using the specified parameters, which are all required. If the request was valid,
# the created job is returned. If the request could not be completed, a list of errors will be returned.
#
# If the job is successfully created, two extra headers will be sent in the response.
# The header <tt>X-State-Changes-Location</tt> contains the location of the state changes endpoint for this job.
# The header <tt>X-Notifications-Location</tt> contains the location of the notifications endpoint for this job.
#
# === Parameters
# <tt>input</tt>, <tt>output</tt> and <tt>preset</tt> are required parameters, <tt>notify</tt> is optional.
# <tt>input</tt>:: Input file to process
# <tt>output</tt>:: Output file to write to
# <tt>preset</tt>:: Preset name to use
# <tt>priority</tt>:: Priority as integer (default nil, maximum 999)
# <tt>notify</tt>:: A list of email addresses and urls separated by commas.
#
# If a job enters the completed or failed state, a notification will be sent to the emails and urls specified in the
# <tt>notify</tt> parameter. Urls will receive a POST request with the JSON representation of the job as body.
#
# === Response codes
# <tt>success</tt>:: <tt>201 created</tt>
# <tt>failed</tt>:: <tt>406 Unprocessable Entity</tt>
#
# === Example
# $ curl -d 'input=/tmp/foo.flv&output=/tmp/bar.mp4&preset=h264' http://localhost:3000/api/jobs
#
# {
# "job": {
# "completed_at":null,
# "created_at":"2011-05-10T08:25:00Z",
# "destination_file":"/tmp/bar.mp4",
# "duration":null,
# "filesize":null,
# "host_id":1,
# "id":26,
# "message":null,
# "preset_id":1,
# "priority":null,
# "progress":null,
# "remote_job_id":"fa832776a64b6844fb9f1a244757734a9d83c00f",
# "source_file":"/tmp/foo.flv",
# "state":"scheduled",
# "transcoding_started_at":"2011-05-10T08:25:03Z",
# "updated_at":"2011-05-10T08:25:03Z"
# }
# }
def create
job = Job.from_api(params)
if job.valid?
response.headers['X-State-Changes-Location'] = api_state_changes_url(job)
response.headers['X-Notifications-Location'] = api_notifications_url(job)
respond_with job, location: api_job_url(job) do |format|
format.html { redirect_to jobs_path }
end
else
respond_with job do |format|
format.html do
@job = job
render '/jobs/new'
end
end
end
end
# == Updates a job with attributes from the transcoder
#
# This endpoint is specifically for updating a job from the transcoder and should not be called manually.
def update #:nodoc:
job = Job.find(params[:id])
job.enter(params[:status], params, request.headers)
respond_with job, location: api_job_url(job)
end
# == Shows a job
#
# The displayed job will have its status updated to provide an up-to-date view of attributes.
#
# === Parameters
# <tt>id</tt>:: The id of the job to show
#
# === Example
# {
# "job": {
# "completed_at":null,
# "created_at":"2011-05-10T08:25:00Z",
# "destination_file":"/tmp/bar.mp4",
# "duration":null,
# "filesize":null,
# "host_id":1,
# "id":26,
# "message":null,
# "preset_id":1,
# "progress":null,
# "remote_job_id":"fa832776a64b6844fb9f1a244757734a9d83c00f",
# "source_file":"/tmp/foo.flv",
# "state":"scheduled",
# "transcoding_started_at":"2011-05-10T08:25:03Z",
# "updated_at":"2011-05-10T08:25:03Z"
# }
# }
def show
job = Job.find(params[:id])
respond_with job
end
# == Purges failed jobs
#
# This method will permanently delete all failed jobs from the database.
#
# $ curl -XDELETE http://localhost:3000/api/jobs/purge
# {} # HTTP Status: 200 OK
def purge
Job.failed.destroy_all
render nothing: true
end
# == Retries a job
#
# This method will force a job into the Scheduled state, regardless of which state it's currently in.
#
# === Parameters
# <tt>id</tt>:: The id of the job to retry
def retry
job = Job.find(params[:id])
job.enter(Job::Scheduled)
respond_with job do |format|
format.html { redirect_to jobs_path }
end
end
# == Deletes a job
#
# Removes a job from the database, regardless of state
#
# == Parameters
# <tt>id</tt>:: The id of the job to destroy
def destroy
job = Job.find(params[:id])
job.destroy
respond_with job do |format|
format.html { redirect_to jobs_path }
end
end
private #:nodoc:
def jobs_index(jobs)
jobs = jobs.order('created_at DESC').page(params[:page])
respond_with jobs
end
end
end