1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
require 'sinatra/base'
require "sinatra/reloader"
ENV["RACK_ENV"] ||= "production"
require File.join(ENV["HOME"],".opentox","config","default.rb") if File.exist? File.join(ENV["HOME"],".opentox","config","default.rb")
require File.join(ENV["HOME"],".opentox","config","#{SERVICE}.rb")
logfile = File.join(ENV['HOME'], ".opentox","log","#{ENV["RACK_ENV"]}.log")
$logger = OTLogger.new(logfile)
module OpenTox
# Base class for OpenTox services
class Service < Sinatra::Base
include Backend
# use OpenTox error handling
set :raise_errors, false
set :show_exceptions, false
set :static, false
configure :development do
register Sinatra::Reloader
also_reload "./*.rb"
also_reload "../opentox-client/lib/*.rb"
also_reload File.join(ENV["HOME"],".opentox","config","#{SERVICE}.rb")
end
before do
request.content_type ? response['Content-Type'] = request.content_type : response['Content-Type'] = request.env['HTTP_ACCEPT']
parse_input if request.request_method =~ /POST|PUT/
@accept = request.env['HTTP_ACCEPT']
@accept = "text/html" if @accept =~ /\*\/\*/ or request.env["HTTP_USER_AGENT"]=~/MSIE/
@accept = request.params["media"] if request.params["media"]
response['Content-Type'] = @accept
end
before "/#{SERVICE}/:id" do
@uri = uri("/#{SERVICE}/#{params[:id]}")
end
helpers do
def parse_input
case request.content_type
when /multipart/
if params[:file]
@body = params[:file][:tempfile].read
# sdf files are incorrectly detected
@content_type = params[:file][:type]
@content_type = "chemical/x-mdl-sdfile" if File.extname(params[:file][:filename]) == ".sdf"
end
else
@body = request.body.read
@content_type = request.content_type
end
end
end
# Attention: Error within tasks are catched by Task.create
error do
error = request.env['sinatra.error']
if error.respond_to? :report
body = error.report.to_turtle
else
response['Content-Type'] = "text/plain"
body = "#{error.message}\n"
body += "URI: #{error.uri}\n" if error.is_a?(RuntimeError)
body += error.backtrace.join("\n")
end
error.respond_to?(:http_code) ? code = error.http_code : code = 500
halt code, body
end
def return_task( task )
raise "http_code == nil" unless task.code!=nil
case request.env['HTTP_ACCEPT']
when /rdf/
response['Content-Type'] = "application/rdf+xml"
halt task.code,task.to_rdfxml
when /yaml/
response['Content-Type'] = "application/x-yaml"
halt task.code,task.to_yaml # PENDING differs from task-webservice
when /html/
response['Content-Type'] = "text/html"
# html -> task created with html form -> redirect to task uri
redirect task.uri
else # default /uri-list/
response['Content-Type'] = "text/uri-list"
if task.completed?
halt task.code,task.resultURI+"\n"
else
halt task.code,task.uri+"\n"
end
end
end
# Default methods, may be overwritten by derived services
# see http://jcalcote.wordpress.com/2008/10/16/put-or-post-the-rest-of-the-story/
# Get a list of objects at the server
get "/#{SERVICE}/?" do
$logger.debug "listing all #{SERVICE} objects"
FourStore.list @accept
end
# Create a new resource
post "/#{SERVICE}/?" do
@uri = uri("/#{SERVICE}/#{SecureRandom.uuid}")
FourStore.put(@uri, @body, @content_type)
response['Content-Type'] = "text/uri-list"
@uri
end
# Get resource representation
get "/#{SERVICE}/:id/?" do
FourStore.get(@uri, @accept)
end
# Modify (i.e. add rdf statments to) a resource
post "/#{SERVICE}/:id/?" do
FourStore.post @uri, @body, @content_type
end
# Create or updata a resource
put "/#{SERVICE}/:id/?" do
FourStore.put @uri, @body, @content_type
end
# Delete a resource
delete "/#{SERVICE}/:id/?" do
FourStore.delete @uri
end
end
end
|