lokka 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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