schnitzelpress 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/CHANGES.md +20 -3
  2. data/README.md +4 -2
  3. data/bin/schnitzelpress +1 -1
  4. data/lib/assets/js/jquery-1.7.1.js +673 -0
  5. data/lib/assets/js/jquery-ujs.js +373 -0
  6. data/lib/assets/js/jquery.cookie.js +47 -0
  7. data/lib/{public → assets}/js/schnitzelpress.js +7 -2
  8. data/lib/public/font/fontawesome-webfont.eot +0 -0
  9. data/lib/public/font/fontawesome-webfont.svg +175 -0
  10. data/lib/public/font/fontawesome-webfont.svgz +0 -0
  11. data/lib/public/font/fontawesome-webfont.ttf +0 -0
  12. data/lib/public/font/fontawesome-webfont.woff +0 -0
  13. data/lib/schnitzelpress.rb +21 -5
  14. data/lib/schnitzelpress/actions/admin.rb +21 -1
  15. data/lib/schnitzelpress/actions/assets.rb +36 -0
  16. data/lib/schnitzelpress/actions/auth.rb +16 -3
  17. data/lib/schnitzelpress/actions/blog.rb +10 -12
  18. data/lib/schnitzelpress/app.rb +16 -19
  19. data/lib/schnitzelpress/cache_control.rb +17 -0
  20. data/lib/schnitzelpress/cli.rb +40 -9
  21. data/lib/schnitzelpress/config.rb +43 -0
  22. data/lib/schnitzelpress/env.rb +5 -0
  23. data/lib/schnitzelpress/helpers.rb +168 -4
  24. data/lib/schnitzelpress/markdown_renderer.rb +2 -2
  25. data/lib/schnitzelpress/post.rb +2 -6
  26. data/lib/schnitzelpress/static.rb +1 -1
  27. data/lib/schnitzelpress/version.rb +2 -2
  28. data/lib/templates/new_blog/Gemfile +4 -5
  29. data/lib/templates/new_blog/Gemfile.lock.tt +137 -0
  30. data/lib/templates/new_blog/Procfile +1 -1
  31. data/lib/templates/new_blog/config.ru.tt +6 -17
  32. data/lib/views/admin/admin.haml +3 -2
  33. data/lib/views/admin/config.haml +27 -0
  34. data/lib/views/atom.haml +3 -3
  35. data/lib/views/index.haml +1 -1
  36. data/lib/views/layout.haml +15 -11
  37. data/lib/views/login.haml +4 -0
  38. data/lib/views/partials/_admin_post_list.haml +8 -8
  39. data/lib/views/partials/_disqus.haml +1 -1
  40. data/lib/views/partials/_gauges.haml +1 -1
  41. data/lib/views/partials/_google_analytics.haml +1 -1
  42. data/lib/views/partials/_post.haml +6 -5
  43. data/lib/views/partials/_post_form.haml +3 -1
  44. data/lib/views/post.haml +4 -1
  45. data/lib/views/schnitzelpress.scss +67 -3
  46. data/schnitzelpress.gemspec +5 -2
  47. data/spec/app_spec.rb +5 -11
  48. data/spec/assets_spec.rb +26 -0
  49. data/spec/factories.rb +1 -1
  50. data/spec/post_spec.rb +9 -2
  51. data/spec/spec_helper.rb +2 -1
  52. metadata +115 -71
  53. data/lib/schnitzelpress/rake.rb +0 -20
  54. data/lib/templates/new_blog/Rakefile +0 -2
  55. data/lib/templates/new_blog/app.rb.tt +0 -34
  56. data/lib/templates/new_blog/config/unicorn.rb +0 -5
  57. data/lib/templates/new_blog/public/.gitkeep +0 -0
@@ -1,4 +1,4 @@
1
- module SchnitzelPress
1
+ module Schnitzelpress
2
2
  module Helpers
3
3
  def h(*args)
4
4
  escape_html(*args)
@@ -21,6 +21,10 @@ module SchnitzelPress
21
21
  haml :"partials/_#{name}", :locals => { name.to_sym => thing }.merge(locals)
22
22
  end
23
23
 
24
+ def config
25
+ Schnitzelpress::Config.instance
26
+ end
27
+
24
28
  def set_page_title(title)
25
29
  @page_title = title
26
30
  end
@@ -32,7 +36,7 @@ module SchnitzelPress
32
36
  end
33
37
 
34
38
  def show_disqus?
35
- settings.disqus_name.present?
39
+ config.disqus_id.present?
36
40
  end
37
41
 
38
42
  def production?
@@ -44,7 +48,7 @@ module SchnitzelPress
44
48
  end
45
49
 
46
50
  def admin_logged_in?
47
- user_logged_in? && session[:auth] == settings.administrator
51
+ user_logged_in? && (session[:auth][:uid] == ENV['SCHNITZELPRESS_OWNER'])
48
52
  end
49
53
 
50
54
  def admin_only!
@@ -53,7 +57,7 @@ module SchnitzelPress
53
57
 
54
58
  def form_field(object, attribute, options = {})
55
59
  options = {
56
- :label => attribute.to_s.humanize,
60
+ :label => attribute.to_s.humanize.titleize,
57
61
  :value => object.send(attribute),
58
62
  :errors => object.errors[attribute.to_sym],
59
63
  :class_name => object.class.to_s.demodulize.underscore
@@ -73,5 +77,165 @@ module SchnitzelPress
73
77
 
74
78
  partial 'form_field', :object => object, :attribute => attribute, :options => options
75
79
  end
80
+
81
+ def icon(name)
82
+ map = {
83
+ 'glass' => 'f000',
84
+ 'music' => 'f001',
85
+ 'search' => 'f002',
86
+ 'envelope' => 'f003',
87
+ 'heart' => 'f004',
88
+ 'star' => 'f005',
89
+ 'star-empty' => 'f006',
90
+ 'user' => 'f007',
91
+ 'film' => 'f008',
92
+ 'th-large' => 'f009',
93
+ 'th' => 'f00a',
94
+ 'th-list' => 'f00b',
95
+ 'ok' => 'f00c',
96
+ 'remove' => 'f00d',
97
+ 'zoom-in' => 'f00e',
98
+ 'zoom-out' => 'f010',
99
+ 'off' => 'f011',
100
+ 'signal' => 'f012',
101
+ 'cog' => 'f013',
102
+ 'trash' => 'f014',
103
+ 'home' => 'f015',
104
+ 'file' => 'f016',
105
+ 'time' => 'f017',
106
+ 'road' => 'f018',
107
+ 'download-alt' => 'f019',
108
+ 'download' => 'f01a',
109
+ 'upload' => 'f01b',
110
+ 'inbox' => 'f01c',
111
+ 'play-circle' => 'f01d',
112
+ 'repeat' => 'f01e',
113
+ 'refresh' => 'f021',
114
+ 'list-alt' => 'f022',
115
+ 'lock' => 'f023',
116
+ 'flag' => 'f024',
117
+ 'headphones' => 'f025',
118
+ 'volume-off' => 'f026',
119
+ 'volume-down' => 'f027',
120
+ 'volume-up' => 'f028',
121
+ 'qrcode' => 'f029',
122
+ 'barcode' => 'f02a',
123
+ 'tag' => 'f02b',
124
+ 'tags' => 'f02c',
125
+ 'book' => 'f02d',
126
+ 'bookmark' => 'f02e',
127
+ 'print' => 'f02f',
128
+ 'camera' => 'f030',
129
+ 'font' => 'f031',
130
+ 'bold' => 'f032',
131
+ 'italic' => 'f033',
132
+ 'text-height' => 'f034',
133
+ 'text-width' => 'f035',
134
+ 'align-left' => 'f036',
135
+ 'align-center' => 'f037',
136
+ 'align-right' => 'f038',
137
+ 'align-justify' => 'f039',
138
+ 'list' => 'f03a',
139
+ 'indent-left' => 'f03b',
140
+ 'indent-right' => 'f03c',
141
+ 'facetime-video' => 'f03d',
142
+ 'picture' => 'f03e',
143
+ 'pencil' => 'f040',
144
+ 'map-marker' => 'f041',
145
+ 'adjust' => 'f042',
146
+ 'tint' => 'f043',
147
+ 'edit' => 'f044',
148
+ 'share' => 'f045',
149
+ 'check' => 'f046',
150
+ 'move' => 'f047',
151
+ 'step-backward' => 'f048',
152
+ 'fast-backward' => 'f049',
153
+ 'backward' => 'f04a',
154
+ 'play' => 'f04b',
155
+ 'pause' => 'f04c',
156
+ 'stop' => 'f04d',
157
+ 'forward' => 'f04e',
158
+ 'fast-forward' => 'f050',
159
+ 'step-forward' => 'f051',
160
+ 'eject' => 'f052',
161
+ 'chevron-left' => 'f053',
162
+ 'chevron-right' => 'f054',
163
+ 'plus-sign' => 'f055',
164
+ 'minus-sign' => 'f056',
165
+ 'remove-sign' => 'f057',
166
+ 'ok-sign' => 'f058',
167
+ 'question-sign' => 'f059',
168
+ 'info-sign' => 'f05a',
169
+ 'screenshot' => 'f05b',
170
+ 'remove-circle' => 'f05c',
171
+ 'ok-circle' => 'f05d',
172
+ 'ban-circle' => 'f05e',
173
+ 'arrow-left' => 'f060',
174
+ 'arrow-right' => 'f061',
175
+ 'arrow-up' => 'f062',
176
+ 'arrow-down' => 'f063',
177
+ 'share-alt' => 'f064',
178
+ 'resize-full' => 'f065',
179
+ 'resize-small' => 'f066',
180
+ 'plus' => 'f067',
181
+ 'minus' => 'f068',
182
+ 'asterisk' => 'f069',
183
+ 'exclamation-sign' => 'f06a',
184
+ 'gift' => 'f06b',
185
+ 'leaf' => 'f06c',
186
+ 'fire' => 'f06d',
187
+ 'eye-open' => 'f06e',
188
+ 'eye-close' => 'f070',
189
+ 'warning-sign' => 'f071',
190
+ 'plane' => 'f072',
191
+ 'calendar' => 'f073',
192
+ 'random' => 'f074',
193
+ 'comment' => 'f075',
194
+ 'magnet' => 'f076',
195
+ 'chevron-up' => 'f077',
196
+ 'chevron-down' => 'f078',
197
+ 'retweet' => 'f079',
198
+ 'shopping-cart' => 'f07a',
199
+ 'folder-close' => 'f07b',
200
+ 'folder-open' => 'f07c',
201
+ 'resize-vertical' => 'f07d',
202
+ 'resize-horizontal' => 'f07e',
203
+ 'bar-chart' => 'f080',
204
+ 'twitter-sign' => 'f081',
205
+ 'facebook-sign' => 'f082',
206
+ 'camera-retro' => 'f083',
207
+ 'key' => 'f084',
208
+ 'cogs' => 'f085',
209
+ 'comments' => 'f086',
210
+ 'thumbs-up' => 'f087',
211
+ 'thumbs-down' => 'f088',
212
+ 'star-half' => 'f089',
213
+ 'heart-empty' => 'f08a',
214
+ 'signout' => 'f08b',
215
+ 'linkedin-sign' => 'f08c',
216
+ 'pushpin' => 'f08d',
217
+ 'external-link' => 'f08e',
218
+ 'signin' => 'f090',
219
+ 'trophy' => 'f091',
220
+ 'github-sign' => 'f092',
221
+ 'upload-alt' => 'f093',
222
+ 'lemon' => 'f094'
223
+ }
224
+
225
+ char = map[name.to_s] || 'f06a'
226
+
227
+ "<span class=\"font-awesome\">&#x#{char};</span>"
228
+ end
229
+
230
+ def link_to(title, target = "", options = {})
231
+ options[:href] = target.respond_to?(:to_url) ? target.to_url : target
232
+ options[:data] ||= {}
233
+ [:method, :confirm].each { |a| options[:data][a] = options.delete(a) }
234
+ haml "%a#{options} #{title}"
235
+ end
236
+
237
+ def link_to_delete_post(title, post)
238
+ link_to title, "/admin/edit/#{post.id}", :method => :delete, :confirm => "Are you sure? This can not be undone."
239
+ end
76
240
  end
77
241
  end
@@ -1,4 +1,4 @@
1
- module SchnitzelPress
1
+ module Schnitzelpress
2
2
  class MarkdownRenderer < Redcarpet::Render::HTML
3
3
  include Redcarpet::Render::SmartyPants
4
4
 
@@ -8,7 +8,7 @@ module SchnitzelPress
8
8
 
9
9
  def image(link, title, alt_text)
10
10
  oembed = OEmbed::Providers.get(link)
11
- %q(<div class="embedded %s">%s</div>) % [oembed.type, oembed.html]
11
+ %q(<div class="embedded %s %s">%s</div>) % [oembed.type, oembed.provider_name.parameterize, oembed.html]
12
12
  rescue OEmbed::NotFound
13
13
  %q(<img src="%s" title="%s" alt="%s"/>) % [link, escape_html(title), escape_html(alt_text)]
14
14
  end
@@ -7,7 +7,7 @@ SoundCloudProvider = OEmbed::Provider.new("http://soundcloud.com/oembed", :json)
7
7
  SoundCloudProvider << "http://*.soundcloud.com/*"
8
8
  OEmbed::Providers.register(SoundCloudProvider)
9
9
 
10
- module SchnitzelPress
10
+ module Schnitzelpress
11
11
  class Post
12
12
  include Mongoid::Document
13
13
  include Mongoid::Timestamps
@@ -170,14 +170,10 @@ module SchnitzelPress
170
170
  if home_page?
171
171
  '/'
172
172
  else
173
- published_at.present? ? "/#{year}/#{month}/#{day}/#{slug}/" : "/#{slug}/"
173
+ published_at.present? ? "/#{sprintf '%04d', year}/#{sprintf '%02d', month}/#{sprintf '%02d', day}/#{slug}/" : "/#{slug}/"
174
174
  end
175
175
  end
176
176
 
177
- def to_etag
178
- Digest::MD5.hexdigest("-#{id}-#{updated_at}-")
179
- end
180
-
181
177
  def disqus?
182
178
  disqus && published?
183
179
  end
@@ -1,4 +1,4 @@
1
- module SchnitzelPress
1
+ module Schnitzelpress
2
2
  class Static
3
3
  def initialize(app, public_dir = './public')
4
4
  @file = Rack::File.new(public_dir)
@@ -1,3 +1,3 @@
1
- module SchnitzelPress
2
- VERSION = "0.1.1"
1
+ module Schnitzelpress
2
+ VERSION = "0.2.0"
3
3
  end
@@ -1,10 +1,9 @@
1
- source 'https://rubygems.org'
1
+ source :rubygems
2
2
 
3
3
  gem 'unicorn', '~> 4.2.0'
4
- gem 'rack-cache', '~> 1.1.0', :require => 'rack/cache'
5
- gem 'schnitzelpress', '~> 0.1.0'
4
+ gem 'schnitzelpress', :git => 'git://github.com/hmans/schnitzelpress.git'
6
5
 
7
6
  group :development do
8
- gem 'shotgun', '~> 0.9.0'
9
- gem 'heroku', '~> 2.20.0'
7
+ gem 'shotgun'
8
+ gem 'heroku'
10
9
  end
@@ -0,0 +1,137 @@
1
+ GIT
2
+ remote: git://github.com/hmans/schnitzelpress.git
3
+ revision: 979750e4f9b8a53b6a751b6e999ab46348b9e02e
4
+ specs:
5
+ schnitzelpress (0.2.0)
6
+ activesupport (~> 3.2.0)
7
+ bson_ext (~> 1.5.0)
8
+ chronic (~> 0.6.7)
9
+ coderay (~> 1.0.5)
10
+ haml (~> 3.1.4)
11
+ i18n (~> 0.6.0)
12
+ mongo (~> 1.5.2)
13
+ mongoid (~> 2.4.0)
14
+ omniauth (~> 1.0.2)
15
+ omniauth-browserid (~> 0.0.1)
16
+ packr (~> 3.1.1)
17
+ pry (~> 0.9.8)
18
+ rack (~> 1.4.1)
19
+ rack-cache (~> 1.1.0)
20
+ rack-contrib (~> 1.1.0)
21
+ rake (~> 0.9.2.2)
22
+ redcarpet (~> 2.1.0)
23
+ ruby-oembed (~> 0.8.5)
24
+ sass (~> 3.1.15)
25
+ schnitzelstyle (~> 0.1.1)
26
+ sinatra (~> 1.3.2)
27
+ sinatra-contrib (~> 1.3.1)
28
+ thor (~> 0.14.6)
29
+ tilt (~> 1.3.0)
30
+
31
+ GEM
32
+ remote: http://rubygems.org/
33
+ specs:
34
+ activemodel (3.2.3)
35
+ activesupport (= 3.2.3)
36
+ builder (~> 3.0.0)
37
+ activesupport (3.2.3)
38
+ i18n (~> 0.6)
39
+ multi_json (~> 1.0)
40
+ addressable (2.2.7)
41
+ backports (2.5.1)
42
+ bson (1.5.2)
43
+ bson_ext (1.5.2)
44
+ bson (= 1.5.2)
45
+ builder (3.0.0)
46
+ chronic (0.6.7)
47
+ coderay (1.0.5)
48
+ eventmachine (0.12.10)
49
+ faraday (0.7.6)
50
+ addressable (~> 2.2)
51
+ multipart-post (~> 1.1)
52
+ rack (~> 1.1)
53
+ haml (3.1.4)
54
+ hashie (1.2.0)
55
+ heroku (2.23.0)
56
+ launchy (>= 0.3.2)
57
+ netrc (~> 0.7.1)
58
+ rest-client (~> 1.6.1)
59
+ rubyzip
60
+ i18n (0.6.0)
61
+ kgio (2.7.4)
62
+ launchy (2.1.0)
63
+ addressable (~> 2.2.6)
64
+ method_source (0.7.1)
65
+ mime-types (1.18)
66
+ mongo (1.5.2)
67
+ bson (= 1.5.2)
68
+ mongoid (2.4.7)
69
+ activemodel (~> 3.1)
70
+ mongo (~> 1.3)
71
+ tzinfo (~> 0.3.22)
72
+ multi_json (1.2.0)
73
+ multipart-post (1.1.5)
74
+ netrc (0.7.1)
75
+ omniauth (1.0.3)
76
+ hashie (~> 1.2)
77
+ rack
78
+ omniauth-browserid (0.0.1)
79
+ faraday
80
+ multi_json
81
+ omniauth (~> 1.0)
82
+ oyster (0.9.5)
83
+ packr (3.1.1)
84
+ oyster (>= 0.9.5)
85
+ pry (0.9.8.4)
86
+ coderay (~> 1.0.5)
87
+ method_source (~> 0.7.1)
88
+ slop (>= 2.4.4, < 3)
89
+ rack (1.4.1)
90
+ rack-cache (1.1)
91
+ rack (>= 0.4)
92
+ rack-contrib (1.1.0)
93
+ rack (>= 0.9.1)
94
+ rack-protection (1.2.0)
95
+ rack
96
+ rack-test (0.6.1)
97
+ rack (>= 1.0)
98
+ raindrops (0.8.0)
99
+ rake (0.9.2.2)
100
+ redcarpet (2.1.1)
101
+ rest-client (1.6.7)
102
+ mime-types (>= 1.16)
103
+ ruby-oembed (0.8.7)
104
+ rubyzip (0.9.6.1)
105
+ sass (3.1.15)
106
+ schnitzelstyle (0.1.2)
107
+ sass
108
+ shotgun (0.9)
109
+ rack (>= 1.0)
110
+ sinatra (1.3.2)
111
+ rack (~> 1.3, >= 1.3.6)
112
+ rack-protection (~> 1.2)
113
+ tilt (~> 1.3, >= 1.3.3)
114
+ sinatra-contrib (1.3.1)
115
+ backports (>= 2.0)
116
+ eventmachine
117
+ rack-protection
118
+ rack-test
119
+ sinatra (~> 1.3.0)
120
+ tilt (~> 1.3)
121
+ slop (2.4.4)
122
+ thor (0.14.6)
123
+ tilt (1.3.3)
124
+ tzinfo (0.3.32)
125
+ unicorn (4.2.1)
126
+ kgio (~> 2.6)
127
+ rack
128
+ raindrops (~> 0.7)
129
+
130
+ PLATFORMS
131
+ ruby
132
+
133
+ DEPENDENCIES
134
+ heroku
135
+ schnitzelpress!
136
+ shotgun
137
+ unicorn (~> 4.2.0)
@@ -1 +1 @@
1
- web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
1
+ web: echo "worker_processes 4 ; timeout 30" | bundle exec unicorn -p $PORT -c /dev/stdin
@@ -1,18 +1,7 @@
1
- $stdout.sync = true
2
- require File.expand_path("../app.rb", __FILE__)
3
-
4
- # Add some caching. This is designed to work out of the box
5
- # on Heroku, but feel free to change this if eg. you'd prefer
6
- # to use Memcache.
7
- #
8
- if SchnitzelPress.env.production?
9
- use Rack::Cache, {
10
- :verbose => true,
11
- :metastore => URI.encode("file:/tmp/cache/meta"),
12
- :entitystore => URI.encode("file:/tmp/cache/body")
13
- }
14
- end
1
+ # encoding: UTF-8
2
+ require 'rubygems'
3
+ require 'bundler'
4
+ Bundler.require
15
5
 
16
- # Run the app, with support for files in ./public/
17
- #
18
- run App.with_local_files
6
+ $stdout.sync = true
7
+ run Schnitzelpress.omnomnom!
@@ -1,10 +1,11 @@
1
1
  %section
2
- %h1 Administration
2
+ %h1 #{icon 'cog'} Administration
3
3
  %p
4
4
  You're logged in as #{session[:auth][:uid]}.
5
5
  %ul.admin
6
6
  %li
7
- %a.green.button{:href => '/admin/new'} Create new Post
7
+ %a.green.button{:href => '/admin/new'} Create new Post or Page
8
+ %a.blue.button{:href => '/admin/config'} Configuration
8
9
  %a.red.button{:href => '/logout'} Logout
9
10
 
10
11
  = partial "admin_post_list", :posts => @drafts, :title => "Drafts"