schnitzelpress 0.1.1 → 0.2.0

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 (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"