forked from magic003/search_pocket
-
Notifications
You must be signed in to change notification settings - Fork 0
/
search_pocket_app.rb
145 lines (128 loc) · 4.18 KB
/
search_pocket_app.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
142
143
144
145
require 'sinatra/base'
require 'haml'
require 'sinatra/config_file'
require 'omniauth'
require 'omniauth-pocket'
require 'sequel'
require 'riddle'
class SearchPocketApp < Sinatra::Base
# version number
VERSION = '0.0.1'
# application config file
register Sinatra::ConfigFile
config_file 'config/config.yml'
enable :sessions
enable :logging
set :views, ['views/layouts', 'views/pages', 'views/partials']
set :haml, {:format => :html5, :layout => :layout }
# include helpers
Dir["./app/helpers/*.rb"].each { |file| require file }
helpers ViewDirectoriesHelper, SessionHelper, LinkHelper
# include models
db = settings.db
Sequel.connect("mysql2://#{db[:username]}:#{db[:password]}@#{db[:host]}:#{db[:port]}/#{db[:database]}")
Dir["./app/models/*.rb"].each { |file| require file }
# use the omniauth-pocket middleware
pocket = settings.pocket
use OmniAuth::Builder do
provider :pocket, pocket[:client_id], pocket[:client_secret]
end
before '/search' do
if current_user.nil?
redirect to('/')
end
end
# routers
get '/' do
if signed_in?
user = current_user
message = nil
if user.since.nil? || Link.where(user_id: user.id, status: 2).empty?
message = 'Your links will be ready for search in several minutes.'
end
haml :search, :locals => {message: message}
else # user not logged in
haml :index, :layout => :home
end
end
get '/auth/:provider/callback' do
uid = env['omniauth.auth'].uid
token = env['omniauth.auth'].credentials.token
sign_in(uid)
user = User[:name => uid]
if user.nil? # it is a new user
user = User.create({:name => uid, :token => token, :register_at => DateTime.now,
:login_at => DateTime.now})
# spawn a process to retrieve and parse links
logger.info "spawn a retrieval process for user #{user.name}"
e = ENV['RACK_ENV'] || 'development'
logger.info "Environment: #{e}"
pid = Process.spawn("script/crawler.rb -c config/config.yml -e #{e} -u #{user.name} "\
"&& script/parser.rb -c config/config.yml -e #{e} "\
"&& script/indexer.rb -c config/config.yml -s config/sphinx.conf -e #{e}",
:chdir => File.expand_path(File.dirname(__FILE__)), :err => :out)
Process.detach(pid)
else
user.set(login_at: DateTime.now)
user.set(token: token) unless user.token.eql?(token)
user.save
end
redirect to('/')
end
get '/auth/failure' do
logger.error "Pocket auth failed: #{params[:message]}"
[400, haml(:error, :locals =>
{ message: "Failed because of #{params[:message]}" })]
end
get '/logout' do
sign_out
redirect to('/');
end
get '/search' do
q = params[:q]
page = (params[:p] || 1).to_i
per_page = 10
if q.nil? || q.empty?
haml :search, :locals => {:message => nil}
else
index = 'main'
client = Riddle::Client.new
client.filters << Riddle::Client::Filter.new('user_id', [current_user.id])
client.offset = (page - 1) * per_page
client.limit = per_page
results = client.query(q, index)
ids = results[:matches].map { |match| match[:doc] }
unless ids.empty?
links = Link.where(:id => ids).all
docs = links.map(&:content)
excerpts = client.excerpts(:docs => docs, :index => index, :words => q)
links.each_index do |i|
links[i].excerpt = excerpts[i]
end
else
links = []
end
haml :results, :locals => {:q => q,
:total => results[:total],
:time => results[:time],
:links => links,
:per_page => per_page,
:page => page}
end
end
get '/terms' do
haml :terms
end
get '/privacy' do
haml :privacy
end
not_found do
[404, haml(:error, locals: { message: "Page Not Found" })]
end
error do
logger.error env['sinatra.error'].name
[500, haml(:error, locals: { message: "Something went wrong on server"})]
end
# Run this application
run! if app_file == $0
end