cartoonist 0.0.9 → 0.0.10
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.
- data/app/controllers/admin_controller.rb +11 -5
- data/app/controllers/cartoonist_controller.rb +15 -0
- data/app/controllers/site_controller.rb +7 -4
- data/app/models/backup.rb +103 -4
- data/app/models/database_file.rb +34 -1
- data/app/models/markdown.rb +25 -5
- data/app/models/setting.rb +4 -0
- data/app/models/user.rb +4 -0
- data/app/views/admin/main.html.erb +5 -1
- data/cartoonist.gemspec +2 -0
- data/config/locales/en.yml +2 -1
- data/db/migrate/20120524032959_add_extension_to_database_files.rb +6 -0
- data/lib/cartoonist/engine.rb +4 -3
- data/lib/cartoonist.rb +3 -0
- metadata +33 -10
@@ -9,11 +9,17 @@ class AdminController < CartoonistController
|
|
9
9
|
def backup
|
10
10
|
respond_to do |format|
|
11
11
|
format.html { redirect_to "/admin/main" }
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
headers["Content-Disposition"] =
|
16
|
-
|
12
|
+
|
13
|
+
format.tgz do
|
14
|
+
backup = Backup.new :tgz
|
15
|
+
headers["Content-Disposition"] = backup.content_disposition
|
16
|
+
self.response_body = backup.response_body
|
17
|
+
end
|
18
|
+
|
19
|
+
format.zip do
|
20
|
+
backup = Backup.new :zip
|
21
|
+
headers["Content-Disposition"] = backup.content_disposition
|
22
|
+
self.response_body = backup.response_body
|
17
23
|
end
|
18
24
|
end
|
19
25
|
end
|
@@ -46,6 +46,21 @@ class CartoonistController < ActionController::Base
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def cache_page_as(path)
|
49
|
+
if block_given?
|
50
|
+
expiration = expiration_for path
|
51
|
+
response.headers["Expires"] = CGI.rfc1123_date expiration.from_now
|
52
|
+
expires_in expiration, :public => true
|
53
|
+
yield
|
54
|
+
end
|
55
|
+
|
49
56
|
cache_page @response, "/cache/#{path}"
|
50
57
|
end
|
58
|
+
|
59
|
+
def expiration_for(path)
|
60
|
+
if path =~ /\.tmp\.[^.]*$/
|
61
|
+
2.hours
|
62
|
+
else
|
63
|
+
7.days
|
64
|
+
end
|
65
|
+
end
|
51
66
|
end
|
@@ -5,8 +5,10 @@ class SiteController < CartoonistController
|
|
5
5
|
|
6
6
|
format.ico do
|
7
7
|
data = ActionController::Base.helpers.asset_paths.asset_environment[Cartoonist::Theme.favicon].to_s
|
8
|
-
|
9
|
-
cache_page_as "static/favicon.ico"
|
8
|
+
|
9
|
+
cache_page_as "static/favicon.ico" do
|
10
|
+
send_data data, :filename => "favicon.ico", :type => "image/x-icon", :disposition => "inline"
|
11
|
+
end
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
@@ -16,8 +18,9 @@ class SiteController < CartoonistController
|
|
16
18
|
format.html { redirect_to "/" }
|
17
19
|
|
18
20
|
format.text do
|
19
|
-
|
20
|
-
|
21
|
+
cache_page_as "static/robots.txt" do
|
22
|
+
render :layout => false
|
23
|
+
end
|
21
24
|
end
|
22
25
|
end
|
23
26
|
end
|
data/app/models/backup.rb
CHANGED
@@ -1,11 +1,110 @@
|
|
1
1
|
class Backup
|
2
|
+
ALLOWED_EXTENSIONS = [:tgz, :zip]
|
3
|
+
|
4
|
+
def initialize(extension)
|
5
|
+
raise "Invalid extension '#{extension}'" unless ALLOWED_EXTENSIONS.include? extension.to_sym
|
6
|
+
@extension = extension.to_sym
|
7
|
+
end
|
8
|
+
|
9
|
+
def content_disposition
|
10
|
+
%{attachment; filename="#{filename}"}
|
11
|
+
end
|
12
|
+
|
13
|
+
def filename
|
14
|
+
prefix = "dev-" unless Rails.env.production?
|
15
|
+
"#{prefix}cartoonist-backup-#{Time.now.strftime("%Y-%m-%d_%H%M%S")}.#{@extension}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def response_body
|
19
|
+
Enumerator.new do |out|
|
20
|
+
send @extension, out
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def zip(out)
|
25
|
+
buffer = Zip::ZipOutputStream.write_buffer do |zos|
|
26
|
+
Backup.each do |entry|
|
27
|
+
zos.put_next_entry entry.path
|
28
|
+
zos.write entry.content
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
out << buffer.string
|
33
|
+
end
|
34
|
+
|
35
|
+
def tgz(out)
|
36
|
+
gzip = Zlib::GzipWriter.new Backup::ResponseOutWriter.new(out)
|
37
|
+
|
38
|
+
begin
|
39
|
+
Archive::Tar::Minitar::Writer.open gzip do |tar|
|
40
|
+
Backup.each do |entry|
|
41
|
+
tar.add_file_simple entry.path, :mode => 0644, :size => entry.content.length do |output|
|
42
|
+
output.write entry.content
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
ensure
|
47
|
+
gzip.close
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class ResponseOutWriter < Struct.new(:stream)
|
52
|
+
def write(content)
|
53
|
+
stream << content
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
2
57
|
class << self
|
3
|
-
def
|
4
|
-
|
5
|
-
|
58
|
+
def each
|
59
|
+
Cartoonist::Backup.all.each do |key, proc|
|
60
|
+
proc.call.find_each do |value|
|
61
|
+
if value.respond_to? :to_backup_entries
|
62
|
+
value.to_backup_entries.each do |entry|
|
63
|
+
yield entry.with_key(key)
|
64
|
+
end
|
65
|
+
else
|
66
|
+
yield Backup::Entry.from_record(value).with_key(key)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class Entry
|
74
|
+
attr_reader :key, :filename, :content
|
75
|
+
|
76
|
+
def initialize(id, title, extension, content)
|
77
|
+
if title
|
78
|
+
title = "%05d_%s" % [id, title]
|
79
|
+
else
|
80
|
+
title = "%05d" % id
|
6
81
|
end
|
7
82
|
|
8
|
-
|
83
|
+
title = DatabaseFile.sanitize title
|
84
|
+
extension = DatabaseFile.sanitize(extension || "")
|
85
|
+
extension = ".#{extension}" if extension.present?
|
86
|
+
@filename = "#{title}#{extension}"
|
87
|
+
@content = content
|
88
|
+
end
|
89
|
+
|
90
|
+
def with_key(key)
|
91
|
+
@key = key
|
92
|
+
self
|
93
|
+
end
|
94
|
+
|
95
|
+
def safe_key
|
96
|
+
DatabaseFile.sanitize key.to_s
|
97
|
+
end
|
98
|
+
|
99
|
+
def path
|
100
|
+
"#{safe_key}/#{filename}"
|
101
|
+
end
|
102
|
+
|
103
|
+
class << self
|
104
|
+
def from_record(record)
|
105
|
+
title = record.zip_title if record.respond_to? :zip_title
|
106
|
+
new record.id, title, "json", record.to_json
|
107
|
+
end
|
9
108
|
end
|
10
109
|
end
|
11
110
|
end
|
data/app/models/database_file.rb
CHANGED
@@ -1,3 +1,36 @@
|
|
1
1
|
class DatabaseFile < ActiveRecord::Base
|
2
|
-
attr_accessible :filename, :content
|
2
|
+
attr_accessible :filename, :extension, :content
|
3
|
+
|
4
|
+
def to_backup_entries
|
5
|
+
if filename
|
6
|
+
meta_name = "#{filename}.meta"
|
7
|
+
else
|
8
|
+
meta_name = "meta"
|
9
|
+
end
|
10
|
+
|
11
|
+
file = Backup::Entry.new id, filename, extension, content
|
12
|
+
meta = Backup::Entry.new id, meta_name, "json", to_json(:except => :content)
|
13
|
+
[file, meta]
|
14
|
+
end
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def sanitize(value)
|
18
|
+
value.gsub(/\s+/, "_").gsub(/[^0-9a-zA-Z.\-_]/, "")
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_from_param(file, options = {})
|
22
|
+
original_filename = file.original_filename
|
23
|
+
extension = File.extname original_filename
|
24
|
+
filename = File.basename original_filename, extension
|
25
|
+
filename = nil if filename.blank?
|
26
|
+
extension = extension[/^\.?(.*?)$/, 1].downcase if extension
|
27
|
+
extension = nil if extension.blank?
|
28
|
+
|
29
|
+
if options.include?(:allowed_extensions) && !options[:allowed_extensions].map(&:downcase).include?(extension)
|
30
|
+
raise "Extension must be one of: #{options[:allowed_extensions].join ", "}"
|
31
|
+
end
|
32
|
+
|
33
|
+
create :filename => filename, :extension => extension, :content => file.read
|
34
|
+
end
|
35
|
+
end
|
3
36
|
end
|
data/app/models/markdown.rb
CHANGED
@@ -1,13 +1,33 @@
|
|
1
1
|
class Markdown
|
2
|
+
class LinkToAbsoluteRenderer < Redcarpet::Render::HTML
|
3
|
+
def link(link, title, content)
|
4
|
+
link = "http://#{Setting[:domain]}#{link}" if link =~ /^\//
|
5
|
+
title = %{ title="#{title}"} if title
|
6
|
+
%{<a href="#{link}"#{title}>#{content}</a>}
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
2
10
|
class << self
|
3
|
-
|
4
|
-
|
11
|
+
RENDER_DEFAULTS = { :html_safe => true, :link_to_absolute => false }
|
12
|
+
|
13
|
+
def standard_renderer
|
14
|
+
@standard_renderer ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML)
|
5
15
|
end
|
6
16
|
|
7
|
-
def
|
8
|
-
|
17
|
+
def link_to_absolute_renderer
|
18
|
+
@link_to_absolute_renderer ||= Redcarpet::Markdown.new(LinkToAbsoluteRenderer.new)
|
19
|
+
end
|
20
|
+
|
21
|
+
def render(text, options = {})
|
22
|
+
options = RENDER_DEFAULTS.merge options
|
23
|
+
|
24
|
+
if options[:link_to_absolute]
|
25
|
+
result = link_to_absolute_renderer.render text
|
26
|
+
else
|
27
|
+
result = standard_renderer.render text
|
28
|
+
end
|
9
29
|
|
10
|
-
if
|
30
|
+
if options[:html_safe]
|
11
31
|
result.html_safe
|
12
32
|
else
|
13
33
|
result
|
data/app/models/setting.rb
CHANGED
data/app/models/user.rb
CHANGED
@@ -4,6 +4,10 @@ class User < ActiveRecord::Base
|
|
4
4
|
# Setup accessible (or protected) attributes for your model
|
5
5
|
attr_accessible :email, :password, :password_confirmation, :remember_me, :name
|
6
6
|
|
7
|
+
def zip_title
|
8
|
+
name
|
9
|
+
end
|
10
|
+
|
7
11
|
class << self
|
8
12
|
def create_user(params)
|
9
13
|
create :email => params[:email], :name => params[:name], :password => params[:password], :password_confirmation => params[:confirm_password]
|
@@ -3,5 +3,9 @@
|
|
3
3
|
</p>
|
4
4
|
|
5
5
|
<p>
|
6
|
-
<a href="/admin/backup.
|
6
|
+
<a href="/admin/backup.tgz"><%= t "admin.general.actions.backup_tgz" %></a>
|
7
|
+
</p>
|
8
|
+
|
9
|
+
<p>
|
10
|
+
<a href="/admin/backup.zip"><%= t "admin.general.actions.backup_zip" %></a>
|
7
11
|
</p>
|
data/cartoonist.gemspec
CHANGED
data/config/locales/en.yml
CHANGED
data/lib/cartoonist/engine.rb
CHANGED
@@ -294,19 +294,20 @@ module Cartoonist
|
|
294
294
|
end
|
295
295
|
|
296
296
|
Mime::Type.register "image/x-icon", :ico
|
297
|
+
Mime::Type.register "application/octet-stream", :tgz
|
297
298
|
Cartoonist::Admin::Tab.add :general, :url => "/admin", :order => 3
|
298
299
|
Cartoonist::Migration.add_for self
|
299
300
|
|
300
301
|
Cartoonist::Backup.for :files do
|
301
|
-
DatabaseFile.order(:id)
|
302
|
+
DatabaseFile.order(:id)
|
302
303
|
end
|
303
304
|
|
304
305
|
Cartoonist::Backup.for :settings do
|
305
|
-
Setting.order(:id)
|
306
|
+
Setting.order(:id)
|
306
307
|
end
|
307
308
|
|
308
309
|
Cartoonist::Backup.for :users do
|
309
|
-
User.order(:id)
|
310
|
+
User.order(:id)
|
310
311
|
end
|
311
312
|
|
312
313
|
Cartoonist::Cron.add do
|
data/lib/cartoonist.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cartoonist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: devise
|
16
|
-
requirement: &
|
16
|
+
requirement: &12204220 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 2.0.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *12204220
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: jquery-rails
|
27
|
-
requirement: &
|
27
|
+
requirement: &12203580 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 2.0.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *12203580
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: railties
|
38
|
-
requirement: &
|
38
|
+
requirement: &12203040 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 3.2.0
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *12203040
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: redcarpet
|
49
|
-
requirement: &
|
49
|
+
requirement: &12273440 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,7 +54,29 @@ dependencies:
|
|
54
54
|
version: 2.1.0
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *12273440
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rubyzip
|
60
|
+
requirement: &12272860 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 0.9.0
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *12272860
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitar
|
71
|
+
requirement: &12272340 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 0.5.0
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *12272340
|
58
80
|
description: This provides the main functionality and plugin api for Cartoonist.
|
59
81
|
email: reasonnumber@gmail.com
|
60
82
|
executables: []
|
@@ -110,6 +132,7 @@ files:
|
|
110
132
|
- db/migrate/20120320043253_create_database_files.rb
|
111
133
|
- db/migrate/20120401014029_create_settings.rb
|
112
134
|
- db/migrate/20120417075756_devise_create_users.rb
|
135
|
+
- db/migrate/20120524032959_add_extension_to_database_files.rb
|
113
136
|
- lib/cartoonist.rb
|
114
137
|
- lib/cartoonist/engine.rb
|
115
138
|
- public/errors/404.html
|