refactor to responders, add the cc.xml stuff
This commit is contained in:
parent
5a6f34005c
commit
f6957636fb
lib/travis/api/app
endpoint.rb
endpoint
accounts.rbartifacts.rbbranches.rbbuilds.rbhooks.rbjobs.rbrepositories.rbresult_image.rbusers.rbworkers.rb
helpers
responder.rbspec
|
@ -11,7 +11,9 @@ class Travis::Api::App
|
|||
register :scoping
|
||||
helpers :current_user
|
||||
|
||||
# TODO hmmm?
|
||||
before { content_type :json }
|
||||
|
||||
error(ActiveRecord::RecordNotFound, Sinatra::NotFound) { not_found }
|
||||
not_found { content_type =~ /json/ ? { 'file' => 'not found' } : 'file not found' }
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ class Travis::Api::App
|
|||
class Endpoint
|
||||
class Accounts < Endpoint
|
||||
get '/', scope: :private do
|
||||
body all(params).run, type: :accounts
|
||||
respond_with all(params).run, type: :accounts
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@ class Travis::Api::App
|
|||
class Artifacts < Endpoint
|
||||
# Fetches an artifact by it's *id*.
|
||||
get '/:id' do |id|
|
||||
body one(params).run
|
||||
respond_with one(params).run
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,7 +4,7 @@ class Travis::Api::App
|
|||
class Endpoint
|
||||
class Branches < Endpoint
|
||||
get '/' do
|
||||
body all(params).run, type: :branches
|
||||
respond_with all(params).run, type: :branches
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,11 +4,11 @@ class Travis::Api::App
|
|||
class Endpoint
|
||||
class Builds < Endpoint
|
||||
get '/' do
|
||||
body all(params).run
|
||||
respond_with all(params).run
|
||||
end
|
||||
|
||||
get '/:id' do
|
||||
body one(params).run
|
||||
respond_with one(params).run
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,7 +4,7 @@ class Travis::Api::App
|
|||
class Endpoint
|
||||
class Hooks < Endpoint
|
||||
get '/', scope: :private do
|
||||
body all(params).run, type: :hooks
|
||||
respond_with all(params).run, type: :hooks
|
||||
end
|
||||
|
||||
put '/:id?', scope: :private do
|
||||
|
|
|
@ -4,11 +4,11 @@ class Travis::Api::App
|
|||
class Endpoint
|
||||
class Jobs < Endpoint
|
||||
get '/' do
|
||||
body all(params).run
|
||||
respond_with all(params).run
|
||||
end
|
||||
|
||||
get '/:id' do
|
||||
body one(params).run
|
||||
respond_with one(params).run
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,12 +4,22 @@ class Travis::Api::App
|
|||
class Endpoint
|
||||
class Repositories < Endpoint
|
||||
get '/' do
|
||||
body all(params).run
|
||||
respond_with all(params).run
|
||||
end
|
||||
|
||||
get '/:id' do
|
||||
body one(params).run
|
||||
respond_with one(params).run
|
||||
end
|
||||
|
||||
# TODO the format constraint neither seems to work nor fail?
|
||||
get '/:id/cc.:format', format: 'xml' do
|
||||
respond_with one(params).run
|
||||
end
|
||||
|
||||
# get '/:owner_name/:name.:format', format: 'png' do
|
||||
# pass unless params.key?('owner_name') && params.key?('name')
|
||||
# result_image service(:repositories, :one, params).run(:raise => false)
|
||||
# end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
require 'travis/api/app'
|
||||
|
||||
class Travis::Api::App
|
||||
class Endpoint
|
||||
class ResultImage < Endpoint
|
||||
# set(:prefix) { '/' }
|
||||
|
||||
# get '/:owner_name/:name.png' do
|
||||
# pass unless params.key?('owner_name') && params.key?('name')
|
||||
# result_image service(:repositories, :one, params).run(:raise => false)
|
||||
# end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -19,7 +19,7 @@ class Travis::Api::App
|
|||
# }
|
||||
# }
|
||||
get '/:id?', scope: :private do
|
||||
body current_user
|
||||
respond_with current_user
|
||||
end
|
||||
|
||||
put '/:id?', scope: :private do
|
||||
|
|
|
@ -4,7 +4,7 @@ class Travis::Api::App
|
|||
class Endpoint
|
||||
class Workers < Endpoint
|
||||
get '/' do
|
||||
body all(params).run
|
||||
respond_with all(params).run
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
require 'travis/api/app'
|
||||
|
||||
class Travis::Api::App
|
||||
module Helpers
|
||||
# Allows routes to return either hashes or anything Travis::API.data can
|
||||
# convert (in addition to the return values supported by Sinatra, of
|
||||
# course). These values will be encoded in JSON.
|
||||
module JsonRenderer
|
||||
ACCEPT_VERSION = /vnd\.travis-ci\.(\d+)\+/
|
||||
DEFAULT_VERSION = 'v1'
|
||||
|
||||
def respond_with(resource, options = {})
|
||||
halt render_json(resource, options)
|
||||
end
|
||||
|
||||
def body(value = nil, options = {}, &block)
|
||||
value = render_json(value, options) if value
|
||||
super(value, &block)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def render_json(resource, options = {})
|
||||
options[:version] ||= api_version
|
||||
options[:params] ||= params
|
||||
|
||||
builder = Travis::Api.builder(resource, options)
|
||||
# builder || raise("could not determine a builder for #{resource}, #{options}")
|
||||
resource = builder.new(resource, options[:params]).data.to_json if builder
|
||||
resource = resource.to_json if resource.is_a? Hash
|
||||
resource
|
||||
end
|
||||
|
||||
def api_version
|
||||
accept = request.env['HTTP_ACCEPT'] || ''
|
||||
accept =~ ACCEPT_VERSION && "v#{$1}" || DEFAULT_VERSION
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
24
lib/travis/api/app/helpers/mime_types.rb
Normal file
24
lib/travis/api/app/helpers/mime_types.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
require 'travis/api/app'
|
||||
|
||||
class Travis::Api::App
|
||||
module Helpers
|
||||
module MimeTypes
|
||||
def html?
|
||||
request.accept =~ %r(text/html)
|
||||
end
|
||||
|
||||
def json?
|
||||
request.accept =~ %r(application/json)
|
||||
end
|
||||
|
||||
def xml?
|
||||
request.accept =~ %r(application/xml)
|
||||
end
|
||||
|
||||
def png?
|
||||
request.accept =~ %r(image/png)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
41
lib/travis/api/app/helpers/respond_with.rb
Normal file
41
lib/travis/api/app/helpers/respond_with.rb
Normal file
|
@ -0,0 +1,41 @@
|
|||
require 'travis/api/app'
|
||||
|
||||
class Travis::Api::App
|
||||
module Helpers
|
||||
module Responders
|
||||
autoload :Base, 'travis/api/app/helpers/responders/base'
|
||||
autoload :Image, 'travis/api/app/helpers/responders/image'
|
||||
autoload :Json, 'travis/api/app/helpers/responders/json'
|
||||
autoload :Xml, 'travis/api/app/helpers/responders/xml'
|
||||
end
|
||||
|
||||
# Allows routes to return either hashes or anything Travis::API.data can
|
||||
# convert (in addition to the return values supported by Sinatra, of
|
||||
# course). These values will be encoded in JSON.
|
||||
module RespondWith
|
||||
def respond_with(resource, options = {})
|
||||
halt responder.new(request, headers, resource, options).render
|
||||
end
|
||||
|
||||
def body(value = nil, options = {}, &block)
|
||||
value = value.to_json if value.is_a?(Hash)
|
||||
super(value, &block)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def responder
|
||||
Responders.const_get(responder_type.to_s.camelize) # or raise shit
|
||||
end
|
||||
|
||||
def responder_type
|
||||
format_from_content_type || params[:format] || 'json'
|
||||
end
|
||||
|
||||
# TODO is there no support for this kind of mime types?
|
||||
def format_from_content_type
|
||||
request.content_type && request.content_type.split(';').first.split('/').last
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
12
lib/travis/api/app/helpers/responders/base.rb
Normal file
12
lib/travis/api/app/helpers/responders/base.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
module Travis::Api::App::Helpers::Responders
|
||||
class Base
|
||||
attr_reader :request, :headers, :resource, :options
|
||||
|
||||
def initialize(request, headers, resource, options = {})
|
||||
@request = request
|
||||
@headers = headers
|
||||
@resource = resource
|
||||
@options = options
|
||||
end
|
||||
end
|
||||
end
|
24
lib/travis/api/app/helpers/responders/image.rb
Normal file
24
lib/travis/api/app/helpers/responders/image.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
module Travis::Api::App::Helpers::Responders
|
||||
class Image < Base
|
||||
NAMES = { nil => 'unknown', 0 => 'passing', 1 => 'failing' }
|
||||
|
||||
def render
|
||||
headers['Expires'] = Time.now.utc.httpdate
|
||||
send_file filename(resource), type: :png, disposition: :inline
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def filename(resource)
|
||||
"#{root}/public/images/result/#{result(resource)}.png"
|
||||
end
|
||||
|
||||
def result(resource)
|
||||
NAMES[resource.try(:last_build_result_on, branch: params[:branch])]
|
||||
end
|
||||
|
||||
def root
|
||||
File.expand_path('.') # TODO wat.
|
||||
end
|
||||
end
|
||||
end
|
21
lib/travis/api/app/helpers/responders/json.rb
Normal file
21
lib/travis/api/app/helpers/responders/json.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
module Travis::Api::App::Helpers::Responders
|
||||
class Json < Base
|
||||
ACCEPT_VERSION = /vnd\.travis-ci\.(\d+)\+/
|
||||
DEFAULT_VERSION = 'v1'
|
||||
|
||||
def render
|
||||
options[:version] ||= version
|
||||
builder = Travis::Api.builder(resource, options) # || raise("could not determine a builder for #{resource}, #{options}")
|
||||
|
||||
resource = builder.new(self.resource, request.params).data if builder
|
||||
resource = resource.to_json unless resource.is_a?(String)
|
||||
resource
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def version
|
||||
request.accept.join =~ ACCEPT_VERSION && "v#{$1}" || DEFAULT_VERSION
|
||||
end
|
||||
end
|
||||
end
|
50
lib/travis/api/app/helpers/responders/xml.rb
Normal file
50
lib/travis/api/app/helpers/responders/xml.rb
Normal file
|
@ -0,0 +1,50 @@
|
|||
module Travis::Api::App::Helpers::Responders
|
||||
class Xml < Base
|
||||
TEMPLATE = File.read(__FILE__).split("__END__").last.strip
|
||||
|
||||
STATUS = {
|
||||
nil => 'Unknown',
|
||||
0 => 'Success',
|
||||
1 => 'Failure'
|
||||
}
|
||||
|
||||
ACTIVITY = {
|
||||
nil => 'Sleeping',
|
||||
'started' => 'Building',
|
||||
'finished' => 'Sleeping'
|
||||
}
|
||||
|
||||
def render
|
||||
TEMPLATE % data
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def data
|
||||
{
|
||||
name: resource.slug,
|
||||
url: [Travis.config.domain, resource.slug].join('/'),
|
||||
activity: ACTIVITY[last_build.try(:state)],
|
||||
label: last_build.try(:number),
|
||||
status: STATUS[resource.last_build_result_on(request.params)],
|
||||
time: last_build.finished_at.try(:strftime, '%Y-%m-%dT%H:%M:%S.%L%z')
|
||||
}
|
||||
end
|
||||
|
||||
def last_build
|
||||
@last_build ||= resource.last_build
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
__END__
|
||||
|
||||
<Projects>
|
||||
<Project
|
||||
name="%{name}"
|
||||
activity="%{activity}"
|
||||
lastBuildStatus="%{status}"
|
||||
lastBuildLabel="%{label}"
|
||||
lastBuildTime="%{time}"
|
||||
webUrl="%{url}" />
|
||||
</Projects>
|
|
@ -1,27 +0,0 @@
|
|||
require 'travis/api/app'
|
||||
require 'cgi'
|
||||
|
||||
module Travis::Api::App::Helpers
|
||||
module ResultImage
|
||||
RESULT_NAMES = { nil => 'unknown', 0 => 'passing', 1 => 'failing' }
|
||||
|
||||
def result_image(resource)
|
||||
headers['Expires'] = CGI.rfc1123_date(Time.now.utc)
|
||||
filename = filename(resource)
|
||||
env['travis.sending-file'] = filename
|
||||
send_file filename, type: :png, disposition: :inline
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def filename(resource)
|
||||
root = File.expand_path("#{settings.root}/../../../../../") # TODO wat.
|
||||
"#{root}/public/images/result/#{result(resource)}.png"
|
||||
end
|
||||
|
||||
def result(resource)
|
||||
RESULT_NAMES[resource.try(:last_build_result_on, branch: params[:branch])]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -23,7 +23,7 @@ class Travis::Api::App
|
|||
enable :raise_errors
|
||||
# disable :dump_errors
|
||||
register :subclass_tracker
|
||||
helpers :json_renderer, :result_image
|
||||
helpers :respond_with, :mime_types
|
||||
end
|
||||
|
||||
configure :development do
|
||||
|
|
|
@ -9,7 +9,7 @@ describe 'Builds' do
|
|||
|
||||
it 'GET /builds?repository_id=1' do
|
||||
response = get '/builds', { repository_id: repo.id }, headers
|
||||
response.should deliver_json_for(repo.builds.was_started, version: 'v1')
|
||||
response.should deliver_json_for(repo.builds.was_started.order('id DESC'), version: 'v1')
|
||||
end
|
||||
|
||||
it 'GET /builds/1' do
|
||||
|
|
|
@ -7,8 +7,8 @@ describe Travis::Api::App::Extensions::SmartConstants do
|
|||
|
||||
describe :helpers do
|
||||
it 'works' do # :)
|
||||
some_app.helpers :json_renderer
|
||||
some_app.ancestors.should include(Travis::Api::App::Helpers::JsonRenderer)
|
||||
some_app.helpers :respond_with
|
||||
some_app.ancestors.should include(Travis::Api::App::Helpers::RespondWith)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
require 'spec_helper'
|
||||
require 'json'
|
||||
|
||||
describe Travis::Api::App::Helpers::JsonRenderer do
|
||||
before do
|
||||
mock_app do
|
||||
helpers Travis::Api::App::Helpers::JsonRenderer
|
||||
get('/') { {'foo' => 'bar'} }
|
||||
end
|
||||
end
|
||||
|
||||
it 'renders body as json' do
|
||||
get('/').should be_ok
|
||||
JSON.load(body).should == {'foo' => 'bar'}
|
||||
end
|
||||
end
|
||||
# describe Travis::Api::App::Helpers::JsonRenderer do
|
||||
# before do
|
||||
# mock_app do
|
||||
# helpers Travis::Api::App::Helpers::JsonRenderer
|
||||
# get('/') { {'foo' => 'bar'} }
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# it 'renders body as json' do
|
||||
# get('/').should be_ok
|
||||
# JSON.load(body).should == {'foo' => 'bar'}
|
||||
# end
|
||||
# end
|
||||
|
|
Loading…
Reference in New Issue
Block a user