-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathbookscan-premium-optimizer.rb
141 lines (122 loc) · 3.27 KB
/
bookscan-premium-optimizer.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#
# bookscan-premium-optimizer.rb
#
Bundler.require
require 'json'
require_relative 'helpers/amazon'
require_relative 'helpers/book'
require_relative 'helpers/booklist'
require_relative 'models/candidate'
module BookscanPremiumOptimizer
class App < Sinatra::Base
set :haml, {format: :html5}
enable :logging
configure :production do
Mongo::Logger.level = Logger::WARN
Mongoid::Config.load_configuration({
clients: {default: {uri: ENV['MONGODB_URI'] || ENV['MONGOLAB_URI']}}
})
set :cache, Dalli::Client.new(
ENV["MEMCACHIER_SERVERS"],
:username => ENV["MEMCACHIER_USERNAME"],
:password => ENV["MEMCACHIER_PASSWORD"],
:expires_in => 24 * 60 * 60)
end
configure :development, :test do
Bundler.require :development
register Sinatra::Reloader
disable :protection
set :logging, ::Logger::DEBUG
Mongo::Logger.level = Logger::WARN
Mongoid::Config.load_configuration({
clients: {default: {uri: 'mongodb://localhost:27017/bpo'}}
})
set :cache, Dalli::Client.new(nil, :expires_in => 24 * 60 * 60)
end
def amazon(isbn, async = true)
amazon = settings.cache.get(isbn)
return amazon if amazon
if async
AmazonPool.add(isbn, settings.cache);
raise AmazonTimeout.new('no amazon data in cache, retry.');
else
amazon = Amazon.new(isbn)
settings.cache.set(isbn, amazon)
settings.cache.set(amazon.isbn, amazon) if isbn != amazon.isbn
return amazon
end
end
def convert2long(candidate, isbns)
isbns.map do |short, long|
candidate.delete(short)
candidate.add(long)
end
end
def booklist(candidate, async = true)
timeout = nil
convert = {}
books = candidate.isbns.map do |isbn|
begin
a = amazon(isbn, async)
if isbn.length < 13 # convert short ISBN to long
convert[isbn] = a.isbn
end
BookscanPremiumOptimizer::Book.new(a.title, a.url, a.pages, a.isbn)
rescue AmazonError
nil
rescue AmazonTimeout => e
timeout = e
end
end
convert2long(candidate, convert)
raise timeout if timeout
return BookscanPremiumOptimizer::Booklist.pack(books.compact, true)
end
get '/' do
haml :index
end
post '/' do
candidate = Candidate.new_list
redirect "/#{candidate.id}"
end
get '/:id' do
booklist_id = params[:id]
candidate = Candidate.where(id: booklist_id).first
return 404 unless candidate
haml :list, locals: {booklist_id: booklist_id}
end
put '/:id' do
booklist_id = params[:id]
candidate = Candidate.where(id: booklist_id).first
return 404 unless candidate
isbn = params[:isbn]
begin
a = amazon(isbn, false)
candidate.add(a.isbn)
content_type :json
return booklist(candidate, false).to_json
rescue AmazonError
return 404
end
end
delete '/:id/:isbn' do
booklist_id = params[:id]
candidate = Candidate.where(id: booklist_id).first
return 404 unless candidate
isbn = params[:isbn]
return booklist(candidate.delete(isbn), false).to_json
end
get '/:id/list' do
booklist_id = params[:id]
candidate = Candidate.where(id: booklist_id).first
return 404 unless candidate
begin
content_type :json
return booklist(candidate).to_json
rescue AmazonTimeout
return 408 # Timeout
end
end
end
end
BookscanPremiumOptimizer::App.run! if __FILE__ == $0