refactor to responders, add the cc.xml stuff
This commit is contained in:
parent
5a6f34005c
commit
f6957636fb
|
@ -11,7 +11,9 @@ class Travis::Api::App
|
||||||
register :scoping
|
register :scoping
|
||||||
helpers :current_user
|
helpers :current_user
|
||||||
|
|
||||||
|
# TODO hmmm?
|
||||||
before { content_type :json }
|
before { content_type :json }
|
||||||
|
|
||||||
error(ActiveRecord::RecordNotFound, Sinatra::NotFound) { not_found }
|
error(ActiveRecord::RecordNotFound, Sinatra::NotFound) { not_found }
|
||||||
not_found { content_type =~ /json/ ? { 'file' => 'not found' } : 'file not found' }
|
not_found { content_type =~ /json/ ? { 'file' => 'not found' } : 'file not found' }
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ class Travis::Api::App
|
||||||
class Endpoint
|
class Endpoint
|
||||||
class Accounts < Endpoint
|
class Accounts < Endpoint
|
||||||
get '/', scope: :private do
|
get '/', scope: :private do
|
||||||
body all(params).run, type: :accounts
|
respond_with all(params).run, type: :accounts
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,7 @@ class Travis::Api::App
|
||||||
class Artifacts < Endpoint
|
class Artifacts < Endpoint
|
||||||
# Fetches an artifact by it's *id*.
|
# Fetches an artifact by it's *id*.
|
||||||
get '/:id' do |id|
|
get '/:id' do |id|
|
||||||
body one(params).run
|
respond_with one(params).run
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,7 @@ class Travis::Api::App
|
||||||
class Endpoint
|
class Endpoint
|
||||||
class Branches < Endpoint
|
class Branches < Endpoint
|
||||||
get '/' do
|
get '/' do
|
||||||
body all(params).run, type: :branches
|
respond_with all(params).run, type: :branches
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,11 +4,11 @@ class Travis::Api::App
|
||||||
class Endpoint
|
class Endpoint
|
||||||
class Builds < Endpoint
|
class Builds < Endpoint
|
||||||
get '/' do
|
get '/' do
|
||||||
body all(params).run
|
respond_with all(params).run
|
||||||
end
|
end
|
||||||
|
|
||||||
get '/:id' do
|
get '/:id' do
|
||||||
body one(params).run
|
respond_with one(params).run
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,7 @@ class Travis::Api::App
|
||||||
class Endpoint
|
class Endpoint
|
||||||
class Hooks < Endpoint
|
class Hooks < Endpoint
|
||||||
get '/', scope: :private do
|
get '/', scope: :private do
|
||||||
body all(params).run, type: :hooks
|
respond_with all(params).run, type: :hooks
|
||||||
end
|
end
|
||||||
|
|
||||||
put '/:id?', scope: :private do
|
put '/:id?', scope: :private do
|
||||||
|
|
|
@ -4,11 +4,11 @@ class Travis::Api::App
|
||||||
class Endpoint
|
class Endpoint
|
||||||
class Jobs < Endpoint
|
class Jobs < Endpoint
|
||||||
get '/' do
|
get '/' do
|
||||||
body all(params).run
|
respond_with all(params).run
|
||||||
end
|
end
|
||||||
|
|
||||||
get '/:id' do
|
get '/:id' do
|
||||||
body one(params).run
|
respond_with one(params).run
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,12 +4,22 @@ class Travis::Api::App
|
||||||
class Endpoint
|
class Endpoint
|
||||||
class Repositories < Endpoint
|
class Repositories < Endpoint
|
||||||
get '/' do
|
get '/' do
|
||||||
body all(params).run
|
respond_with all(params).run
|
||||||
end
|
end
|
||||||
|
|
||||||
get '/:id' do
|
get '/:id' do
|
||||||
body one(params).run
|
respond_with one(params).run
|
||||||
end
|
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
|
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
|
get '/:id?', scope: :private do
|
||||||
body current_user
|
respond_with current_user
|
||||||
end
|
end
|
||||||
|
|
||||||
put '/:id?', scope: :private do
|
put '/:id?', scope: :private do
|
||||||
|
|
|
@ -4,7 +4,7 @@ class Travis::Api::App
|
||||||
class Endpoint
|
class Endpoint
|
||||||
class Workers < Endpoint
|
class Workers < Endpoint
|
||||||
get '/' do
|
get '/' do
|
||||||
body all(params).run
|
respond_with all(params).run
|
||||||
end
|
end
|
||||||
end
|
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
|
enable :raise_errors
|
||||||
# disable :dump_errors
|
# disable :dump_errors
|
||||||
register :subclass_tracker
|
register :subclass_tracker
|
||||||
helpers :json_renderer, :result_image
|
helpers :respond_with, :mime_types
|
||||||
end
|
end
|
||||||
|
|
||||||
configure :development do
|
configure :development do
|
||||||
|
|
|
@ -9,7 +9,7 @@ describe 'Builds' do
|
||||||
|
|
||||||
it 'GET /builds?repository_id=1' do
|
it 'GET /builds?repository_id=1' do
|
||||||
response = get '/builds', { repository_id: repo.id }, headers
|
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
|
end
|
||||||
|
|
||||||
it 'GET /builds/1' do
|
it 'GET /builds/1' do
|
||||||
|
|
|
@ -7,8 +7,8 @@ describe Travis::Api::App::Extensions::SmartConstants do
|
||||||
|
|
||||||
describe :helpers do
|
describe :helpers do
|
||||||
it 'works' do # :)
|
it 'works' do # :)
|
||||||
some_app.helpers :json_renderer
|
some_app.helpers :respond_with
|
||||||
some_app.ancestors.should include(Travis::Api::App::Helpers::JsonRenderer)
|
some_app.ancestors.should include(Travis::Api::App::Helpers::RespondWith)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
require 'json'
|
require 'json'
|
||||||
|
|
||||||
describe Travis::Api::App::Helpers::JsonRenderer do
|
# describe Travis::Api::App::Helpers::JsonRenderer do
|
||||||
before do
|
# before do
|
||||||
mock_app do
|
# mock_app do
|
||||||
helpers Travis::Api::App::Helpers::JsonRenderer
|
# helpers Travis::Api::App::Helpers::JsonRenderer
|
||||||
get('/') { {'foo' => 'bar'} }
|
# get('/') { {'foo' => 'bar'} }
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
it 'renders body as json' do
|
# it 'renders body as json' do
|
||||||
get('/').should be_ok
|
# get('/').should be_ok
|
||||||
JSON.load(body).should == {'foo' => 'bar'}
|
# JSON.load(body).should == {'foo' => 'bar'}
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user