forked from adamwiggins/scanty
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.rb
213 lines (181 loc) · 6.1 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
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# encoding: utf-8
require 'rubygems'
require 'sinatra/base'
require 'sinatra/contrib'
require 'sequel'
require 'builder'
require 'digest/sha1'
class Main < Sinatra::Base
register Sinatra::Contrib
config_file "#{settings.root}/config.yml"
configure do
DB = Sequel.connect(ENV['DATABASE_URL'] || 'sqlite://blog.db')
require 'ostruct'
Blog = OpenStruct.new(
:title => settings.title,
:subtitle => settings.subtitle,
:author => settings.author,
:url_base => settings.url_base,
:admin_password => Digest::SHA1.hexdigest(settings.admin_password),
:admin_cookie_key => settings.admin_cookie_key,
:admin_cookie_value => Digest::SHA1.hexdigest(settings.admin_cookie_value),
:disqus_shortname => settings.disqus_shortname ||= nil,
:page_size => settings.page_size.to_i,
:timezone => settings.timezone
)
end
configure :development do
register Sinatra::Reloader
end
error do
e = request.env['sinatra.error']
puts e.to_s
puts e.backtrace.join("\n")
"Application error"
end
$LOAD_PATH.unshift("#{settings.root}/lib")
require 'post'
helpers do
def admin?
request.cookies[Blog.admin_cookie_key] == Blog.admin_cookie_value
end
def auth
halt [ 401, 'Not authorized' ] unless admin?
end
def paginate(post, options={})
return "" if post.page_count == 1
html = '<div class="paginate">'
url = ""
url = "/tags/#{options[:tag]}" if options[:tag]
if post.prev_page
html += "<p class=\"pull-left\"><a href=\"#{url}/page/#{post.prev_page}\">← Previous</a></p>"
end
if post.next_page
html += "<p class=\"pull-right\"><a href=\"#{url}/page/#{post.next_page}\">Next →</a></p>"
end
html += "</div>"
end
end
### Public
get '/' do
posts = Post.filter(:delete_status => 1).reverse_order(:created_at).paginate(1, Blog.page_size)
erb :index, :locals => { :posts => posts, :dates => Post.dates(admin?) }, :layout => :sidebar_layout
end
get %r{^/\d{4}/\d{2}/\d{2}/(?<slug>[a-zA-Z0-9%\-]+)/?$} do
posts = nil
if admin?
post = Post.filter(:slug => URI.escape(params[:slug])).first
else
post = Post.filter(:delete_status => 1).filter(:slug => URI.escape(params[:slug])).first
end
halt [ 404, "Page not found" ] unless post
erb :post, :locals => { :post => post }, :layout => :layout
end
get '/archive' do
posts = nil
if admin?
posts = Post.reverse_order(:created_at)
else
posts = Post.filter(:delete_status => 1).reverse_order(:created_at)
end
erb :archive, :locals => { :posts => posts }, :layout => :layout
end
get '/tags/:tag' do
tag = params[:tag]
posts = Post.filter(:delete_status => 1).filter(:tags.like("%#{tag}%")).reverse_order(:created_at).paginate(1, Blog.page_size)
erb :tagged, :locals => { :posts => posts, :tag => tag }, :layout => :layout
end
get '/page/:page' do
posts = Post.filter(:delete_status => 1).reverse_order(:created_at).paginate(params[:page].to_i, Blog.page_size)
redirect '/' if posts.page_count < params[:page].to_i
erb :index, :locals => { :posts => posts, :dates => Post.dates(admin?) }, :layout => :sidebar_layout
end
get '/tags/:tag/page/:page' do
tag = params[:tag]
posts = Post.filter(:delete_status => 1).filter(:tags.like("%#{tag}%")).reverse_order(:created_at).paginate(params[:page].to_i, Blog.page_size)
redirect '/' if posts.page_count < params[:page].to_i
erb :tagged, :locals => { :posts => posts, :tag => tag }, :layout => :layout
end
get %r{/(?:rss|feed)(?:.xml)?} do
@posts = Post.filter(:delete_status => 1).reverse_order(:created_at).limit(20)
content_type 'application/atom+xml', :charset => 'utf-8'
builder :feed
end
get %r{^/(?<year>\d{4})/(?<month>\d{2})/?$} do
all_posts = nil
if admin?
all_posts = Post.reverse_order(:created_at)
else
all_posts = Post.filter(:delete_status => 1).reverse_order(:created_at)
end
posts = []
all_posts.each do |post|
posts << post if post.created_at.strftime("%Y") == params[:year] and post.created_at.strftime("%m") == params[:month]
end
erb :archive, :locals => { :posts => posts }, :layout => :layout
end
### Admin
get '/auth' do
erb :auth, :locals => { :error => false }
end
post '/auth' do
if Digest::SHA1.hexdigest(params[:password]) == Blog.admin_password
response.set_cookie(Blog.admin_cookie_key, Blog.admin_cookie_value)
redirect '/'
else
erb :auth, :locals => { :error => true }
end
end
get '/logout' do
response.delete_cookie(Blog.admin_cookie_key)
redirect '/'
end
get '/posts/new' do
auth
erb :edit, :locals => { :post => Post.new, :url => '/posts' }
end
post '/posts' do
auth
post = nil
DB.transaction do
post = Post.new(
:title => params[:title],
:tags => params[:tags],
:content => params[:content],
:format => params[:format],
:created_at => Time.now.utc.getlocal(Blog.timezone))
post.save
end
redirect post.url
end
get %r{^/\d{4}/\d{2}/\d{2}/(?<slug>[a-zA-Z0-9%\-]+)/edit/?$} do
auth
post = Post.filter(:slug => URI.escape(params[:slug])).first
halt [ 404, "Page not found" ] unless post
erb :edit, :locals => { :post => post, :url => post.url }
end
post %r{^/\d{4}/\d{2}/\d{2}/(?<slug>[a-zA-Z0-9%\-]+)/$} do
auth
delete_status = params[:delete_status] ? 0 : 1
post = nil
DB.transaction do
post = Post.filter(:slug => URI.escape(params[:slug])).first
halt [ 404, "Page not found" ] unless post
unless params[:delete_status]
post.title = params[:title]
post.tags = params[:tags]
post.content = params[:content]
post.slug = Post.make_slug(params[:title]) if params[:change_slug]
post.format = params[:format]
end
post.delete_status = delete_status
post.update
if params[:delete_status]
redirect '/'
else
redirect post.url
end
end
end
run! if app_file == $0
end