135 lines
3.4 KiB
Ruby
135 lines
3.4 KiB
Ruby
module Travis::API::V3
|
|
class Service
|
|
DEFAULT_PARAMS = [ "include".freeze, "@type".freeze ]
|
|
private_constant :DEFAULT_PARAMS
|
|
|
|
def self.result_type(type = nil)
|
|
@result_type = type if type
|
|
@result_type ||= parent.result_type if parent and parent.respond_to? :result_type
|
|
raise 'result type not set' unless defined? @result_type
|
|
@result_type
|
|
end
|
|
|
|
def self.filter_params(params)
|
|
wanted = self.params
|
|
params.select { |key| wanted.include? key }
|
|
end
|
|
|
|
def self.params(*list, prefix: nil)
|
|
@params ||= superclass.respond_to?(:params) ? superclass.params.dup : DEFAULT_PARAMS
|
|
list.each do |entry|
|
|
@params << entry.to_s
|
|
@params << "#{prefix || result_type}.#{entry}" if entry.is_a? Symbol
|
|
end
|
|
@params
|
|
end
|
|
|
|
def self.paginate(**options)
|
|
params("limit".freeze, "offset".freeze)
|
|
params("sort_by".freeze) if query_factory.sortable?
|
|
@paginator = Paginator.new(**options)
|
|
end
|
|
|
|
def self.paginator
|
|
@paginator ||= nil
|
|
end
|
|
|
|
def self.paginate?
|
|
!!@paginator if defined? @paginator
|
|
end
|
|
|
|
def self.query_factory
|
|
Queries[result_type]
|
|
end
|
|
|
|
attr_accessor :access_control, :params, :request_body
|
|
|
|
def initialize(access_control, params, request_body)
|
|
@access_control = access_control
|
|
@params = params
|
|
@queries = {}
|
|
@github = {}
|
|
@request_body = request_body
|
|
end
|
|
|
|
def query(type = result_type)
|
|
@queries[type] ||= Queries[type].new(params, result_type, service: self)
|
|
end
|
|
|
|
def github(user = nil)
|
|
@github[user] ||= GitHub.new(user)
|
|
end
|
|
|
|
def find(type = result_type, *args)
|
|
not_found(true, type) unless object = query(type).find(*args)
|
|
not_found(false, type) unless access_control.visible? object
|
|
object
|
|
end
|
|
|
|
def check_login_and_find(*args)
|
|
raise LoginRequired unless access_control.full_access_or_logged_in?
|
|
find(*args) or raise NotFound
|
|
end
|
|
|
|
def not_found(actually_not_found = false, type = nil)
|
|
type, actually_not_found = actually_not_found, false if actually_not_found.is_a? Symbol
|
|
error = actually_not_found ? EntityMissing : NotFound
|
|
raise(error, type || result_type)
|
|
end
|
|
|
|
def run!
|
|
not_implemented
|
|
end
|
|
|
|
def result_type
|
|
self.class.result_type
|
|
end
|
|
|
|
def result(*args)
|
|
Result.new(access_control, *args)
|
|
end
|
|
|
|
def run
|
|
not_found unless result = run!
|
|
result = result(result_type, result) unless result.is_a? Result
|
|
result = paginate(result) if self.class.paginate?
|
|
apply_warnings(result)
|
|
result
|
|
end
|
|
|
|
def warnings
|
|
@warnings ||= []
|
|
end
|
|
|
|
def warn(*args)
|
|
warnings << args
|
|
end
|
|
|
|
def apply_warnings(result)
|
|
warnings.each { |args| result.warn(*args) }
|
|
end
|
|
|
|
def paginate(result)
|
|
self.class.paginator.paginate(result,
|
|
limit: params['limit'.freeze],
|
|
offset: params['offset'.freeze],
|
|
access_control: access_control)
|
|
end
|
|
|
|
def params_for?(prefix)
|
|
return true if params['@type'.freeze] == prefix
|
|
return true if params[prefix].is_a? Hash
|
|
params.keys.any? { |key| key.start_with? "#{prefix}." }
|
|
end
|
|
|
|
def accepted(**payload)
|
|
payload[:resource_type] ||= result_type
|
|
result(:accepted, payload, status: 202)
|
|
end
|
|
|
|
def not_implemented
|
|
raise NotImplemented
|
|
end
|
|
end
|
|
end
|