lokka 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (197) hide show
  1. data/Gemfile +48 -0
  2. data/LICENSE +20 -0
  3. data/README.ja.rdoc +46 -0
  4. data/README.rdoc +46 -0
  5. data/Rakefile +116 -0
  6. data/VERSION +1 -0
  7. data/bin/autotest +16 -0
  8. data/bin/bluefeather +16 -0
  9. data/bin/convert_to_should_syntax +16 -0
  10. data/bin/css2sass +16 -0
  11. data/bin/edit_json.rb +16 -0
  12. data/bin/erubis +16 -0
  13. data/bin/exceptional +16 -0
  14. data/bin/haml +16 -0
  15. data/bin/html2haml +16 -0
  16. data/bin/jeweler +16 -0
  17. data/bin/lokka +4 -0
  18. data/bin/prettify_json.rb +16 -0
  19. data/bin/rackup +16 -0
  20. data/bin/rake +16 -0
  21. data/bin/rcov +16 -0
  22. data/bin/sass +16 -0
  23. data/bin/sass-convert +16 -0
  24. data/bin/tilt +16 -0
  25. data/bin/unit_diff +16 -0
  26. data/config.ru +3 -0
  27. data/config.yml +4 -0
  28. data/i18n/en.yml +149 -0
  29. data/i18n/ja.yml +149 -0
  30. data/init.rb +7 -0
  31. data/install.rb +16 -0
  32. data/lib/lokka.rb +138 -0
  33. data/lib/lokka/app.rb +562 -0
  34. data/lib/lokka/before.rb +29 -0
  35. data/lib/lokka/bread_crumb.rb +34 -0
  36. data/lib/lokka/category.rb +33 -0
  37. data/lib/lokka/comment.rb +26 -0
  38. data/lib/lokka/entry.rb +70 -0
  39. data/lib/lokka/helpers.rb +214 -0
  40. data/lib/lokka/option.rb +23 -0
  41. data/lib/lokka/site.rb +19 -0
  42. data/lib/lokka/tag.rb +5 -0
  43. data/lib/lokka/theme.rb +17 -0
  44. data/lib/lokka/user.rb +77 -0
  45. data/lib/sqlite3.dll +0 -0
  46. data/lokka.exe +0 -0
  47. data/lokka.exy +15 -0
  48. data/lokka.gemspec +373 -0
  49. data/lokka.ico +0 -0
  50. data/lokka.rb +11 -0
  51. data/public/admin/categories/edit.haml +6 -0
  52. data/public/admin/categories/form.haml +18 -0
  53. data/public/admin/categories/index.haml +15 -0
  54. data/public/admin/categories/new.haml +5 -0
  55. data/public/admin/comments/edit.haml +6 -0
  56. data/public/admin/comments/form.haml +29 -0
  57. data/public/admin/comments/index.haml +22 -0
  58. data/public/admin/comments/new.haml +5 -0
  59. data/public/admin/css/editor.css +10 -0
  60. data/public/admin/css/jquery.cleditor.css +24 -0
  61. data/public/admin/css/style.css +710 -0
  62. data/public/admin/edit.haml +42 -0
  63. data/public/admin/favicon.ico +0 -0
  64. data/public/admin/images/add.png +0 -0
  65. data/public/admin/images/aside_arrow.png +0 -0
  66. data/public/admin/images/buttons.gif +0 -0
  67. data/public/admin/images/category.png +0 -0
  68. data/public/admin/images/comment.png +0 -0
  69. data/public/admin/images/dashboard.png +0 -0
  70. data/public/admin/images/file.png +0 -0
  71. data/public/admin/images/files.png +0 -0
  72. data/public/admin/images/mail-attachment.png +0 -0
  73. data/public/admin/images/plugin.png +0 -0
  74. data/public/admin/images/post.png +0 -0
  75. data/public/admin/images/setting.png +0 -0
  76. data/public/admin/images/tag.png +0 -0
  77. data/public/admin/images/theme.png +0 -0
  78. data/public/admin/images/toolbar.gif +0 -0
  79. data/public/admin/images/user.png +0 -0
  80. data/public/admin/index.haml +1 -0
  81. data/public/admin/js/editor.js +7 -0
  82. data/public/admin/js/jquery.cleditor.js +1132 -0
  83. data/public/admin/js/jquery.cleditor.min.js +31 -0
  84. data/public/admin/layout.haml +91 -0
  85. data/public/admin/pages/edit.haml +6 -0
  86. data/public/admin/pages/form.haml +33 -0
  87. data/public/admin/pages/index.haml +23 -0
  88. data/public/admin/pages/new.haml +5 -0
  89. data/public/admin/plugins/index.haml +4 -0
  90. data/public/admin/posts/edit.haml +6 -0
  91. data/public/admin/posts/form.haml +33 -0
  92. data/public/admin/posts/index.haml +23 -0
  93. data/public/admin/posts/new.haml +5 -0
  94. data/public/admin/show.haml +7 -0
  95. data/public/admin/signup.haml +17 -0
  96. data/public/admin/site/edit.haml +13 -0
  97. data/public/admin/tags/edit.haml +6 -0
  98. data/public/admin/tags/form.haml +10 -0
  99. data/public/admin/tags/index.haml +19 -0
  100. data/public/admin/themes/index.haml +13 -0
  101. data/public/admin/users/edit.haml +6 -0
  102. data/public/admin/users/form.haml +22 -0
  103. data/public/admin/users/index.haml +24 -0
  104. data/public/admin/users/new.haml +5 -0
  105. data/public/plugin/lokka-google_analytics/lib/lokka/google_analytics.rb +29 -0
  106. data/public/plugin/lokka-google_analytics/views/index.haml +15 -0
  107. data/public/plugin/lokka-hello/lib/lokka/hello.rb +15 -0
  108. data/public/plugin/lokka-markdown/lib/lokka/markdown.rb +12 -0
  109. data/public/plugin/lokka-rbconfig/lib/lokka/rbconfig.rb +11 -0
  110. data/public/plugin/lokka-rbconfig/views/index.haml +7 -0
  111. data/public/plugin/lokka-rbconfig/views/style.css +12 -0
  112. data/public/system/404.haml +20 -0
  113. data/public/system/500.haml +19 -0
  114. data/public/system/comments/form.haml +22 -0
  115. data/public/system/favicon.ico +0 -0
  116. data/public/system/index.builder +25 -0
  117. data/public/system/style.css +8 -0
  118. data/public/theme/default/entries.erb +40 -0
  119. data/public/theme/default/entry.erb +23 -0
  120. data/public/theme/default/layout.erb +74 -0
  121. data/public/theme/default/quote.gif +0 -0
  122. data/public/theme/default/screenshot.png +0 -0
  123. data/public/theme/default/style.css +1147 -0
  124. data/public/theme/jarvi/entries.erb +26 -0
  125. data/public/theme/jarvi/entry.erb +14 -0
  126. data/public/theme/jarvi/favicon.ico +0 -0
  127. data/public/theme/jarvi/images/aside_dt.gif +0 -0
  128. data/public/theme/jarvi/images/aside_dt.png +0 -0
  129. data/public/theme/jarvi/images/footer.gif +0 -0
  130. data/public/theme/jarvi/images/footer.psd +0 -0
  131. data/public/theme/jarvi/images/header_deascription_ul.gif +0 -0
  132. data/public/theme/jarvi/images/header_language.gif +0 -0
  133. data/public/theme/jarvi/images/header_nav.gif +0 -0
  134. data/public/theme/jarvi/images/html.gif +0 -0
  135. data/public/theme/jarvi/images/index_content.gif +0 -0
  136. data/public/theme/jarvi/images/index_content_footer.gif +0 -0
  137. data/public/theme/jarvi/images/index_content_header.gif +0 -0
  138. data/public/theme/jarvi/images/index_header_nav.gif +0 -0
  139. data/public/theme/jarvi/images/section_header_title.gif +0 -0
  140. data/public/theme/jarvi/images/wide_content.gif +0 -0
  141. data/public/theme/jarvi/images/wide_content_body.gif +0 -0
  142. data/public/theme/jarvi/images/wide_content_h3.gif +0 -0
  143. data/public/theme/jarvi/layout.erb +55 -0
  144. data/public/theme/jarvi/screenshot.png +0 -0
  145. data/public/theme/jarvi/style.css +618 -0
  146. data/public/theme/lokka-org/article.haml +9 -0
  147. data/public/theme/lokka-org/entries.haml +9 -0
  148. data/public/theme/lokka-org/entry.haml +1 -0
  149. data/public/theme/lokka-org/favicon.ico +0 -0
  150. data/public/theme/lokka-org/images/aside_dt.gif +0 -0
  151. data/public/theme/lokka-org/images/aside_dt.png +0 -0
  152. data/public/theme/lokka-org/images/download_button.jpg +0 -0
  153. data/public/theme/lokka-org/images/footer.gif +0 -0
  154. data/public/theme/lokka-org/images/footer.psd +0 -0
  155. data/public/theme/lokka-org/images/header_capture.gif +0 -0
  156. data/public/theme/lokka-org/images/header_capture.jpg +0 -0
  157. data/public/theme/lokka-org/images/header_capture_a.gif +0 -0
  158. data/public/theme/lokka-org/images/header_deascription_ul.gif +0 -0
  159. data/public/theme/lokka-org/images/header_h1_a.gif +0 -0
  160. data/public/theme/lokka-org/images/header_language.gif +0 -0
  161. data/public/theme/lokka-org/images/header_nav.gif +0 -0
  162. data/public/theme/lokka-org/images/heder_nav_home.gif +0 -0
  163. data/public/theme/lokka-org/images/heder_nav_home.jpg +0 -0
  164. data/public/theme/lokka-org/images/html.gif +0 -0
  165. data/public/theme/lokka-org/images/index_content.gif +0 -0
  166. data/public/theme/lokka-org/images/index_content_footer.gif +0 -0
  167. data/public/theme/lokka-org/images/index_content_header.gif +0 -0
  168. data/public/theme/lokka-org/images/index_header_h1.gif +0 -0
  169. data/public/theme/lokka-org/images/index_header_nav.gif +0 -0
  170. data/public/theme/lokka-org/images/language_a.png +0 -0
  171. data/public/theme/lokka-org/images/section_header_title.gif +0 -0
  172. data/public/theme/lokka-org/images/wide_content.gif +0 -0
  173. data/public/theme/lokka-org/images/wide_content_body.gif +0 -0
  174. data/public/theme/lokka-org/images/wide_content_h3.gif +0 -0
  175. data/public/theme/lokka-org/index.haml +5 -0
  176. data/public/theme/lokka-org/layout.haml +72 -0
  177. data/public/theme/lokka-org/quote.gif +0 -0
  178. data/public/theme/lokka-org/screenshot.png +0 -0
  179. data/public/theme/lokka-org/style.css +806 -0
  180. data/public/theme/p0t/article.haml +10 -0
  181. data/public/theme/p0t/entries.haml +9 -0
  182. data/public/theme/p0t/entry.haml +7 -0
  183. data/public/theme/p0t/favicon.ico +0 -0
  184. data/public/theme/p0t/images/quote.gif +0 -0
  185. data/public/theme/p0t/layout.haml +68 -0
  186. data/public/theme/p0t/screenshot.png +0 -0
  187. data/public/theme/p0t/style.css +359 -0
  188. data/public/theme/vicuna-mono/entries.erb +40 -0
  189. data/public/theme/vicuna-mono/entry.erb +23 -0
  190. data/public/theme/vicuna-mono/layout.erb +76 -0
  191. data/public/theme/vicuna-mono/quote.gif +0 -0
  192. data/public/theme/vicuna-mono/screenshot.png +0 -0
  193. data/public/theme/vicuna-mono/style.css +1156 -0
  194. data/test/helper.rb +23 -0
  195. data/test/lokka/app_test.rb +15 -0
  196. data/test/lokka/post_test.rb +17 -0
  197. metadata +965 -0
data/init.rb ADDED
@@ -0,0 +1,7 @@
1
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__)))
2
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), 'lib'))
3
+
4
+ require 'rubygems'
5
+ require 'bundler'
6
+ Bundler.setup
7
+ require 'lokka'
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ def _run(cmd)
4
+ puts cmd
5
+ system cmd
6
+ end
7
+
8
+ Dir.chdir(File.dirname(__FILE__))
9
+
10
+ _run 'gem update --system'
11
+ _run 'gem install bundler --no-rdoc --no-ri --version "1.0.3"'
12
+ _run 'bundle install --path bundle --without production test'
13
+ _run 'bundle exec rake db:reset'
14
+ puts '--- Installation complete ---'
15
+ puts 'Press Enter.'
16
+ STDIN.getc
@@ -0,0 +1,138 @@
1
+ # coding: utf-8
2
+ require 'rubygems'
3
+ require 'pathname'
4
+ require 'erb'
5
+ require 'ostruct'
6
+ require 'digest/sha1'
7
+
8
+ require 'active_support/all'
9
+ require 'sinatra/base'
10
+ require 'sinatra/r18n'
11
+ require 'sinatra/content_for'
12
+ require 'rack/flash'
13
+ require 'dm-core'
14
+ require 'dm-timestamps'
15
+ require 'dm-migrations'
16
+ require 'dm-validations'
17
+ require 'dm-types'
18
+ require 'dm-is-tree'
19
+ require 'dm-tags'
20
+ require 'dm-pager'
21
+ require 'haml'
22
+ require 'builder'
23
+ require 'exceptional'
24
+
25
+ require 'lokka/theme'
26
+ require 'lokka/user'
27
+ require 'lokka/site'
28
+ require 'lokka/option'
29
+ require 'lokka/entry'
30
+ require 'lokka/category'
31
+ require 'lokka/tag'
32
+ require 'lokka/comment'
33
+ require 'lokka/bread_crumb'
34
+ require 'lokka/before'
35
+ require 'lokka/helpers'
36
+ require 'lokka/app'
37
+
38
+ module Lokka
39
+ class NoTemplateError < StandardError; end
40
+
41
+ class Database
42
+ def initialize
43
+ @@models = [Site, Option, User, Entry, Category, Comment, Tag, Tagging]
44
+ end
45
+
46
+ def create
47
+ puts 'Creating Database...'
48
+ @@models.each {|m| m.auto_migrate! }
49
+ self
50
+ end
51
+
52
+ def setup
53
+ puts 'Initializing Database...'
54
+ User.create(
55
+ :name => 'test',
56
+ :password => 'test',
57
+ :password_confirmation => 'test')
58
+ Site.create(
59
+ :title => 'Test Site',
60
+ :description => 'description...',
61
+ :theme => 'jarvi')
62
+ Post.create(
63
+ :user_id => 1,
64
+ :title => "Test Post",
65
+ :body => "<p>Wellcome to Lokka!</p>\n<p><a href=\"/admin/\">Admin login</a> (user / password : test / test)</p>")
66
+ self
67
+ end
68
+ end
69
+ end
70
+
71
+ unless String.public_method_defined?(:force_encoding)
72
+ class String
73
+ def force_encoding(encoding)
74
+ self
75
+ end
76
+ end
77
+ end
78
+
79
+ unless String.public_method_defined?(:encoding)
80
+ class String
81
+ def encoding
82
+ self
83
+ end
84
+ end
85
+ end
86
+
87
+ unless defined? Encoding
88
+ class Encoding
89
+ def self.default_external
90
+ nil
91
+ end
92
+ end
93
+ end
94
+
95
+ module Rack
96
+ module Utils
97
+ alias :escape_org :escape
98
+ alias :unescape_org :unescape
99
+
100
+ def escape(s)
101
+ escape_org(s).force_encoding(Encoding.default_external)
102
+ end
103
+ def unescape(s)
104
+ unescape_org(s).force_encoding(Encoding.default_external)
105
+ end
106
+ end
107
+ end
108
+
109
+ module DataMapper
110
+ module Validations
111
+ class LengthValidator
112
+ alias :value_length_org :value_length
113
+ def value_length(value)
114
+ value.force_encoding(Encoding.default_external)
115
+ value_length_org(value)
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ module LuckySneaks
122
+ module StringExtensions
123
+ alias :to_url_org :to_url
124
+ def to_url
125
+ self.force_encoding(Encoding.default_external)
126
+ end
127
+ end
128
+ end
129
+
130
+ module Tilt
131
+ class Template
132
+ alias :render_org :render
133
+ def render(scope=Object.new, locals={}, &block)
134
+ output = render_org(scope, locals, &block)
135
+ output.force_encoding(Encoding.default_external) unless output.nil?
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,562 @@
1
+ module Lokka
2
+ class App < Sinatra::Base
3
+ def self.load_plugin
4
+ names = []
5
+ Dir["public/plugin/lokka-*/lib/lokka/*.rb"].each do |path|
6
+ paths = path.split(File::SEPARATOR)
7
+ $:.push File.join(paths[0], paths[1], paths[2], paths[3])
8
+
9
+ i18n = File.join(paths[0], paths[1], paths[2], 'i18n')
10
+ R18n.extension_places << R18n::Loader::YAML.new(i18n) if File.exist? i18n
11
+
12
+ name, ext = paths[5].split('.')
13
+ require "lokka/#{name}"
14
+ begin
15
+ plugee = ::Lokka.const_get(name.camelize)
16
+ register plugee
17
+ names << name
18
+ rescue => e
19
+ puts "plugin #{paths[2]} is identified as a suspect."
20
+ end
21
+ end
22
+
23
+ plugins = []
24
+ unless @routes['GET'].blank?
25
+ matchers = @routes['GET'].map(&:first)
26
+ names.map do |name|
27
+ OpenStruct.new(
28
+ :name => name,
29
+ :have_admin_page => matchers.any? {|m| m =~ "/admin/plugins/#{name}" })
30
+ end
31
+ end
32
+ set :plugins, plugins
33
+ end
34
+
35
+ configure do
36
+ enable :method_override, :raise_errors, :static, :sessions
37
+ disable :logging
38
+ set :root, File.expand_path('../../..', __FILE__)
39
+ set :public => Proc.new { File.join(root, 'public') }
40
+ set :views => Proc.new { public }
41
+ set :theme => Proc.new { File.join(public, 'theme') }
42
+ set :config => YAML.load(ERB.new(File.read("#{root}/config.yml")).result(binding))
43
+ set :supported_templates => %w(erb haml erubis)
44
+ set :per_page, 10
45
+ set :admin_per_page, 50
46
+ set :default_locale, 'en'
47
+ set :haml, :ugly => false, :attr_wrapper => '"'
48
+ register Sinatra::R18n
49
+ register Lokka::Before
50
+ helpers Sinatra::ContentFor
51
+ helpers Lokka::Helpers
52
+ use Rack::Flash
53
+ use Rack::Exceptional, ENV['EXCEPTIONAL_API_KEY'] || 'key' if ENV['RACK_ENV'] == 'production'
54
+
55
+ load_plugin
56
+ end
57
+
58
+ configure :production do
59
+ DataMapper.setup(:default, ENV['DATABASE_URL'] || config['production']['dsn'])
60
+ end
61
+
62
+ configure :development do
63
+ DataMapper.setup(:default, config['development']['dsn'])
64
+ end
65
+
66
+ get '/admin/' do
67
+ render_any :index
68
+ end
69
+
70
+ get '/admin/login' do
71
+ render_any :login, :layout => false
72
+ end
73
+
74
+ post '/admin/login' do
75
+ @user = User.authenticate(params[:name], params[:password])
76
+ if @user
77
+ session[:user] = @user.id
78
+ flash[:notice] = t.logged_in_successfully
79
+ if session[:return_to]
80
+ redirect_url = session[:return_to]
81
+ session[:return_to] = false
82
+ redirect redirect_url
83
+ else
84
+ redirect '/admin/'
85
+ end
86
+ else
87
+ @login_failed = true
88
+ render_any :login, :layout => false
89
+ end
90
+ end
91
+
92
+ get '/admin/logout' do
93
+ session[:user] = nil
94
+ redirect '/admin/login'
95
+ end
96
+
97
+ # posts
98
+ get '/admin/posts' do
99
+ @posts = Post.all(:order => :created_at.desc).
100
+ page(params[:page], :per_page => settings.admin_per_page)
101
+ render_any :'posts/index'
102
+ end
103
+
104
+ get '/admin/posts/new' do
105
+ @post = Post.new(:created_at => DateTime.now)
106
+ @categories = Category.all.map {|c| [c.id, c.title] }.unshift([nil, t.not_select])
107
+ render_any :'posts/new'
108
+ end
109
+
110
+ post '/admin/posts' do
111
+ @post = Post.new(params['post'])
112
+ @post.user = current_user
113
+ if @post.save
114
+ flash[:notice] = t.post_was_successfully_created
115
+ redirect '/admin/posts'
116
+ else
117
+ @categories = Category.all.map {|c| [c.id, c.title] }.unshift([nil, t.not_select])
118
+ render_any :'posts/new'
119
+ end
120
+ end
121
+
122
+ get '/admin/posts/:id/edit' do |id|
123
+ @post = Post.get(id)
124
+ @categories = Category.all.map {|c| [c.id, c.title] }.unshift([nil, t.not_select])
125
+ render_any :'posts/edit'
126
+ end
127
+
128
+ put '/admin/posts/:id' do |id|
129
+ @post = Post.get(id)
130
+ if @post.update(params['post'])
131
+ flash[:notice] = t.post_was_successfully_updated
132
+ redirect '/admin/posts'
133
+ else
134
+ @categories = Category.all.map {|c| [c.id, c.title] }.unshift([nil, t.not_select])
135
+ render_any :'posts/edit'
136
+ end
137
+ end
138
+
139
+ delete '/admin/posts/:id' do |id|
140
+ Post.get(id).destroy
141
+ flash[:notice] = t.post_was_successfully_deleted
142
+ redirect '/admin/posts'
143
+ end
144
+
145
+ # pages
146
+ get '/admin/pages' do
147
+ @pages = Page.all(:order => :created_at.desc).
148
+ page(params[:page], :per_page => settings.admin_per_page)
149
+ render_any :'pages/index'
150
+ end
151
+
152
+ get '/admin/pages/new' do
153
+ @page = Page.new(:created_at => DateTime.now)
154
+ @categories = Category.all.map {|c| [c.id, c.title] }.unshift([nil, t.not_select])
155
+ render_any :'pages/new'
156
+ end
157
+
158
+ post '/admin/pages' do
159
+ @page = Page.new(params['page'])
160
+ @page.user = current_user
161
+ if @page.save
162
+ flash[:notice] = t.page_was_successfully_created
163
+ redirect '/admin/pages'
164
+ else
165
+ @categories = Category.all.map {|c| [c.id, c.title] }.unshift([nil, t.not_select])
166
+ render_any :'pages/new'
167
+ end
168
+ end
169
+
170
+ get '/admin/pages/:id/edit' do |id|
171
+ @page = Page.get(id)
172
+ @categories = Category.all.map {|c| [c.id, c.title] }.unshift([nil, t.not_select])
173
+ render_any :'pages/edit'
174
+ end
175
+
176
+ put '/admin/pages/:id' do |id|
177
+ @page = Page.get(id)
178
+ if @page.update(params['page'])
179
+ flash[:notice] = t.page_was_successfully_updated
180
+ redirect '/admin/pages'
181
+ else
182
+ @categories = Category.all.map {|c| [c.id, c.title] }.unshift([nil, t.not_select])
183
+ render_any :'pages/edit'
184
+ end
185
+ end
186
+
187
+ delete '/admin/pages/:id' do |id|
188
+ Page.get(id).destroy
189
+ flash[:notice] = t.page_was_successfully_deleted
190
+ redirect '/admin/pages'
191
+ end
192
+
193
+ # comment
194
+ get '/admin/comments' do
195
+ @comments = Comment.all(:order => :created_at.desc).
196
+ page(params[:page], :per_page => settings.admin_per_page)
197
+ render_any :'comments/index'
198
+ end
199
+
200
+ get '/admin/comments/new' do
201
+ @comment = Comment.new(:created_at => DateTime.now)
202
+ @entries = Entry.all.map {|e| [e.id, e.title] }.unshift([nil, t.not_select])
203
+ render_any :'comments/new'
204
+ end
205
+
206
+ post '/admin/comments' do
207
+ @comment = Comment.new(params['comment'])
208
+ if @comment.save
209
+ flash[:notice] = t.comment_was_successfully_created
210
+ redirect '/admin/comments'
211
+ else
212
+ @entries = Entry.all.map {|e| [e.id, e.title] }.unshift([nil, t.not_select])
213
+ render_any :'comments/new'
214
+ end
215
+ end
216
+
217
+ get '/admin/comments/:id/edit' do |id|
218
+ @comment = Comment.get(id)
219
+ @entries = Entry.all.map {|e| [e.id, e.title] }.unshift([nil, t.not_select])
220
+ render_any :'comments/edit'
221
+ end
222
+
223
+ put '/admin/comments/:id' do |id|
224
+ @comment = Comment.get(id)
225
+ if @comment.update(params['comment'])
226
+ flash[:notice] = t.comment_was_successfully_updated
227
+ redirect '/admin/comments'
228
+ else
229
+ @entries = Entry.all.map {|e| [e.id, e.title] }.unshift([nil, t.not_select])
230
+ render_any :'comments/edit'
231
+ end
232
+ end
233
+
234
+ delete '/admin/comments/:id' do |id|
235
+ Comment.get(id).destroy
236
+ flash[:notice] = t.comment_was_successfully_deleted
237
+ redirect '/admin/comments'
238
+ end
239
+
240
+ # category
241
+ get '/admin/categories' do
242
+ @categories = Category.all.
243
+ page(params[:page], :per_page => settings.admin_per_page)
244
+ render_any :'categories/index'
245
+ end
246
+
247
+ get '/admin/categories/new' do
248
+ @category = Category.new
249
+ @categories = [nil, t.not_select] + Category.all.map {|c| [c.id, c.title] }
250
+ render_any :'categories/new'
251
+ end
252
+
253
+ post '/admin/categories' do
254
+ @category = Category.new(params['category'])
255
+ #@category.user = current_user
256
+ if @category.save
257
+ flash[:notice] = t.category_was_successfully_created
258
+ redirect '/admin/categories'
259
+ else
260
+ render_any :'categories/new'
261
+ end
262
+ end
263
+
264
+ get '/admin/categories/:id/edit' do |id|
265
+ @category = Category.get(id)
266
+ render_any :'categories/edit'
267
+ end
268
+
269
+ put '/admin/categories/:id' do |id|
270
+ @category = Category.get(id)
271
+ if @category.update(params['category'])
272
+ flash[:notice] = t.category_was_successfully_updated
273
+ redirect '/admin/categories'
274
+ else
275
+ render_any :'categories/edit'
276
+ end
277
+ end
278
+
279
+ delete '/admin/categories/:id' do |id|
280
+ Category.get(id).destroy
281
+ flash[:notice] = t.category_was_successfully_deleted
282
+ redirect '/admin/categories'
283
+ end
284
+
285
+ # tag
286
+ get '/admin/tags' do
287
+ @tags = Tag.all.
288
+ page(params[:page], :per_page => settings.admin_per_page)
289
+ render_any :'tags/index'
290
+ end
291
+
292
+ get '/admin/tags/:id/edit' do |id|
293
+ @tag = Tag.get(id)
294
+ render_any :'tags/edit'
295
+ end
296
+
297
+ put '/admin/tags/:id' do |id|
298
+ @tag = Tag.get(id)
299
+ if @tag.update(params['tag'])
300
+ flash[:notice] = t.tag_was_successfully_updated
301
+ redirect '/admin/tags'
302
+ else
303
+ render_any :'tags/edit'
304
+ end
305
+ end
306
+
307
+ delete '/admin/tags/:id' do |id|
308
+ Tag.get(id).destroy
309
+ flash[:notice] = t.tag_was_successfully_deleted
310
+ redirect '/admin/tags'
311
+ end
312
+
313
+ # users
314
+ get '/admin/users' do
315
+ @users = User.all(:order => :created_at.desc).
316
+ page(params[:page], :per_page => settings.admin_per_page)
317
+ render_any :'users/index'
318
+ end
319
+
320
+ get '/admin/users/new' do
321
+ @user = User.new
322
+ render_any :'users/new'
323
+ end
324
+
325
+ post '/admin/users' do
326
+ @user = User.new(params['user'])
327
+ if @user.save
328
+ flash[:notice] = t.user_was_successfully_created
329
+ redirect '/admin/users'
330
+ else
331
+ render_any :'users/new'
332
+ end
333
+ end
334
+
335
+ get '/admin/users/:id/edit' do |id|
336
+ @user = User.get(id)
337
+ render_any :'users/edit'
338
+ end
339
+
340
+ put '/admin/users/:id' do |id|
341
+ @user = User.get(id)
342
+ if @user.update(params['user'])
343
+ flash[:notice] = t.user_was_successfully_updated
344
+ redirect '/admin/users'
345
+ else
346
+ render_any :'users/edit'
347
+ end
348
+ end
349
+
350
+ delete '/admin/users/:id' do |id|
351
+ target_user = User.get(id)
352
+ if current_user == target_user
353
+ flash[:alert] = 'Can not delete your self.'
354
+ else
355
+ target_user.destroy
356
+ end
357
+ flash[:notice] = t.user_was_successfully_deleted
358
+ redirect '/admin/users'
359
+ end
360
+
361
+ # theme
362
+ get '/admin/themes' do
363
+ @themes =
364
+ Dir.glob("#{settings.theme}/*").map do |f|
365
+ title = f.split('/').last
366
+ s = Dir.glob("#{f}/screenshot.*")
367
+ screenshot = s.empty? ? nil : "/#{s.first.split('/')[-3, 3].join('/')}"
368
+ OpenStruct.new(:title => title, :screenshot => screenshot)
369
+ end
370
+ render_any :'themes/index'
371
+ end
372
+
373
+ put '/admin/themes' do
374
+ site = Site.first
375
+ site.update(:theme => params[:title])
376
+ flash[:notice] = t.theme_was_successfully_updated
377
+ redirect '/admin/themes'
378
+ end
379
+
380
+ # plugin
381
+ get '/admin/plugins' do
382
+ render_any :'plugins/index'
383
+ end
384
+
385
+ # site
386
+ get '/admin/site/edit' do
387
+ @site = Site.first
388
+ render_any :'site/edit'
389
+ end
390
+
391
+ put '/admin/site' do
392
+ if Site.first.update(params['site'])
393
+ flash[:notice] = t.site_was_successfully_updated
394
+ redirect '/admin/site/edit'
395
+ else
396
+ render_any :'site/edit'
397
+ end
398
+ end
399
+
400
+ # index
401
+ get '/' do
402
+ @theme_types << :index
403
+ @theme_types << :entries
404
+
405
+ @posts = Post.page(params[:page], :per_page => settings.per_page)
406
+
407
+ @bread_crumbs = BreadCrumb.new
408
+ @bread_crumbs.add('Home', '/')
409
+
410
+ render_detect :index, :entries
411
+ end
412
+
413
+ get '/index.atom' do
414
+ @posts = Post.page(params[:page], :per_page => settings.per_page)
415
+ content_type 'application/atom+xml', :charset => 'utf-8'
416
+ builder :'system/index'
417
+ end
418
+
419
+ # search
420
+ get '/search/' do
421
+ @theme_types << :search
422
+ @theme_types << :entries
423
+
424
+ @query = params[:query]
425
+ @posts = Post.search(@query).
426
+ page(params[:page], :per_page => settings.per_page)
427
+
428
+ @title = "Search by #{@query} - #{@site.title}"
429
+
430
+ @bread_crumbs = BreadCrumb.new
431
+ @bread_crumbs.add('Home', '/')
432
+ @bread_crumbs.add('Search', '/search/')
433
+
434
+ render_detect :search, :entries
435
+ end
436
+
437
+ # category
438
+ get '/category/*/' do |path|
439
+ @theme_types << :category
440
+ @theme_types << :entries
441
+
442
+ category_title = path.split('/').last
443
+ @category = Category.get_by_fuzzy_slug(category_title)
444
+ return 404 if @category.nil?
445
+ @posts = Post.all(:category => @category).
446
+ page(params[:page], :per_page => settings.per_page)
447
+
448
+ @title = "#{@category.title} - #{@site.title}"
449
+
450
+ @bread_crumbs = BreadCrumb.new
451
+ @bread_crumbs.add('Home', '/')
452
+ @category.ancestors.each do |cat|
453
+ @bread_crumbs.add(cat.name, cat.link)
454
+ end
455
+ @bread_crumbs.add(@category.title, @category.link)
456
+
457
+ render_detect :category, :entries
458
+ end
459
+
460
+ # tag
461
+ get '/tags/:tag/' do |tag|
462
+ @theme_types << :tag
463
+ @theme_types << :entries
464
+
465
+ @tag = Tag.first(:name => tag)
466
+ return 404 if @tag.nil?
467
+ @posts = Post.all(:id.in => @tag.taggings.map {|o| o.taggable_id }).
468
+ page(params[:page], :per_page => settings.per_page)
469
+ @title = "#{@tag.name} - #{@site.title}"
470
+
471
+ @bread_crumbs = BreadCrumb.new
472
+ @bread_crumbs.add('Home', '/')
473
+ @bread_crumbs.add(@tag.name, @tag.link)
474
+
475
+ render_detect :tag, :entries
476
+ end
477
+
478
+ # monthly
479
+ get %r{^/([\d]{4})/([\d]{2})/$} do |year, month|
480
+ @theme_types << :monthly
481
+ @theme_types << :entries
482
+
483
+ year, month = year.to_i, month.to_i
484
+ @posts = Post.all(:created_at.gte => DateTime.new(year, month)).
485
+ all(:created_at.lt => DateTime.new(year, month) >> 1).
486
+ page(params[:page], :per_page => settings.per_page)
487
+
488
+ @title = "#{year}/#{month} - #{@site.title}"
489
+
490
+ @bread_crumbs = BreadCrumb.new
491
+ @bread_crumbs.add('Home', '/')
492
+ @bread_crumbs.add("#{year}", "/#{year}/")
493
+ @bread_crumbs.add("#{year}/#{month}", "/#{year}/#{month}/")
494
+
495
+ render_detect :monthly, :entries
496
+ end
497
+
498
+ # yearly
499
+ get %r{^/([\d]{4})/$} do |year|
500
+ @theme_types << :yearly
501
+ @theme_types << :entries
502
+
503
+ year = year.to_i
504
+ @posts = Post.all(:created_at.gte => DateTime.new(year)).
505
+ all(:created_at.lt => DateTime.new(year + 1)).
506
+ page(params[:page], :per_page => settings.per_page)
507
+
508
+ @title = "#{year} - #{@site.title}"
509
+
510
+ @bread_crumbs = BreadCrumb.new
511
+ @bread_crumbs.add('Home', '/')
512
+ @bread_crumbs.add("#{year}", "/#{year}/")
513
+
514
+ render_detect :yearly, :entries
515
+ end
516
+
517
+ # entry
518
+ get %r{^/([0-9a-zA-Z-]+)$} do |id_or_slug|
519
+ @theme_types << :entry
520
+
521
+ @entry = Entry.get_by_fuzzy_slug(id_or_slug)
522
+ return 404 if @entry.blank?
523
+
524
+ @title = "#{@entry.title} - #{@site.title}"
525
+
526
+ @bread_crumbs = BreadCrumb.new
527
+ @bread_crumbs.add('Home', '/')
528
+ if @entry.category
529
+ @entry.category.ancestors.each do |cat|
530
+ @bread_crumbs.add(cat.name, cat.link)
531
+ end
532
+ @bread_crumbs.add(@entry.category.title, @entry.category.link)
533
+ end
534
+ @bread_crumbs.add(@entry.title, @entry.link)
535
+
536
+ render_any :entry
537
+ end
538
+
539
+ # comment
540
+ post %r{^/([0-9a-zA-Z-]+)$} do |id_or_slug|
541
+ @theme_types << :entry
542
+
543
+ @entry = Entry.get_by_fuzzy_slug(id_or_slug)
544
+ return 404 if @entry.blank?
545
+
546
+ @comment = @entry.comments.new(params['comment'])
547
+ if @comment.save
548
+ redirect @entry.link
549
+ else
550
+ render_any :entry
551
+ end
552
+ end
553
+
554
+ not_found do
555
+ haml :'system/404', :layout => false
556
+ end
557
+
558
+ error do
559
+ 'Error: ' + env['sinatra.error'].name
560
+ end
561
+ end
562
+ end