forked from oisin/corkboard_server_example
-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathcorkboard.rb
More file actions
162 lines (139 loc) · 3.98 KB
/
corkboard.rb
File metadata and controls
162 lines (139 loc) · 3.98 KB
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
require 'rubygems'
require 'sinatra'
require 'json'
require 'dm-core'
require 'dm-validations'
require 'dm-timestamps'
require 'dm-migrations'
if development? # This is set by default, override with `RACK_ENV=production rackup`
require 'sinatra/reloader'
require 'debugger'
Debugger.settings[:autoeval] = true
Debugger.settings[:autolist] = 1
Debugger.settings[:reload_source_on_change] = true
end
# TODO:
# . logging
# . media types testing
# . put the database somewhere else
# . GET a range
# . multi-user with authentication
configure :development, :production do
set :datamapper_url, "sqlite3://#{File.dirname(__FILE__)}/corkboard.sqlite3"
end
configure :test do
set :datamapper_url, "sqlite3://#{File.dirname(__FILE__)}/corkboard-test.sqlite3"
end
DataMapper.setup(:default, settings.datamapper_url)
class Note
include DataMapper::Resource
Note.property(:id, Serial)
Note.property(:subject, Text, :required => true)
Note.property(:content, Text, :required => true)
Note.property(:created_at, DateTime)
Note.property(:updated_at, DateTime)
def to_json(*a)
{
'id' => self.id,
'subject' => self.subject,
'content' => self.content,
'date' => self.updated_at
}.to_json(*a)
end
end
DataMapper.finalize
Note.auto_upgrade!
def jsonp?(json)
if params[:callback]
return("#{params[:callback]}(#{json})")
else
return(json)
end
end
# Download one note, subject and content
# Returns:
# {
# subject : "the subject",
# content : "wibble wibble wibble wibble""
# }
#
get '/note/:id' do
note = Note.get(params[:id])
if note.nil?
return [404, {'Content-Type' => 'application/json'}, ['']]
end
return [200, {'Content-Type' => 'application/json'}, [jsonp?(note.to_json)]]
end
# Add a note to the server, subject and content
# will give you back an id
# Body
# {
# subject : "the subject",
# content : "wibble wibble wibble wibble""
# }
#
# Returns
# 2
put '/note' do
# Request.body.read is destructive, make sure you don't use a puts here.
data = JSON.parse(request.body.read)
# Normally we would let the model validations handle this but we don't
# have validations yet so we have to check now and after we save.
if data.nil? || data['subject'].nil? || data['content'].nil?
return [406, {'Content-Type' => 'application/json'}, ['']]
end
note = Note.create(
:subject => data['subject'],
:content => data['content'],
:created_at => Time.now,
:updated_at => Time.now)
# PUT requests must return a Location header for the new resource
if note.save
return [201, {'Content-Type' => 'application/json', 'Location' => "/note/#{note.id}"}, [jsonp?(note.to_json)]]
else
return [406, {'Content-Type' => 'application/json'}, ['']]
end
end
# Update the content of a note, replace subject
# or content
# Body
# {
# subject : "the subject",
# content : "wibble wibble wibble wibble""
# }
# Subject and content are optional!
post '/note/:id' do
# Request.body.read is destructive, make sure you don't use a puts here.
data = JSON.parse(request.body.read)
if data.nil?
return [406, {'Content-Type' => 'application/json'}, ['']]
end
note = Note.get(params[:id])
if note.nil?
return [404, {'Content-Type' => 'application/json'}, ['']]
end
%w(subject content).each do |key|
if !data[key].nil? && data[key] != note[key]
note[key] = data[key]
note['updated_at'] = Time.now
end
end
if note.save then
return [200, {'Content-Type' => 'application/json'}, [jsonp?(note.to_json)]]
else
return [406, {'Content-Type' => 'application/json'}, ['']]
end
end
# Remove a note entirely
# delete method hack might be required here!
delete '/note/:id' do
note = Note.get(params[:id])
if note.nil?
return [404, {'Content-Type' => 'application/json'}, ['']]
end
if note.destroy then
return [204, {'Content-Type' => 'application/json'}, ['']]
else
return [500, {'Content-Type' => 'application/json'}, ['']]
end
end