-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.rb
120 lines (105 loc) · 3.59 KB
/
main.rb
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
require 'rubygems'
require 'sinatra'
require 'json'
require 'data_mapper'
require 'dm-migrations'
require 'will_paginate'
require 'will_paginate/collection'
require 'will_paginate/view_helpers'
require 'haml'
require 'active_attr'
# Now using pg locally and on heroku
# First create a unicycle database - you may need to change the local og url
# here or run the app with
# $ DATABASE_URL='postgres://user:pwd@host:port/database' ruby main.rb
database_url = ENV['DATABASE_URL'] || 'postgres://tim@localhost:5432/unicycle'
DataMapper.setup(:default, database_url)
# A model representing a unicode character, maps to a characters table in the database
class Character
include DataMapper::Resource
property :id, Serial
property :code, String
property :hex, String
property :ref, String
property :description, String
# Helper method to search and return an array of characters
# paginated usin the will_paginate gem
def self.paginated_search(params, term)
per_page = params[:per_page] || 20
page = params[:page] || 1
page = page.to_i
page -= 1
per_page = per_page.to_i
offset = per_page * page
term = term.gsub('#','').upcase
characters = Character.all
# apply search term is there is one
unless term.empty?
characters = characters.all(:description.like => "%#{term}%") |
characters.all(:hex.like => "%#{term}%") |
characters.all(:code.like => "%#{term}%")
end
# get the current set of characters to display
characters_on_this_page = characters.all(limit: per_page, offset: offset)
WillPaginate::Collection.create(page + 1, per_page, characters.count) do |p|
p.replace characters_on_this_page
end
end
end
DataMapper.finalize
DataMapper.auto_upgrade!
# This root url delivers a json-driven page with no server-side view formatting at all
get '/' do
haml :webapp, format: :html5
@term = params[:term] || ''
@characters = Character.paginated_search(params, @term)
haml :webapp, format: :html5
end
# This url is a web service serving up characters as paginated json
# This is the format of the json returned
# {
# "characters":
# [
# {
# "code": " ",
# "id": 1,
# "hex": "U+0020",
# "description": "SPACE",
# "ref": " "
# },
# {...}
# ],
# "pagination": {
# "total_entries": 11293,
# "current_page_number": {
# "name": "page",
# "_dc_obj": 1
# },
# "total_pages": 565,
# "previous_page": "",
# "next_page": "http://unicycle.herokuapp.com/characters.json?page=2&term=",
# "offset": 0,
# "current_page": "http://unicycle.herokuapp.com/characters.json?page=1&term="
# }
# }
get '/characters.json' do
content_type :json
@term = params[:term] || ''
@characters = Character.paginated_search(params, @term)
pagination = { next_page: url_for_page(@characters.next_page, @term),
previous_page: url_for_page(@characters.previous_page, @term),
current_page: url_for_page(@characters.current_page, @term),
current_page_number: @characters.current_page,
offset: @characters.offset,
total_entries: @characters.total_entries,
total_pages: @characters.total_pages }
{ characters: @characters, pagination: pagination }.to_json
end
# Helper to format urls returned in the pagination json
def url_for_page(page, term)
if page.nil?
''
else
"http://#{request.host_with_port}#{request.path_info}?page=#{page}&term=#{term}"
end
end