cartoonist 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. data/app/assets/stylesheets/admin.css.scss +2 -0
  2. data/app/controllers/{accounts_controller.rb → admin/accounts_controller.rb} +4 -4
  3. data/app/controllers/{cache_controller.rb → admin/cache_controller.rb} +6 -6
  4. data/app/controllers/{settings_controller.rb → admin/settings_controller.rb} +11 -6
  5. data/app/controllers/{static_cache_controller.rb → admin/static_cache_controller.rb} +3 -3
  6. data/app/controllers/admin_controller.rb +7 -33
  7. data/app/controllers/cartoonist_controller.rb +1 -1
  8. data/app/helpers/{cache_helper.rb → admin/cache_helper.rb} +1 -1
  9. data/app/helpers/admin/settings_helper.rb +17 -0
  10. data/app/models/entity.rb +104 -0
  11. data/app/models/postable.rb +59 -0
  12. data/app/models/setting.rb +70 -26
  13. data/app/models/simple_template.rb +2 -0
  14. data/app/views/{accounts → admin/accounts}/edit.html.erb +1 -1
  15. data/app/views/{accounts → admin/accounts}/index.html.erb +3 -3
  16. data/app/views/{accounts → admin/accounts}/new.html.erb +1 -1
  17. data/app/views/{accounts → admin/accounts}/show.html.erb +1 -1
  18. data/app/views/{cache → admin/cache}/index.html.erb +5 -5
  19. data/app/views/{settings → admin/settings}/initial_setup.html.erb +1 -1
  20. data/app/views/{settings → admin/settings}/show.html.erb +18 -6
  21. data/app/views/{static_cache → admin/static_cache}/index.html.erb +2 -2
  22. data/app/views/layouts/admin.html.erb +2 -2
  23. data/app/views/layouts/admin/accounts.html.erb +8 -0
  24. data/app/views/layouts/{initial_setup.html.erb → admin/initial_setup.html.erb} +0 -0
  25. data/app/views/layouts/general_admin.html.erb +3 -3
  26. data/cartoonist.gemspec +0 -1
  27. data/config/locales/en.yml +0 -11
  28. data/lib/cartoonist.rb +47 -1
  29. data/lib/cartoonist/engine.rb +75 -91
  30. metadata +28 -37
  31. data/app/models/tweetable.rb +0 -17
  32. data/app/views/layouts/accounts.html.erb +0 -8
@@ -1,3 +1,5 @@
1
+ .message { color: red; }
2
+
1
3
  form.inline { display: inline-block; }
2
4
 
3
5
  table {
@@ -1,4 +1,4 @@
1
- class AccountsController < CartoonistController
1
+ class Admin::AccountsController < CartoonistController
2
2
  before_filter :ensure_ssl!
3
3
  before_filter :check_admin!
4
4
 
@@ -8,7 +8,7 @@ class AccountsController < CartoonistController
8
8
 
9
9
  def create
10
10
  user = User.create_user params
11
- redirect_to "/accounts"
11
+ redirect_to "/admin/accounts"
12
12
  end
13
13
 
14
14
  def show
@@ -21,12 +21,12 @@ class AccountsController < CartoonistController
21
21
 
22
22
  def update
23
23
  user = User.update_user params
24
- redirect_to "/accounts/#{user.id}"
24
+ redirect_to "/admin/accounts/#{user.id}"
25
25
  end
26
26
 
27
27
  def destroy
28
28
  raise "Cannot destroy yourself!" if current_user.id == params[:id].to_i
29
29
  User.delete_user params
30
- redirect_to "/accounts"
30
+ redirect_to "/admin/accounts"
31
31
  end
32
32
  end
@@ -1,4 +1,4 @@
1
- class CacheController < CartoonistController
1
+ class Admin::CacheController < CartoonistController
2
2
  before_filter :ensure_ssl!
3
3
  before_filter :check_admin!
4
4
  layout "general_admin"
@@ -9,26 +9,26 @@ class CacheController < CartoonistController
9
9
 
10
10
  def destroy
11
11
  PageCache.find(params[:id]).expire!
12
- redirect_to "/cache"
12
+ redirect_to "/admin/cache"
13
13
  end
14
14
 
15
15
  def expire_www
16
16
  PageCache.expire_www!
17
- redirect_to "/cache"
17
+ redirect_to "/admin/cache"
18
18
  end
19
19
 
20
20
  def expire_m
21
21
  PageCache.expire_m!
22
- redirect_to "/cache"
22
+ redirect_to "/admin/cache"
23
23
  end
24
24
 
25
25
  def expire_tmp
26
26
  PageCache.expire_tmp!
27
- redirect_to "/cache"
27
+ redirect_to "/admin/cache"
28
28
  end
29
29
 
30
30
  def expire_all
31
31
  PageCache.expire_all!
32
- redirect_to "/cache"
32
+ redirect_to "/admin/cache"
33
33
  end
34
34
  end
@@ -1,9 +1,9 @@
1
- class SettingsController < CartoonistController
1
+ class Admin::SettingsController < CartoonistController
2
2
  before_filter :ensure_ssl!
3
3
  before_filter :check_admin!, :except => [:initial_setup, :save_initial_setup]
4
4
 
5
5
  def index
6
- redirect_to "/settings/general"
6
+ redirect_to "/admin/settings/general"
7
7
  end
8
8
 
9
9
  def show
@@ -13,15 +13,20 @@ class SettingsController < CartoonistController
13
13
 
14
14
  def update
15
15
  params[:included_settings].each do |setting|
16
- Setting[setting] = params[setting]
16
+ begin
17
+ Setting[setting] = params[setting]
18
+ rescue Setting::InvalidError => e
19
+ flash[:update_errors] ||= []
20
+ flash[:update_errors] << e.message
21
+ end
17
22
  end
18
23
 
19
- redirect_to "/settings/#{params[:id]}"
24
+ redirect_to "/admin/settings/#{params[:id]}"
20
25
  end
21
26
 
22
27
  def initial_setup
23
28
  return redirect_to "/admin" unless initial_setup_required?
24
- render :layout => "initial_setup"
29
+ render :layout => "admin/initial_setup"
25
30
  end
26
31
 
27
32
  def save_initial_setup
@@ -29,7 +34,7 @@ class SettingsController < CartoonistController
29
34
 
30
35
  if params[:admin_password] != params[:admin_confirm_password]
31
36
  flash[:error] = t "settings.initial_setup.passwords_dont_match"
32
- return redirect_to "/settings/initial_setup"
37
+ return redirect_to "/admin/settings/initial_setup"
33
38
  end
34
39
 
35
40
  Setting[:copyright_starting_year] = Date.today.strftime("%Y").to_i
@@ -1,4 +1,4 @@
1
- class StaticCacheController < CartoonistController
1
+ class Admin::StaticCacheController < CartoonistController
2
2
  before_filter :ensure_ssl!
3
3
  before_filter :check_admin!
4
4
  layout "general_admin"
@@ -9,11 +9,11 @@ class StaticCacheController < CartoonistController
9
9
 
10
10
  def destroy
11
11
  StaticCache.find(params[:id]).expire!
12
- redirect_to "/static_cache"
12
+ redirect_to "/admin/static_cache"
13
13
  end
14
14
 
15
15
  def expire_all
16
16
  StaticCache.expire_all!
17
- redirect_to "/static_cache"
17
+ redirect_to "/admin/static_cache"
18
18
  end
19
19
  end
@@ -1,8 +1,8 @@
1
1
  class AdminController < CartoonistController
2
- before_filter :ensure_ssl!, :except => [:cache_cron, :tweet_cron]
3
- before_filter :check_admin!, :except => [:cache_cron, :tweet_cron]
2
+ before_filter :ensure_ssl!, :except => [:cron]
3
+ before_filter :check_admin!, :except => [:cron]
4
4
 
5
- def index
5
+ def show
6
6
  redirect_to "/admin/main"
7
7
  end
8
8
 
@@ -32,37 +32,11 @@ class AdminController < CartoonistController
32
32
  render :layout => "general_admin"
33
33
  end
34
34
 
35
- def cache_cron
36
- Dir.glob(File.join(Rails.root, "public/cache/**/*.tmp.html*"), File::FNM_DOTMATCH).each do |file|
37
- if 2.hours.ago > File.mtime(file)
38
- File.delete file
39
- end
40
- end
41
-
35
+ def cron
36
+ Cartoonist::Cron.all.each &:call
42
37
  render :text => "Success.", :layout => false
43
- rescue
44
- render :text => "Failure.", :layout => false
45
- end
46
-
47
- def tweet_cron
48
- messages = []
49
-
50
- Comic.untweeted.each do |comic|
51
- comic.tweet!
52
- messages << "Comic: #{comic.tweet}"
53
- end
54
-
55
- BlogPost.untweeted.each do |post|
56
- post.tweet!
57
- messages << "Blog Post: #{post.tweet}"
58
- end
59
-
60
- unless Rails.env.production?
61
- content = "#{messages.join "\n"}\n"
62
- end
63
-
64
- render :text => "#{content}Success.", :layout => false
65
- rescue
38
+ rescue => e
39
+ logger.error "Failure running cron: #{e}\n #{e.backtrace.join "\n "}"
66
40
  render :text => "Failure.", :layout => false
67
41
  end
68
42
  end
@@ -15,7 +15,7 @@ class CartoonistController < ActionController::Base
15
15
 
16
16
  def check_admin!
17
17
  if initial_setup_required?
18
- redirect_to "/settings/initial_setup"
18
+ redirect_to "/admin/settings/initial_setup"
19
19
  else
20
20
  authenticate_user!
21
21
  end
@@ -1,4 +1,4 @@
1
- module CacheHelper
1
+ module Admin::CacheHelper
2
2
  def td_cache_class(test)
3
3
  if test
4
4
  "cached"
@@ -0,0 +1,17 @@
1
+ module Admin::SettingsHelper
2
+ def setting_select_value(option)
3
+ if option.kind_of? Hash
4
+ option[:value]
5
+ else
6
+ option
7
+ end
8
+ end
9
+
10
+ def setting_select_label(option)
11
+ if option.kind_of? Hash
12
+ t option[:label]
13
+ else
14
+ option
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,104 @@
1
+ module Entity
2
+ def entity_type
3
+ self.class.entity_type
4
+ end
5
+
6
+ def entity_label
7
+ self.class.entity_label
8
+ end
9
+
10
+ def entity_localized_label
11
+ self.class.entity_localized_label
12
+ end
13
+
14
+ def entity_description
15
+ self.class.entity_description.call self
16
+ end
17
+
18
+ def entity_relative_url
19
+ self.class.entity_url.call self if self.class.entity_url
20
+ end
21
+
22
+ def entity_absolute_url
23
+ "http://#{Setting[:domain]}#{entity_relative_url}" if entity_relative_url
24
+ end
25
+
26
+ def entity_edit_url
27
+ self.class.entity_edit_url.call self if self.class.entity_edit_url
28
+ end
29
+
30
+ def self.included(base)
31
+ base.extend ClassMethods
32
+
33
+ base.after_save do |entity|
34
+ Cartoonist::Entity.hooks_with(:after_entity_save).each do |hook|
35
+ hook.after_entity_save entity
36
+ end
37
+ end
38
+ end
39
+
40
+ module ClassMethods
41
+ def entity_relative_url
42
+ entity_global_url
43
+ end
44
+
45
+ def entity_absolute_url
46
+ "http://#{Setting[:domain]}#{entity_relative_url}" if entity_relative_url
47
+ end
48
+
49
+ def entity_type(value = nil)
50
+ if value
51
+ @entity_type = value
52
+ else
53
+ @entity_type || raise(EntityTypeNotSpecifiedError.new("entity_type was not defined for #{self.name}"))
54
+ end
55
+ end
56
+
57
+ def entity_label(value = nil)
58
+ if value
59
+ @entity_label = value
60
+ else
61
+ @entity_label || "cartoonist.entity.#{entity_type}"
62
+ end
63
+ end
64
+
65
+ def entity_localized_label
66
+ I18n.t entity_label
67
+ end
68
+
69
+ def entity_description(&block)
70
+ if block
71
+ @entity_description = block
72
+ else
73
+ @entity_description
74
+ end
75
+ end
76
+
77
+ def entity_global_url(value = nil)
78
+ if value
79
+ @entity_global_url = value
80
+ else
81
+ @entity_global_url
82
+ end
83
+ end
84
+
85
+ def entity_url(&block)
86
+ if block
87
+ @entity_url = block
88
+ else
89
+ @entity_url
90
+ end
91
+ end
92
+
93
+ def entity_edit_url(&block)
94
+ if block
95
+ @entity_edit_url = block
96
+ else
97
+ @entity_edit_url
98
+ end
99
+ end
100
+ end
101
+
102
+ class EntityTypeNotSpecifiedError < StandardError
103
+ end
104
+ end
@@ -0,0 +1,59 @@
1
+ module Postable
2
+ def posted?
3
+ posted_at && posted_at <= postable_now
4
+ end
5
+
6
+ def postable_type
7
+ self.class.postable_type
8
+ end
9
+
10
+ def postable_now
11
+ self.class.postable_now
12
+ end
13
+
14
+ def formatted_posted_at(default_msg = "not yet posted")
15
+ return default_msg unless posted_at
16
+
17
+ if postable_type == :date
18
+ posted_at.strftime "%-m/%-d/%Y"
19
+ else
20
+ posted_at.localtime.strftime "%-m/%-d/%Y at %-l:%M %P"
21
+ end
22
+ end
23
+
24
+ def self.included(base)
25
+ base.extend ClassMethods
26
+ end
27
+
28
+ module ClassMethods
29
+ def postable_now
30
+ if postable_type == :date
31
+ Date.today
32
+ else
33
+ Time.now
34
+ end
35
+ end
36
+
37
+ def postable_type
38
+ type = columns_hash["posted_at"].type
39
+ raise "Postable's posted_at column type should be :date or :datetime!" unless [:date, :datetime].include?(type)
40
+ type
41
+ end
42
+
43
+ def posted
44
+ where "#{quoted_table_name}.posted_at IS NOT NULL AND #{quoted_table_name}.posted_at <= ?", postable_now
45
+ end
46
+
47
+ def unposted
48
+ where "#{quoted_table_name}.posted_at IS NULL OR #{quoted_table_name}.posted_at > ?", postable_now
49
+ end
50
+
51
+ def chronological
52
+ order "#{quoted_table_name}.posted_at ASC"
53
+ end
54
+
55
+ def reverse_chronological
56
+ order "#{quoted_table_name}.posted_at DESC"
57
+ end
58
+ end
59
+ end
@@ -4,9 +4,14 @@ class Setting < ActiveRecord::Base
4
4
  class << self
5
5
  def [](label)
6
6
  raise "Invalid label" unless label.present?
7
- meta = Meta[label.to_sym]
7
+ meta = Setting::Meta[label.to_sym]
8
8
  raise "Missing setting definition for '#{label}'" unless meta
9
- record = where(:label => label.to_s).first
9
+
10
+ begin
11
+ record = where(:label => label.to_s).first
12
+ rescue => e
13
+ raise unless e.to_s =~ /Could not find table/
14
+ end
10
15
 
11
16
  if record
12
17
  meta.convert record.value
@@ -19,8 +24,9 @@ class Setting < ActiveRecord::Base
19
24
 
20
25
  def []=(label, value)
21
26
  raise "Invalid label" unless label.present?
22
- meta = Meta[label.to_sym]
27
+ meta = Setting::Meta[label.to_sym]
23
28
  raise "Missing setting definition for '#{label}'" unless meta
29
+ meta.validation.call value if meta.validation
24
30
  old_value = self[label]
25
31
  record = where(:label => label.to_s).first
26
32
  record = Setting.new :label => label.to_s unless record
@@ -31,36 +37,39 @@ class Setting < ActiveRecord::Base
31
37
  end
32
38
 
33
39
  def define(label, options = {})
34
- Meta[label.to_sym] = Meta.new label, options
40
+ Setting::Meta[label.to_sym] = Setting::Meta.new label, options
35
41
  end
36
42
 
37
43
  def tabs
38
- Tab.all.sort.map &:label
44
+ Setting::Tab.all.sort.map &:label
39
45
  end
40
46
  end
41
47
 
42
48
  class Meta
43
- attr_reader :label, :tab, :section, :order, :type, :default, :onchange, :select_from
49
+ attr_reader :label, :info_label, :tab, :section, :order, :type, :default, :onchange, :validation, :select_from
44
50
  @@settings = {}
45
51
  @@by_tab_section_and_label = {}
46
52
 
47
53
  def initialize(label, options)
48
54
  @label = label.to_sym
49
- @tab = (options[:tab] || Tab.default)
50
- @section = (options[:section] || Section.default)
55
+ @label_override = options[:label]
56
+ @info_label = options[:info_label]
57
+ @tab = (options[:tab] || Setting::Tab.default)
58
+ @section = (options[:section] || Setting::Section.default)
51
59
  @order = (options[:order] || 0)
52
60
  @type = (options[:type] || :string).to_sym
53
61
  @onchange = options[:onchange]
62
+ @validation = options[:validation]
54
63
  @select_from = options[:select_from]
55
64
  raise "Invalid setting type #{@type}" unless [:string, :symbol, :boolean, :int, :float, :array, :hash].include? @type
56
65
 
57
66
  # Auto create general tab and section if it isn't created
58
- if @tab == :general && !Tab[@tab]
59
- Tab.define :general, :order => 0
67
+ if @tab == :general && !Setting::Tab[@tab]
68
+ Setting::Tab.define :general, :order => 0
60
69
  end
61
70
 
62
- if @section == :general && !Section.by_tab_and_label[@tab][@section]
63
- Section.define :general, :order => 0, :tab => @tab
71
+ if @section == :general && !Setting::Section.by_tab_and_label[@tab][@section]
72
+ Setting::Section.define :general, :order => 0, :tab => @tab
64
73
  end
65
74
 
66
75
  if options.include? :default
@@ -82,6 +91,12 @@ class Setting < ActiveRecord::Base
82
91
  end
83
92
  end
84
93
 
94
+ def localized
95
+ return @label_override.call if @label_override.respond_to? :call
96
+ return @label_override if @label_override
97
+ I18n.t @label, :scope => "settings.show.settings"
98
+ end
99
+
85
100
  def select_from_options
86
101
  if select_from.respond_to? :call
87
102
  select_from.call
@@ -160,18 +175,25 @@ class Setting < ActiveRecord::Base
160
175
 
161
176
  def initialize(label, options = {})
162
177
  @label = label.to_sym
178
+ @label_override = options[:label]
163
179
  @order = options[:order] || 1
164
- Section.by_tab_and_label[@label] ||= {}
180
+ Setting::Section.by_tab_and_label[@label] ||= {}
181
+ end
182
+
183
+ def localized
184
+ return @label_override.call if @label_override.respond_to? :call
185
+ return @label_override if @label_override
186
+ I18n.t @label, :scope => "settings.show.tabs"
165
187
  end
166
188
 
167
189
  def sections
168
- Section.by_tab_and_label[label] ||= {}
169
- Section.by_tab_and_label[label].values.sort.map &:label
190
+ Setting::Section.by_tab_and_label[label] ||= {}
191
+ Setting::Section.by_tab_and_label[label].values.sort.map &:label
170
192
  end
171
193
 
172
194
  def [](section_label)
173
- Section.by_tab_and_label[label] ||= {}
174
- Section.by_tab_and_label[label][section_label.to_sym]
195
+ Setting::Section.by_tab_and_label[label] ||= {}
196
+ Setting::Section.by_tab_and_label[label][section_label.to_sym]
175
197
  end
176
198
 
177
199
  def <=>(other)
@@ -193,16 +215,25 @@ class Setting < ActiveRecord::Base
193
215
  @@default
194
216
  end
195
217
 
218
+ def with_default_tab(label)
219
+ original = @@default
220
+
221
+ begin
222
+ @@default = label.to_sym
223
+ yield
224
+ ensure
225
+ @@default = original
226
+ end
227
+ end
228
+
196
229
  def define(label, options = {})
197
230
  raise "Duplicate tab '#{label}' being defined" if @@by_label.include? label.to_sym
198
- tab = Tab.new label, options
231
+ tab = Setting::Tab.new label, options
199
232
  @@all << tab
200
233
  @@by_label[label.to_sym] = tab
201
- begin
202
- @@default = label.to_sym
234
+
235
+ with_default_tab label do
203
236
  yield if block_given?
204
- ensure
205
- @@default = :general
206
237
  end
207
238
  end
208
239
  end
@@ -216,12 +247,19 @@ class Setting < ActiveRecord::Base
216
247
 
217
248
  def initialize(label, options = {})
218
249
  @label = label.to_sym
250
+ @label_override = options[:label]
219
251
  @order = options[:order] || 1
220
- @tab = (options[:tab] || Tab.default).to_sym
252
+ @tab = (options[:tab] || Setting::Tab.default).to_sym
253
+ end
254
+
255
+ def localized
256
+ return @label_override.call if @label_override.respond_to? :call
257
+ return @label_override if @label_override
258
+ I18n.t @label, :scope => "settings.show.sections.#{Setting::Tab[@tab].label}"
221
259
  end
222
260
 
223
261
  def settings
224
- Meta.by_tab_section_and_label[tab][label].values.sort.map &:label
262
+ Setting::Meta.by_tab_section_and_label[tab][label].values.sort.map &:label
225
263
  end
226
264
 
227
265
  def <=>(other)
@@ -240,13 +278,16 @@ class Setting < ActiveRecord::Base
240
278
  end
241
279
 
242
280
  def define(label, options = {})
243
- section = Section.new label, options
281
+ section = Setting::Section.new label, options
244
282
  @@all << section
245
283
  @@by_tab_and_label[section.tab] ||= {}
246
284
  @@by_tab_and_label[section.tab][label.to_sym] = section
247
285
  begin
248
286
  @@default = label.to_sym
249
- yield if block_given?
287
+
288
+ Setting::Tab.with_default_tab section.tab do
289
+ yield if block_given?
290
+ end
250
291
  ensure
251
292
  @@default = :general
252
293
  end
@@ -257,4 +298,7 @@ class Setting < ActiveRecord::Base
257
298
  end
258
299
  end
259
300
  end
301
+
302
+ class InvalidError < StandardError
303
+ end
260
304
  end