Initial commit
This commit is contained in:
11
app/controllers/api/acquired_media_releases_controller.rb
Normal file
11
app/controllers/api/acquired_media_releases_controller.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class Api::AcquiredMediaReleasesController < Api::ReleasesController
|
||||
deserializable_resource :acquired_media_release, only: [:create, :update]
|
||||
|
||||
def model_name
|
||||
"acquired_media_release"
|
||||
end
|
||||
|
||||
def attributes_for_index
|
||||
[:name]
|
||||
end
|
||||
end
|
||||
48
app/controllers/api/api_controller.rb
Normal file
48
app/controllers/api/api_controller.rb
Normal file
@@ -0,0 +1,48 @@
|
||||
class Api::ApiController < ActionController::Base
|
||||
skip_before_action :verify_authenticity_token
|
||||
include Knock::Authenticable
|
||||
include Pundit
|
||||
|
||||
rescue_from Exception, :with => :return_error
|
||||
before_action :authenticate_user
|
||||
before_action do
|
||||
Current.user = current_user if current_user.present?
|
||||
end
|
||||
|
||||
def pundit_user
|
||||
UserContext.new(Current.user, Current.account)
|
||||
end
|
||||
|
||||
# Catch exception and return JSON-formatted error
|
||||
def return_error(exception)
|
||||
raise exception if Rails.env.test?
|
||||
|
||||
logger.error "==Handled======="
|
||||
logger.error exception.message
|
||||
logger.error exception.backtrace.join("\n")
|
||||
logger.error "==Handled======="
|
||||
case exception.class
|
||||
when ActiveRecord::RecordNotFound
|
||||
@status = 404
|
||||
@message = 'Record not found'
|
||||
when ActiveRecord::RecordInvalid
|
||||
@status = 422
|
||||
@message = 'Record invalid'
|
||||
when ArgumentError
|
||||
@status = 400
|
||||
@message = 'Argument Error'
|
||||
else
|
||||
@status = 500
|
||||
@message = 'Internal Error'
|
||||
end
|
||||
|
||||
# for some reason render json_errors is not working
|
||||
# simulating JSON API support
|
||||
render json: {
|
||||
errors: [{
|
||||
status: @status.to_s,
|
||||
title: @message
|
||||
}]
|
||||
}
|
||||
end
|
||||
end
|
||||
23
app/controllers/api/appearance_releases_controller.rb
Normal file
23
app/controllers/api/appearance_releases_controller.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
class Api::AppearanceReleasesController < Api::ReleasesController
|
||||
deserializable_resource :appearance_release, only: [:create]
|
||||
|
||||
def model_name
|
||||
"appearance_release"
|
||||
end
|
||||
|
||||
def attributes_for_index
|
||||
[:person_name]
|
||||
end
|
||||
|
||||
def handle_attachments(release, _)
|
||||
photo = release_create_params[:person_photo]
|
||||
photo[:io] = StringIO.new(Base64.decode64(photo[:io]))
|
||||
release.person_photo.attach(io: photo[:io], filename: photo[:filename])
|
||||
|
||||
guardian_photo = release_create_params[:guardian_photo]
|
||||
if guardian_photo
|
||||
guardian_photo[:io] = StringIO.new(Base64.decode64(guardian_photo[:io]))
|
||||
release.guardian_photo.attach(io: guardian_photo[:io], filename: guardian_photo[:filename])
|
||||
end
|
||||
end
|
||||
end
|
||||
55
app/controllers/api/broadcasts_controller.rb
Normal file
55
app/controllers/api/broadcasts_controller.rb
Normal file
@@ -0,0 +1,55 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::BroadcastsController < Api::ApiController
|
||||
deserializable_resource :broadcast, only: [:update]
|
||||
|
||||
include ProjectContext
|
||||
|
||||
before_action :set_project
|
||||
before_action :set_broadcast, only: [:show, :update]
|
||||
|
||||
def index
|
||||
render jsonapi: broadcasts, class: { Broadcast: SerializableBroadcast }
|
||||
end
|
||||
|
||||
def show
|
||||
render jsonapi:
|
||||
@broadcast,
|
||||
class: {
|
||||
Broadcast: SerializableBroadcast,
|
||||
"ActiveStorage::Attachment".to_sym => ActiveStorage::SerializableAttachment
|
||||
},
|
||||
include: [:files]
|
||||
end
|
||||
|
||||
def update
|
||||
file_params.each do |file|
|
||||
file[:io] = StringIO.new(Base64.decode64(file[:io]))
|
||||
@broadcast.files.attach(io: file[:io], filename: file[:filename])
|
||||
end
|
||||
@broadcast.save!
|
||||
|
||||
render jsonapi:
|
||||
@broadcast,
|
||||
class: {
|
||||
Broadcast: SerializableBroadcast,
|
||||
"ActiveStorage::Attachment".to_sym => ActiveStorage::SerializableAttachment
|
||||
},
|
||||
include: [:files]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def file_params
|
||||
broadcast_params = params.require(:broadcast).permit!
|
||||
broadcast_params[:files]
|
||||
end
|
||||
|
||||
def broadcasts
|
||||
policy_scope(@project.broadcasts.where(status: %w[created idle]))
|
||||
end
|
||||
|
||||
def set_broadcast
|
||||
@broadcast = authorize policy_scope(@project.broadcasts).find(params[:id])
|
||||
end
|
||||
end
|
||||
63
app/controllers/api/contract_templates_controller.rb
Normal file
63
app/controllers/api/contract_templates_controller.rb
Normal file
@@ -0,0 +1,63 @@
|
||||
class Api::ContractTemplatesController < Api::ApiController
|
||||
include ProjectContext
|
||||
|
||||
before_action :set_project, only: [:index]
|
||||
before_action :set_contract_template, only: [:show]
|
||||
|
||||
def index
|
||||
render jsonapi: contract_templates, class: { "ContractTemplate": index_serializable }
|
||||
end
|
||||
|
||||
def show
|
||||
handle_response(@contract_template)
|
||||
end
|
||||
|
||||
def handle_response(contract_template, status = :ok)
|
||||
mapping = {
|
||||
"ContractTemplate": show_serializable,
|
||||
"ActiveStorage::Attachment".to_sym => ActiveStorage::SerializableAttachment,
|
||||
}
|
||||
|
||||
render jsonapi: contract_template,
|
||||
status: status,
|
||||
class: mapping
|
||||
end
|
||||
|
||||
def attributes_for_index
|
||||
[:name]
|
||||
end
|
||||
|
||||
def index_serializable
|
||||
name = "contract_template"
|
||||
attributes_to_send = attributes_for_index
|
||||
Class.new(JSONAPI::Serializable::Resource) do
|
||||
type name
|
||||
|
||||
attributes_to_send.each do |attr|
|
||||
attribute attr.to_sym
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def show_serializable
|
||||
name = "contract_template"
|
||||
Class.new(JSONAPI::Serializable::Resource) do
|
||||
type name
|
||||
|
||||
ContractTemplate.new.attributes.keys.each do |attr|
|
||||
attribute attr.to_sym
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def contract_templates
|
||||
date = Date.parse(params.fetch(:updated_since, Date.new.to_s))
|
||||
policy_scope(ContractTemplate.where(project_id: @project.id, updated_at: date..Float::INFINITY))
|
||||
end
|
||||
|
||||
def set_contract_template
|
||||
@contract_template = ContractTemplate.find(params[:id])
|
||||
end
|
||||
end
|
||||
11
app/controllers/api/location_releases_controller.rb
Normal file
11
app/controllers/api/location_releases_controller.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class Api::LocationReleasesController < Api::ReleasesController
|
||||
deserializable_resource :location_release, only: [:create, :update]
|
||||
|
||||
def model_name
|
||||
"location_release"
|
||||
end
|
||||
|
||||
def attributes_for_index
|
||||
[:name]
|
||||
end
|
||||
end
|
||||
11
app/controllers/api/material_releases_controller.rb
Normal file
11
app/controllers/api/material_releases_controller.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class Api::MaterialReleasesController < Api::ReleasesController
|
||||
deserializable_resource :material_release, only: [:create, :update]
|
||||
|
||||
def model_name
|
||||
"material_release"
|
||||
end
|
||||
|
||||
def attributes_for_index
|
||||
[:name]
|
||||
end
|
||||
end
|
||||
35
app/controllers/api/notes_controller.rb
Normal file
35
app/controllers/api/notes_controller.rb
Normal file
@@ -0,0 +1,35 @@
|
||||
class Api::NotesController < Api::ApiController
|
||||
before_action :set_release
|
||||
deserializable_resource :note, only: [:create]
|
||||
|
||||
def index
|
||||
render jsonapi: @release.notes, class: { Note: SerializableNote }
|
||||
end
|
||||
|
||||
def create
|
||||
note = @release.notes.new(note_create_params)
|
||||
note.user_id = current_user.id
|
||||
note.email = current_user.email
|
||||
note.save!
|
||||
render jsonapi: note, class: { Note: SerializableNote }, status: :created
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def model_name
|
||||
request.path.match(/(\w+_releases)/).captures.first.singularize
|
||||
end
|
||||
|
||||
def model_constant
|
||||
model_name.camelize.constantize
|
||||
end
|
||||
|
||||
def set_release
|
||||
@release = authorize model_constant.find(params["#{model_name}_id"])
|
||||
end
|
||||
|
||||
def note_create_params
|
||||
parameters = params.require(:note).permit!
|
||||
parameters.slice(:content)
|
||||
end
|
||||
end
|
||||
5
app/controllers/api/profiles_controller.rb
Normal file
5
app/controllers/api/profiles_controller.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class Api::ProfilesController < Api::ApiController
|
||||
def show
|
||||
render jsonapi: current_user
|
||||
end
|
||||
end
|
||||
6
app/controllers/api/projects_controller.rb
Normal file
6
app/controllers/api/projects_controller.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class Api::ProjectsController < Api::ApiController
|
||||
def index
|
||||
projects = Current.user.accessible_projects_for(Current.account)
|
||||
render jsonapi: projects
|
||||
end
|
||||
end
|
||||
182
app/controllers/api/releases_controller.rb
Normal file
182
app/controllers/api/releases_controller.rb
Normal file
@@ -0,0 +1,182 @@
|
||||
class Api::ReleasesController < Api::ApiController
|
||||
include ProjectContext
|
||||
include CreateReleasableJobs
|
||||
|
||||
before_action :set_project, only: [:index]
|
||||
before_action :set_release, only: [:show, :update]
|
||||
before_action :set_template_and_project, only: [:create]
|
||||
|
||||
def index
|
||||
render jsonapi: releases, class: { "#{model_name.camelize}": index_serializable }
|
||||
end
|
||||
|
||||
def show
|
||||
handle_response(@release)
|
||||
end
|
||||
|
||||
def create
|
||||
params_without_photo = release_create_params.except(:photos, :person_photo)
|
||||
release = filtered_releases.new(params_without_photo)
|
||||
release.project_id = @project.id
|
||||
release.contract_template_id = @contract_template.id
|
||||
handle_attachments(release, release_create_params[:photos])
|
||||
release.save!(context: :native)
|
||||
log_create_analytics
|
||||
after_create(release)
|
||||
handle_response(release, :created)
|
||||
end
|
||||
|
||||
def update
|
||||
if model_name == "acquired_media_release"
|
||||
authorize @release, :update_file_infos?
|
||||
|
||||
@release.attributes = release_create_params
|
||||
@release.save!
|
||||
else
|
||||
authorize @release, :update_photos?
|
||||
|
||||
handle_attachments(@release, release_create_params[:photos])
|
||||
@release.save!
|
||||
end
|
||||
|
||||
handle_response(@release)
|
||||
end
|
||||
|
||||
def handle_response(release, status = :ok)
|
||||
if model_name == "acquired_media_release"
|
||||
mapping = {
|
||||
"#{model_name.camelize}": SerializableAcquiredMediaRelease,
|
||||
FileInfo: SerializableFileInfo
|
||||
}
|
||||
|
||||
render jsonapi: release,
|
||||
status: status,
|
||||
class: mapping,
|
||||
include: [:file_infos]
|
||||
else
|
||||
mapping = {
|
||||
"#{model_name.camelize}": show_serializable,
|
||||
"ActiveStorage::Attachment".to_sym => ActiveStorage::SerializableAttachment,
|
||||
}
|
||||
|
||||
render jsonapi: release,
|
||||
status: status,
|
||||
class: mapping,
|
||||
include: [:photos, :guardian_photos]
|
||||
end
|
||||
end
|
||||
|
||||
def model_name
|
||||
raise "Please specify model name underscored and lowercase e.g. appearance_release"
|
||||
end
|
||||
|
||||
def model_constant
|
||||
model_name.camelize.constantize
|
||||
end
|
||||
|
||||
def attributes_for_index
|
||||
raise "Please specify attributes for index"
|
||||
end
|
||||
|
||||
def index_serializable
|
||||
name = model_name
|
||||
attributes_to_send = attributes_for_index
|
||||
Class.new(JSONAPI::Serializable::Resource) do
|
||||
type name
|
||||
|
||||
attributes_to_send.each do |attr|
|
||||
attribute attr.to_sym
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def show_serializable
|
||||
name = model_name
|
||||
constant = model_constant
|
||||
Class.new(JSONAPI::Serializable::Resource) do
|
||||
type name
|
||||
|
||||
constant.new.attributes.keys.each do |attr|
|
||||
attribute attr.to_sym
|
||||
end
|
||||
|
||||
if ["appearance_release", "talent_release"].include?(name)
|
||||
has_many :guardian_photos do
|
||||
data do
|
||||
[@object.guardian_photo.try(:attachment)].compact
|
||||
end
|
||||
meta do
|
||||
{ count: @object.try(:guardian_photo).try(:attached?) ? 1 : 0 }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless name == "acquired_media_release"
|
||||
has_many :photos do
|
||||
if name == "appearance_release"
|
||||
data do
|
||||
[@object.photo.attachment]
|
||||
end
|
||||
end
|
||||
meta do
|
||||
{ count: @object.photos.size }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def create_deserializable
|
||||
constant = model_constant
|
||||
Class.new(JSONAPI::Deserializable::Resource) do
|
||||
constant.new.attributes.keys.except(:created_at, :updated_at, :id, :user_id).each do |attr|
|
||||
attribute attr.to_sym
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def handle_attachments(release, params_photos)
|
||||
photos = params_photos || []
|
||||
photos.each do |photo|
|
||||
photo[:io] = StringIO.new(Base64.decode64(photo[:io]))
|
||||
release.photos.attach(io: photo[:io], filename: photo[:filename])
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def releases
|
||||
date = Date.parse(params.fetch(:updated_since, Date.new.to_s))
|
||||
table = model_constant.table_name
|
||||
policy_scope(model_constant.where(["#{table}.project_id = ? and #{table}.updated_at >= ?", @project.id, date]))
|
||||
end
|
||||
|
||||
def set_release
|
||||
@release = model_constant.find(params[:id])
|
||||
end
|
||||
|
||||
def set_template_and_project
|
||||
@contract_template = ContractTemplate.find(params[:contract_template_id])
|
||||
@project = @contract_template.project
|
||||
end
|
||||
|
||||
def filtered_releases
|
||||
if @project.present?
|
||||
policy_scope(@project.public_send(model_name.pluralize))
|
||||
else
|
||||
releases
|
||||
end
|
||||
end
|
||||
|
||||
def release_create_params
|
||||
parameters = params.require(model_name).permit!
|
||||
keys = model_constant.new.attributes.keys + [:guardian_photo, :person_photo, :photos, :signature, :signature_base64, :file_infos_attributes]
|
||||
parameters[:signature_base64] = parameters[:signature]
|
||||
parameters = parameters.slice(*keys).except(:created_at, :updated_at, :id, :user_id, :signature)
|
||||
parameters
|
||||
end
|
||||
|
||||
def log_create_analytics
|
||||
TrackAnalyticsJob.perform_later(Current.user, Current.account, :track_create_native_release, release_type: model_constant.to_s, account: @account, user_agent: request.user_agent, user_ip: request.remote_ip, application: :ios)
|
||||
end
|
||||
end
|
||||
78
app/controllers/api/sync_controller.rb
Normal file
78
app/controllers/api/sync_controller.rb
Normal file
@@ -0,0 +1,78 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::SyncController < Api::ApiController
|
||||
def index
|
||||
accessible_projects = current_user.accessible_projects_for(Current.account)
|
||||
@accounts = filter(current_user.accounts)
|
||||
@projects = filter(Project).all
|
||||
@contract_templates = filter(ContractTemplate.where(project: accessible_projects)).all
|
||||
@acquired_media_releases = (AcquiredMediaRelease.where(project: accessible_projects))
|
||||
@appearance_releases = (AppearanceRelease.where(project: accessible_projects))
|
||||
@location_releases = (LocationRelease.where(project: accessible_projects))
|
||||
@material_releases = (MaterialRelease.where(project: accessible_projects))
|
||||
@talent_releases = (TalentRelease.where(project: accessible_projects))
|
||||
@notes = notes_query(Note.where(notable: @appearance_releases + @location_releases + @material_releases + @talent_releases + @acquired_media_releases ))
|
||||
|
||||
render json: {
|
||||
data: {
|
||||
accounts: @accounts,
|
||||
projects: @projects,
|
||||
contract_templates: @contract_templates,
|
||||
acquired_media_releases: releases_query(@acquired_media_releases),
|
||||
appearance_releases: releases_query(@appearance_releases),
|
||||
location_releases: releases_query(@location_releases),
|
||||
material_releases: releases_query(@material_releases),
|
||||
talent_releases: releases_query(@talent_releases),
|
||||
notes: @notes
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def releases_query(release)
|
||||
filter(release).all.map { |release| release_json(release) }
|
||||
end
|
||||
|
||||
def notes_query(notes)
|
||||
filter(notes).all.map do |note|
|
||||
json = note.as_json
|
||||
json[:attributes][:email] = note.email
|
||||
json
|
||||
end
|
||||
end
|
||||
|
||||
def release_json(release)
|
||||
json = release.as_json
|
||||
|
||||
unless release.model_name.to_s == "AcquiredMediaRelease"
|
||||
json[:attributes][:photos] = release.photos.map do |photo|
|
||||
build_photo_object photo
|
||||
end
|
||||
end
|
||||
|
||||
if release.respond_to?(:guardian_photo)
|
||||
photo = release.guardian_photo
|
||||
json[:attributes][:guardian_photo] = photo.attached? ? build_photo_object(photo) : nil
|
||||
end
|
||||
|
||||
json
|
||||
end
|
||||
|
||||
def filter(relation)
|
||||
policy_scope(relation)
|
||||
end
|
||||
|
||||
def build_photo_object(photo)
|
||||
{
|
||||
id: photo.id.to_s,
|
||||
type: 'active_storage_attachment',
|
||||
attributes: {
|
||||
filename: photo.filename.to_s,
|
||||
content_type: photo.content_type,
|
||||
url: Rails.application.routes.url_helpers.rails_blob_url(photo, host: AppHost.new.domain_with_port),
|
||||
thumbnail_url: Rails.application.routes.url_helpers.rails_representation_url(photo.variant(resize: '150x150'), host: AppHost.new.domain_with_port)
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
21
app/controllers/api/talent_releases_controller.rb
Normal file
21
app/controllers/api/talent_releases_controller.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
class Api::TalentReleasesController < Api::ReleasesController
|
||||
deserializable_resource :talent_release, only: [:create, :update]
|
||||
|
||||
def model_name
|
||||
"talent_release"
|
||||
end
|
||||
|
||||
def attributes_for_index
|
||||
[:person_name]
|
||||
end
|
||||
|
||||
def handle_attachments(release, _)
|
||||
super
|
||||
|
||||
guardian_photo = release_create_params[:guardian_photo]
|
||||
if guardian_photo
|
||||
guardian_photo[:io] = StringIO.new(Base64.decode64(guardian_photo[:io]))
|
||||
release.guardian_photo.attach(io: guardian_photo[:io], filename: guardian_photo[:filename])
|
||||
end
|
||||
end
|
||||
end
|
||||
36
app/controllers/api/user_token_controller.rb
Normal file
36
app/controllers/api/user_token_controller.rb
Normal file
@@ -0,0 +1,36 @@
|
||||
class Api::UserTokenController < Knock::AuthTokenController
|
||||
skip_before_action :verify_authenticity_token
|
||||
|
||||
rescue_from Exception, :with => :return_error
|
||||
|
||||
# Catch exception and return JSON-formatted error
|
||||
def return_error(exception)
|
||||
logger.error "==Handled======="
|
||||
logger.error exception.message
|
||||
logger.error exception.backtrace.join("\n")
|
||||
logger.error "==Handled======="
|
||||
case exception
|
||||
when ActiveRecord::RecordNotFound
|
||||
@status = 404
|
||||
@message = 'Record not found'
|
||||
when ActiveRecord::RecordInvalid
|
||||
@status = 422
|
||||
@message = 'Record invalid'
|
||||
when ArgumentError
|
||||
@status = 400
|
||||
@message = 'Argument Error'
|
||||
else
|
||||
@status = 500
|
||||
@message = 'Internal Error'
|
||||
end
|
||||
|
||||
# for some reason render json_errors is not working
|
||||
# simulating JSON API support
|
||||
render json: {
|
||||
errors: [{
|
||||
status: @status.to_s,
|
||||
title: @message
|
||||
}]
|
||||
}
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user