cartoonist 0.0.8 → 0.0.9

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