caboose-cms 0.4.71 → 0.4.72
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.
- checksums.yaml +8 -8
- data/app/assets/javascripts/caboose/admin_images_index.js +168 -0
- data/app/assets/stylesheets/caboose/admin_images_index.css +33 -0
- data/app/assets/stylesheets/caboose/model_binder.css +1 -1
- data/app/controllers/caboose/images_controller.rb +46 -230
- data/app/controllers/caboose/login_controller.rb +1 -1
- data/app/controllers/caboose/logout_controller.rb +2 -0
- data/app/controllers/caboose/media_categories_controller.rb +56 -0
- data/app/models/caboose/media_category.rb +12 -0
- data/app/models/caboose/media_file.rb +9 -0
- data/app/models/caboose/media_image.rb +22 -3
- data/app/models/caboose/media_image_socket.rb +73 -0
- data/app/models/caboose/schema.rb +8 -6
- data/app/views/caboose/blocks/_controller_view_content.html.erb +7 -0
- data/app/views/caboose/extras/error_invalid_site.html.erb +3 -0
- data/app/views/caboose/images/admin_edit.html.erb +60 -0
- data/app/views/caboose/images/admin_index.html.erb +32 -81
- data/config/routes.rb +5 -0
- data/lib/caboose/version.rb +1 -1
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
OWQ2YWNkYzI0MTBjZjI1ZmYyNDRhYTE4NGE5ODA4ZDQ0MWRiMDBlMQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YWM0MWU1NTc0ZjE4NWIyNTA3NTI2ZDJlNjhlY2U3N2NjZWQ1ZmExOQ==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NWQyNGIzYTJhNThmYjRiM2M0ZjQ0NjA3ZDU1ZGNiOTRlNzYyYzk2YWNjYTM4
|
10
|
+
OGUxMzc2N2Q2ODVkOGViNjg0NjJkZjJmOTE5Yjk2MjJhZjQ5YjI5MTk1MDFm
|
11
|
+
ZGRkMzE4YzJjY2U1MTY2ZmVmOWM3NjRmNmMyMWQwNjdiNjMxMzI=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
Yzk3NjQyZTQxZTAxNTM2OTBlMTA0MGQzYjFmZmIxZDhlMDkwNzYzOWNmYTM5
|
14
|
+
MTE2OWNkNjVkOTcyYmEwYzM4MDcwNWFmMzMwNmQxZDNjNDZmYTU2ZDg3N2Fi
|
15
|
+
MjZkMDRiNWI1Njk1ODE3ZDViMjAwZDczYWZhYmM5NjE0YmYwNzQ=
|
@@ -0,0 +1,168 @@
|
|
1
|
+
|
2
|
+
var ImagesController = function(params) { this.init(params); };
|
3
|
+
|
4
|
+
ImagesController.prototype = {
|
5
|
+
|
6
|
+
cat_id: false,
|
7
|
+
cat: false,
|
8
|
+
|
9
|
+
init: function(params) {
|
10
|
+
var that = this;
|
11
|
+
for (var i in params)
|
12
|
+
this[i] = params[i];
|
13
|
+
|
14
|
+
$('#new_cat_link').click(function(e) {
|
15
|
+
e.preventDefault();
|
16
|
+
that.add_category(that.cat_id);
|
17
|
+
});
|
18
|
+
|
19
|
+
this.print_images();
|
20
|
+
},
|
21
|
+
|
22
|
+
// Gets updated image info from server and prints out categories and images.
|
23
|
+
print_images: function() {
|
24
|
+
var that = this;
|
25
|
+
$('#message').html("<p class='loading'>Refreshing images...</p>");
|
26
|
+
$.ajax({
|
27
|
+
url: '/admin/images/json',
|
28
|
+
type: 'get',
|
29
|
+
async: false,
|
30
|
+
data: { media_category_id: this.cat_id },
|
31
|
+
success: function(resp) {
|
32
|
+
that.cat = resp;
|
33
|
+
}
|
34
|
+
});
|
35
|
+
$('#message').empty();
|
36
|
+
var ul = $('#media');
|
37
|
+
if (this.cat.children.length > 0 || this.cat.images.count > 0)
|
38
|
+
{
|
39
|
+
$.each(this.cat.children, function(i, cat2) {
|
40
|
+
ul.append($('<li/>').addClass('category').attr('id', 'cat' + cat2.id)
|
41
|
+
.append($('<a/>').attr('href', '/admin/images?media_category_id=' + cat2.id)
|
42
|
+
.append($('<span/>').addClass('icon icon-folder2'))
|
43
|
+
.append($('<span/>').addClass('name').html(cat2.name))
|
44
|
+
)
|
45
|
+
);
|
46
|
+
});
|
47
|
+
$.each(this.cat.images, function(i, mi) {
|
48
|
+
ul.append($('<li/>').addClass('image').attr('id', 'image' + mi.id)
|
49
|
+
.append($('<a/>').attr('href', '/admin/images/' + mi.id)
|
50
|
+
.css('background-image', mi.tiny_url)
|
51
|
+
.append($('<span/>').addClass('name').html(mi.name))
|
52
|
+
)
|
53
|
+
);
|
54
|
+
});
|
55
|
+
}
|
56
|
+
ul.replaceWith($('<p/>').html("This category is empty."));
|
57
|
+
},
|
58
|
+
|
59
|
+
// Adds a new media category
|
60
|
+
add_category: function(parent_id, name)
|
61
|
+
{
|
62
|
+
var that = this;
|
63
|
+
if (!name)
|
64
|
+
{
|
65
|
+
var div = $('<p/>').addClass('note warning')
|
66
|
+
.append('New Category Name: ')
|
67
|
+
.append($('<input/>').attr('type', 'text').attr('id', 'new_cat_name')).append(" ")
|
68
|
+
.append($('<input/>').attr('type', 'button').val('Add').click(function() { that.add_category(parent_id, $('#new_cat_name').val()); })).append(" ")
|
69
|
+
.append($('<input/>').attr('type', 'button').val('Cancel').click(function() { $('#new_cat_message').empty(); }));
|
70
|
+
$('#new_cat_message').empty().append(div);
|
71
|
+
return;
|
72
|
+
}
|
73
|
+
$('#new_cat_message').empty().html("<p class='loading'>Adding category...</p>");
|
74
|
+
$.ajax({
|
75
|
+
url: '/admin/media-categories',
|
76
|
+
type: 'post',
|
77
|
+
data: {
|
78
|
+
parent_id: parent_id,
|
79
|
+
name: name
|
80
|
+
},
|
81
|
+
success: function(resp) {
|
82
|
+
if (resp.error) $('#new_cat_message').empty().html("<p class='note error'>" + resp.error + "</p>");
|
83
|
+
if (resp.refresh) window.location.reload(true);
|
84
|
+
}
|
85
|
+
});
|
86
|
+
},
|
87
|
+
|
88
|
+
// Lets a single image poll the server to see if it has been processed.
|
89
|
+
wait_for_image_processing: function(image_id, i)
|
90
|
+
{
|
91
|
+
if (!i) i = 1;
|
92
|
+
var is_finished = false;
|
93
|
+
$.ajax({
|
94
|
+
url: '/admin/images/' + image_id + '/finished',
|
95
|
+
type: 'get',
|
96
|
+
async: false,
|
97
|
+
success: function(resp) {
|
98
|
+
if (resp.error) alert("Error processing image: \n" + resp.error);
|
99
|
+
if (resp.is_finished)
|
100
|
+
{
|
101
|
+
is_finished = true;
|
102
|
+
$('#image' + mi.id + ' a').css('background-image', resp.tiny_url);
|
103
|
+
}
|
104
|
+
}
|
105
|
+
});
|
106
|
+
if (!is_finished)
|
107
|
+
setTimeout(function() { that.wait_for_image_processing(image_id, i+1); }, 500);
|
108
|
+
},
|
109
|
+
|
110
|
+
upload_form: function()
|
111
|
+
{
|
112
|
+
var that = this;
|
113
|
+
$('#file').fileupload({
|
114
|
+
//forceIframeTransport: true,
|
115
|
+
autoUpload: true,
|
116
|
+
//replaceFileInput: true,
|
117
|
+
//singleFileUploads: false,
|
118
|
+
add: function(e, data) {
|
119
|
+
$.ajax({
|
120
|
+
url: '/admin/images/s3',
|
121
|
+
type: 'get',
|
122
|
+
data: {
|
123
|
+
name: data.files[0].name,
|
124
|
+
media_category_id: that.cat_id
|
125
|
+
},
|
126
|
+
async: false,
|
127
|
+
success: function(resp) {
|
128
|
+
image_ids.push(resp.media_image_id);
|
129
|
+
var form = $('#new_image_form');
|
130
|
+
for (var i in resp.fields)
|
131
|
+
form.find("input[name=" + i + "]").val(resp.fields[i]);
|
132
|
+
form.attr('action', resp.url);
|
133
|
+
}
|
134
|
+
});
|
135
|
+
data.submit();
|
136
|
+
},
|
137
|
+
progressall: function (e, data) {
|
138
|
+
$('#bar').css('width', parseInt(data.loaded / data.total * 100, 10) + '%')
|
139
|
+
},
|
140
|
+
start: function (e) {
|
141
|
+
$('#file').hide();
|
142
|
+
$('#bar').css('background', 'green').css('display', 'block').css('width', '0%').html(" ");
|
143
|
+
},
|
144
|
+
done: function(e, data) {
|
145
|
+
console.log("Upload done.");
|
146
|
+
console.log(data);
|
147
|
+
setTimeout(function() {
|
148
|
+
$.each(image_ids, function(i, id) {
|
149
|
+
$.ajax({
|
150
|
+
url: '/admin/images/' + id + '/process',
|
151
|
+
type: 'get',
|
152
|
+
async: false,
|
153
|
+
success: function(resp) {}
|
154
|
+
});
|
155
|
+
});
|
156
|
+
$('#progress').empty().html("<p class='loading'>Upload complete. Processing images...</p>");
|
157
|
+
that.wait_for_image_processing(id);
|
158
|
+
|
159
|
+
}, 500);
|
160
|
+
},
|
161
|
+
fail: function(e, data) {
|
162
|
+
console.log("Upload failed.");
|
163
|
+
console.log(data);
|
164
|
+
$('#bar').css("background", "red").text("Failed");
|
165
|
+
}
|
166
|
+
});
|
167
|
+
}
|
168
|
+
};
|
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
ul.media { list-style: none; margin: 0; padding: 0; }
|
3
|
+
ul.media li { list-style: none; margin: 4px; padding: 0; float: left; }
|
4
|
+
ul.media a {
|
5
|
+
display: block;
|
6
|
+
width: 150px;
|
7
|
+
height: 150px;
|
8
|
+
overflow: hidden;
|
9
|
+
border: #666 4px solid;
|
10
|
+
background-size: contain;
|
11
|
+
background-repeat: no-repeat;
|
12
|
+
background-position: center;
|
13
|
+
background-color: #666;
|
14
|
+
position: relative;
|
15
|
+
text-align: center;
|
16
|
+
}
|
17
|
+
ul.media a:hover {
|
18
|
+
background-color: #fff69f;
|
19
|
+
border-color: #fff69f;
|
20
|
+
}
|
21
|
+
ul.media li a span { color: #fff; text-decoration: none; }
|
22
|
+
ul.media li a:hover span { background: #efefef; color: #000; }
|
23
|
+
ul.media li a span.name { display: block; background: #666; color: #fff; text-decoration: none !important; border: 0; }
|
24
|
+
ul.media li a:hover span.name { background: #fff69f; color: #000; }
|
25
|
+
|
26
|
+
ul.media li a.selected span,
|
27
|
+
ul.media li a.selected:hover span { background: #fff69f; color: #000; border: #fff69f 1px solid; }
|
28
|
+
|
29
|
+
ul.media li.category a span.icon { display: block; padding: 10px 20px; font-size: 24pt; color: #fff; }
|
30
|
+
ul.media li.category a:hover span.icon { background: #fff69f; color: #000; }
|
31
|
+
|
32
|
+
.progress { max-width: 600px; margin: 0.2em 0 0.2em 0; }
|
33
|
+
.progress .bar { height: 1.2em; padding: 0.2em; color: white; display: none; }
|
@@ -10,11 +10,23 @@ module Caboose
|
|
10
10
|
|
11
11
|
# GET /admin/images
|
12
12
|
def admin_index
|
13
|
-
return if !user_is_allowed('images', 'view')
|
14
|
-
|
15
|
-
|
13
|
+
return if !user_is_allowed('images', 'view')
|
14
|
+
render :file => 'caboose/extras/error_invalid_site' and return if @site.nil?
|
15
|
+
|
16
|
+
id = params[:media_category_id]
|
17
|
+
@media_category = id ? MediaCategory.find(id) : MediaCategory.top_image_category(@site.id)
|
16
18
|
render :layout => 'caboose/admin'
|
17
19
|
end
|
20
|
+
|
21
|
+
# GET /admin/images/json
|
22
|
+
def admin_json
|
23
|
+
return if !user_is_allowed('images', 'view')
|
24
|
+
render :json => false and return if @site.nil?
|
25
|
+
|
26
|
+
id = params[:media_category_id]
|
27
|
+
cat = id ? MediaCategory.find(id) : MediaCategory.top_image_category(@site.id)
|
28
|
+
render :json => cat.api_hash
|
29
|
+
end
|
18
30
|
|
19
31
|
# GET /admin/images/new
|
20
32
|
def admin_new
|
@@ -26,252 +38,39 @@ module Caboose
|
|
26
38
|
# GET /admin/images/:id
|
27
39
|
def admin_edit
|
28
40
|
return unless user_is_allowed('images', 'edit')
|
29
|
-
@
|
41
|
+
@media_image = MediaImage.find(params[:id])
|
30
42
|
render :layout => 'caboose/admin'
|
31
43
|
end
|
32
|
-
|
33
|
-
# POST /admin/images
|
34
|
-
def admin_add
|
35
|
-
return unless user_is_allowed('images', 'add')
|
36
|
-
|
37
|
-
resp = Caboose::StdClass.new({
|
38
|
-
'error' => nil,
|
39
|
-
'redirect' => nil
|
40
|
-
})
|
41
44
|
|
42
|
-
parent_id = params[:parent_id]
|
43
|
-
title = params[:title]
|
44
|
-
|
45
|
-
if (title.strip.length == 0)
|
46
|
-
resp.error = "A page title is required."
|
47
|
-
elsif (!logged_in_user.is_allowed('all', 'all') &&
|
48
|
-
!Page.page_ids_with_permission(logged_in_user, 'edit' ).include?(parent_id) &&
|
49
|
-
!Page.page_ids_with_permission(logged_in_user, 'approve').include?(parent_id))
|
50
|
-
resp.error = "You don't have permission to add a page there."
|
51
|
-
end
|
52
|
-
if (!resp.error.nil?)
|
53
|
-
render :json => resp
|
54
|
-
return
|
55
|
-
end
|
56
|
-
|
57
|
-
parent = Caboose::Page.find(parent_id)
|
58
|
-
page = Caboose::Page.new
|
59
|
-
|
60
|
-
if parent.nil?
|
61
|
-
d = Domain.where(:domain => request.host_with_port).first.site_id
|
62
|
-
page.site_id = d.site_id
|
63
|
-
else
|
64
|
-
page.site_id = parent.site_id
|
65
|
-
end
|
66
|
-
|
67
|
-
page.title = title
|
68
|
-
page.parent_id = parent_id
|
69
|
-
page.hide = true
|
70
|
-
page.content_format = Caboose::Page::CONTENT_FORMAT_HTML
|
71
|
-
|
72
|
-
i = 0
|
73
|
-
begin
|
74
|
-
page.slug = Page.slug(page.title + (i > 0 ? " #{i}" : ""))
|
75
|
-
page.uri = parent.parent_id == -1 ? page.slug : "#{parent.uri}/#{page.slug}"
|
76
|
-
i = i+1
|
77
|
-
end while (Page.where(:uri => page.uri).count > 0 && i < 10)
|
78
|
-
|
79
|
-
page.save
|
80
|
-
|
81
|
-
# Create the top level block for the page
|
82
|
-
bt = BlockType.find(params[:block_type_id])
|
83
|
-
Block.create(:page_id => page.id, :block_type_id => params[:block_type_id], :name => bt.name)
|
84
|
-
|
85
|
-
# Set the new page's permissions
|
86
|
-
viewers = Caboose::PagePermission.where({ :page_id => parent.id, :action => 'view' }).pluck(:role_id)
|
87
|
-
editors = Caboose::PagePermission.where({ :page_id => parent.id, :action => 'edit' }).pluck(:role_id)
|
88
|
-
Caboose::Page.update_authorized_for_action(page.id, 'view', viewers)
|
89
|
-
Caboose::Page.update_authorized_for_action(page.id, 'edit', editors)
|
90
|
-
|
91
|
-
# Send back the response
|
92
|
-
resp.redirect = "/admin/images/#{page.id}/edit"
|
93
|
-
render json: resp
|
94
|
-
end
|
95
|
-
|
96
45
|
# PUT /admin/images/:id
|
97
46
|
def admin_update
|
98
47
|
return unless user_is_allowed('images', 'edit')
|
99
48
|
|
100
49
|
resp = StdClass.new({'attributes' => {}})
|
101
|
-
|
50
|
+
image = MediaImage.find(params[:id])
|
102
51
|
|
103
|
-
save = true
|
104
|
-
user = logged_in_user
|
52
|
+
save = true
|
105
53
|
params.each do |name, value|
|
106
54
|
case name
|
107
|
-
|
108
|
-
|
109
|
-
if page.id == value
|
110
|
-
resp.error = "The page's parent cannot be itself."
|
111
|
-
elsif Page.is_child(page.id, value)
|
112
|
-
resp.error = "You can't set the current page's parent to be one of its child pages."
|
113
|
-
elsif value != page.parent_id
|
114
|
-
p = Page.find(value)
|
115
|
-
if !user.is_allowed(p, 'edit')
|
116
|
-
resp.error = "You don't have access to put the current page there."
|
117
|
-
end
|
118
|
-
end
|
119
|
-
if resp.error
|
120
|
-
save = false
|
121
|
-
else
|
122
|
-
page.parent = Page.find(value)
|
123
|
-
page.save
|
124
|
-
Page.update_uri(page)
|
125
|
-
resp.attributes['parent_id'] = { 'text' => page.parent.title }
|
126
|
-
end
|
127
|
-
|
128
|
-
when 'custom_css', 'custom_js'
|
129
|
-
value.strip!
|
130
|
-
page[name.to_sym] = value
|
131
|
-
|
132
|
-
when 'title', 'menu_title', 'hide', 'layout', 'redirect_url',
|
133
|
-
'seo_title', 'meta_description', 'fb_description', 'gp_description', 'canonical_url'
|
134
|
-
page[name.to_sym] = value
|
135
|
-
|
136
|
-
when 'linked_resources'
|
137
|
-
result = []
|
138
|
-
value.each_line do |line|
|
139
|
-
line.chomp!
|
140
|
-
line.strip!
|
141
|
-
next if line.empty?
|
142
|
-
|
143
|
-
if !(line.ends_with('.js') || line.ends_with('.css'))
|
144
|
-
resp.error = "Resource '#{line}' has an unsupported file type ('#{comps.last}')."
|
145
|
-
save = false
|
146
|
-
end
|
147
|
-
|
148
|
-
result << line
|
149
|
-
end
|
150
|
-
page.linked_resources = result.join("\n")
|
151
|
-
|
152
|
-
when 'content_format'
|
153
|
-
page.content_format = value
|
154
|
-
resp.attributes['content_format'] = { 'text' => value }
|
155
|
-
|
156
|
-
when 'meta_robots'
|
157
|
-
if (value.include?('index') && value.include?('noindex'))
|
158
|
-
resp.error = "You can't have both index and noindex"
|
159
|
-
save = false
|
160
|
-
elsif (value.include?('follow') && value.include?('nofollow'))
|
161
|
-
resp.error = "You can't have both follow and nofollow"
|
162
|
-
save = false
|
163
|
-
else
|
164
|
-
page.meta_robots = value.join(', ')
|
165
|
-
resp.attributes['meta_robots'] = { 'text' => page.meta_robots }
|
166
|
-
end
|
167
|
-
|
168
|
-
when 'content'
|
169
|
-
page.content = value.strip.gsub(/<meta.*?>/, '').gsub(/<link.*?>/, '').gsub(/\<\!--[\S\s]*?--\>/, '')
|
170
|
-
|
171
|
-
when 'slug'
|
172
|
-
page.slug = Page.slug(value.strip.length > 0 ? value : page.title)
|
173
|
-
page.save
|
174
|
-
Page.update_uri(page)
|
175
|
-
resp.attributes['slug'] = { 'value' => page.slug }
|
176
|
-
resp.attributes['uri'] = { 'value' => page.uri }
|
177
|
-
|
178
|
-
when 'alias'
|
179
|
-
page.alias = Page.slug(value.strip)
|
180
|
-
page.save
|
181
|
-
Page.update_uri(page)
|
182
|
-
resp.attributes['slug'] = { 'value' => page.slug }
|
183
|
-
resp.attributes['uri'] = { 'value' => page.uri }
|
184
|
-
|
185
|
-
when 'custom_sort_children'
|
186
|
-
if (value == 0)
|
187
|
-
page.children.each do |p|
|
188
|
-
p.sort_order = 1
|
189
|
-
p.save
|
190
|
-
end
|
191
|
-
end
|
192
|
-
page.custom_sort_children = value
|
193
|
-
|
194
|
-
when 'viewers'
|
195
|
-
Page.update_authorized_for_action(page.id, 'view', value)
|
196
|
-
when 'editors'
|
197
|
-
Page.update_authorized_for_action(page.id, 'edit', value)
|
198
|
-
when 'approvers'
|
199
|
-
Page.update_authorized_for_action(page.id, 'approve', value)
|
55
|
+
when 'name' then image.name = value
|
56
|
+
when 'description' then image.description = value
|
200
57
|
end
|
201
58
|
end
|
202
59
|
|
203
|
-
resp.success = save &&
|
204
|
-
render json
|
60
|
+
resp.success = save && image.save
|
61
|
+
render :json => resp
|
205
62
|
end
|
206
63
|
|
207
|
-
# DELETE /admin/images
|
64
|
+
# DELETE /admin/images/:id
|
208
65
|
def admin_delete
|
209
66
|
return unless user_is_allowed('images', 'delete')
|
210
|
-
|
211
|
-
p.destroy
|
212
|
-
|
67
|
+
img = MediaImage.find(params[:id])
|
213
68
|
resp = StdClass.new({
|
214
|
-
'redirect' =>
|
69
|
+
'redirect' => "/admin/images?media_category_id=#{img.media_category_id}"
|
215
70
|
})
|
216
|
-
|
71
|
+
img.destroy
|
72
|
+
render :json => resp
|
217
73
|
end
|
218
|
-
|
219
|
-
## PUT /admin/images/sign-s3
|
220
|
-
#def admin_sign_s3
|
221
|
-
# return unless user_is_allowed('images', 'add')
|
222
|
-
#
|
223
|
-
# config = YAML.load(File.read(Rails.root.join('config', 'aws.yml')))[Rails.env]
|
224
|
-
# access_key = config['access_key_id']
|
225
|
-
# secret_key = config['secret_access_key']
|
226
|
-
# bucket = config['bucket']
|
227
|
-
# s3 = AWS::S3.new(
|
228
|
-
# :access_key_id => access_key,
|
229
|
-
# :secret_access_key => secret_key
|
230
|
-
# )
|
231
|
-
#
|
232
|
-
# name = params[:name]
|
233
|
-
# mi = MediaImage.create(
|
234
|
-
# :media_category_id => params[:media_category_id],
|
235
|
-
# :name => params[:name]
|
236
|
-
# )
|
237
|
-
# pp = s3.buckets[bucket].presigned_post(
|
238
|
-
# :key => "media-images/test.jpg", #{mi.id}.#{File.extname(name)}",
|
239
|
-
# :expires => DateTime.now + 10.seconds,
|
240
|
-
# :success_action_status => 201,
|
241
|
-
# :acl => :public_read
|
242
|
-
# )
|
243
|
-
#
|
244
|
-
# render :json => {
|
245
|
-
# 'media_image' => mi,
|
246
|
-
# 'presigned_post' => {
|
247
|
-
# 'url' => pp.url.to_s,
|
248
|
-
# 'fields' => pp.fields
|
249
|
-
# }
|
250
|
-
# }
|
251
|
-
#
|
252
|
-
# #expires = (DateTime.now.utc + 10.seconds).to_i
|
253
|
-
# #amz_headers = "x-amz-acl:public-read"
|
254
|
-
# #put_request = "PUT\n\n#{mime_type}\n#{expires}\n#{amz_headers}\n/#{bucket}/media-images/#{object_name}"
|
255
|
-
# #signature = CGI.escape(Base64.encode64("#{OpenSSL::HMAC.digest('sha1', secret_key, put_request)}\n"))
|
256
|
-
# ##signature = base64.encodestring(hmac.new(secret_key, put_request, sha1).digest())
|
257
|
-
# ##signature = urllib.quote_plus(signature.strip())
|
258
|
-
# #render :json => {
|
259
|
-
# # 'signed_request' => "#{url}?AWSAccessKeyId=#{access_key}&Expires=#{expires}&Signature=#{signature}",
|
260
|
-
# # 'url' => url
|
261
|
-
# #}
|
262
|
-
#
|
263
|
-
# #pp = AWS::S3::PresignedPost.new(s3.buckets[bucket],
|
264
|
-
# # :key => "media-images/#{object_name}",
|
265
|
-
# # :expires => DateTime.now + 10.seconds,
|
266
|
-
# # :content_type => mime_type
|
267
|
-
# #)
|
268
|
-
# #url = "#{pp.url.to_s}#{pp.key}" #"https://#{pp.bucket.name}.s3.amazonaws.com/#{pp.key}"
|
269
|
-
# #render :json => {
|
270
|
-
# # 'signed_request' => "#{url}?AWSAccessKeyId=#{access_key}&Expires=#{pp.expires.to_time.to_i}&Signature=#{pp.fields[:signature]}",
|
271
|
-
# # 'url' => url
|
272
|
-
# #}
|
273
|
-
#
|
274
|
-
#end
|
275
74
|
|
276
75
|
# GET /admin/images/sign-s3
|
277
76
|
def admin_sign_s3
|
@@ -291,7 +90,7 @@ module Caboose
|
|
291
90
|
policy = {
|
292
91
|
"expiration" => 10.seconds.from_now.utc.xmlschema,
|
293
92
|
"conditions" => [
|
294
|
-
{ "bucket" =>
|
93
|
+
{ "bucket" => bucket },
|
295
94
|
["starts-with", "$key", key],
|
296
95
|
{ "acl" => "public-read" },
|
297
96
|
{ "success_action_status" => "200" }
|
@@ -324,10 +123,27 @@ module Caboose
|
|
324
123
|
# GET /admin/images/:id/process
|
325
124
|
def admin_process
|
326
125
|
return if !user_is_allowed('images', 'edit')
|
327
|
-
mi = MediaImage.find(params[:id])
|
126
|
+
mi = MediaImage.find(params[:id])
|
328
127
|
mi.delay.process
|
329
128
|
render :json => true
|
330
129
|
end
|
130
|
+
|
131
|
+
## GET /admin/images/:id/finished
|
132
|
+
def admin_process_finished
|
133
|
+
return if !user_is_allowed('images', 'edit')
|
134
|
+
mi = MediaImage.find(params[:id])
|
135
|
+
resp = StdClass.new
|
136
|
+
if mi.image_file_name && mi.image_file_name.strip.length > 0
|
137
|
+
resp.is_finished = true
|
138
|
+
resp.tiny_url = mi.image.url(:tiny)
|
139
|
+
resp.thumb_url = mi.image.url(:thumb)
|
140
|
+
resp.large_url = mi.image.url(:large)
|
141
|
+
resp.original_url = mi.image.url(:original)
|
142
|
+
else
|
143
|
+
resp.is_finished = false
|
144
|
+
end
|
145
|
+
render :json => resp
|
146
|
+
end
|
331
147
|
|
332
148
|
end
|
333
149
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
|
2
|
+
module Caboose
|
3
|
+
class MediaCategoriesController < ApplicationController
|
4
|
+
|
5
|
+
# POST /admin/media-categories
|
6
|
+
def admin_add
|
7
|
+
return unless user_is_allowed('mediacategories', 'add')
|
8
|
+
|
9
|
+
resp = Caboose::StdClass.new
|
10
|
+
|
11
|
+
cat = MediaCategory.new(
|
12
|
+
:site_id => @site.id,
|
13
|
+
:parent_id => params[:parent_id],
|
14
|
+
:name => params[:name]
|
15
|
+
)
|
16
|
+
if !cat.save
|
17
|
+
resp.error = cat.errors.first[1]
|
18
|
+
else
|
19
|
+
resp.refresh = true
|
20
|
+
end
|
21
|
+
|
22
|
+
render :json => resp
|
23
|
+
end
|
24
|
+
|
25
|
+
# PUT /admin/media-categories/:id
|
26
|
+
def admin_update
|
27
|
+
return unless user_is_allowed('mediacategories', 'edit')
|
28
|
+
|
29
|
+
resp = StdClass.new
|
30
|
+
cat = MediaCategory.find(params[:id])
|
31
|
+
|
32
|
+
save = true
|
33
|
+
params.each do |name, value|
|
34
|
+
case name
|
35
|
+
when 'name' then cat.name = value
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
resp.success = save && cat.save
|
40
|
+
render :json => resp
|
41
|
+
end
|
42
|
+
|
43
|
+
# DELETE /admin/media-categories/:id
|
44
|
+
def admin_delete
|
45
|
+
return unless user_is_allowed('mediacategories', 'delete')
|
46
|
+
cat = MediaCategory.find(params[:id])
|
47
|
+
cat.destroy
|
48
|
+
|
49
|
+
resp = StdClass.new({
|
50
|
+
'redirect' => '/admin/media-categories'
|
51
|
+
})
|
52
|
+
render :json => resp
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -14,5 +14,17 @@ class Caboose::MediaCategory < ActiveRecord::Base
|
|
14
14
|
def self.top_file_category(site_id)
|
15
15
|
return self.where("parent_id is null and site_id = ? and name = ?", site_id, 'Files').first
|
16
16
|
end
|
17
|
+
|
18
|
+
def api_hash
|
19
|
+
{
|
20
|
+
:id => self.id,
|
21
|
+
:parent_id => self.parent_id,
|
22
|
+
:site_id => self.site_id,
|
23
|
+
:name => self.name,
|
24
|
+
:children => self.children.collect { |child| child.api_hash },
|
25
|
+
:images => self.media_images.collect { |img| img.api_hash },
|
26
|
+
:files => self.media_files.collect { |file| file.api_hash }
|
27
|
+
}
|
28
|
+
end
|
17
29
|
|
18
30
|
end
|
@@ -5,5 +5,14 @@ class Caboose::MediaFile < ActiveRecord::Base
|
|
5
5
|
has_attached_file :file, :path => 'media-files/:id.:extension'
|
6
6
|
do_not_validate_attachment_file_type :file
|
7
7
|
attr_accessible :id, :media_category_id, :name, :description
|
8
|
+
|
9
|
+
def api_hash
|
10
|
+
{
|
11
|
+
:id => self.id,
|
12
|
+
:name => self.name,
|
13
|
+
:description => self.description,
|
14
|
+
:url => self.file.url
|
15
|
+
}
|
16
|
+
end
|
8
17
|
|
9
18
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'uri'
|
2
|
+
require 'httparty'
|
2
3
|
|
3
4
|
class Caboose::MediaImage < ActiveRecord::Base
|
4
5
|
|
@@ -16,9 +17,27 @@ class Caboose::MediaImage < ActiveRecord::Base
|
|
16
17
|
attr_accessible :id, :media_category_id, :name, :description
|
17
18
|
|
18
19
|
def process
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
|
21
|
+
config = YAML.load(File.read(Rails.root.join('config', 'aws.yml')))[Rails.env]
|
22
|
+
bucket = config['bucket']
|
23
|
+
|
24
|
+
uri = "http://#{bucket}.s3.amazonaws.com/media-images/#{self.id}#{File.extname(self.name.downcase)}"
|
25
|
+
puts "Processing #{uri}..."
|
26
|
+
|
27
|
+
self.image = URI.parse(uri)
|
28
|
+
self.save
|
29
|
+
end
|
30
|
+
|
31
|
+
def api_hash
|
32
|
+
{
|
33
|
+
:id => self.id,
|
34
|
+
:name => self.name,
|
35
|
+
:description => self.description,
|
36
|
+
:tiny_url => self.image.url(:tiny),
|
37
|
+
:thumb_url => self.image.url(:thumb),
|
38
|
+
:large_url => self.image.url(:large),
|
39
|
+
:original_url => self.image.url(:original)
|
40
|
+
}
|
22
41
|
end
|
23
42
|
|
24
43
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'faye/websocket'
|
2
|
+
|
3
|
+
module Caboose
|
4
|
+
class MediaImageSocket
|
5
|
+
|
6
|
+
KEEPALIVE_TIME = 15 # in seconds
|
7
|
+
|
8
|
+
def initialize(app)
|
9
|
+
@app = app
|
10
|
+
@clients = {}
|
11
|
+
@image_ids = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
if Faye::WebSocket.websocket?(env)
|
16
|
+
|
17
|
+
uri = env['REQUEST_URI']
|
18
|
+
#Caboose.log(uri)
|
19
|
+
|
20
|
+
# GET /admin/images/:id/wait
|
21
|
+
if uri =~ /\/admin\/images\/\d*\/wait/
|
22
|
+
image_id = uri.gsub('/admin/images/', '').gsub('/wait', '').to_i
|
23
|
+
#Caboose.log("Waiting on image_id #{image_id}...")
|
24
|
+
ws = Faye::WebSocket.new(env, nil, { :ping => KEEPALIVE_TIME })
|
25
|
+
ws.on :open do |event|
|
26
|
+
Caboose.log("Opening browser web socket for image #{image_id}...")
|
27
|
+
@clients[image_id] = [] if @clients[image_id].nil?
|
28
|
+
@clients[image_id] << ws
|
29
|
+
end
|
30
|
+
ws.on :message do |event|
|
31
|
+
Caboose.log("Received browser message for image #{image_id}")
|
32
|
+
@clients[image_id].each { |client| client.send(event.data) }
|
33
|
+
end
|
34
|
+
ws.on :close do |event|
|
35
|
+
Caboose.log("Closing browser web socket for image #{image_id}...")
|
36
|
+
#p [:close, ws.object_id, event.code, event.reason]
|
37
|
+
@clients.delete(ws)
|
38
|
+
ws = nil
|
39
|
+
end
|
40
|
+
ws.rack_response
|
41
|
+
|
42
|
+
# GET /admin/images/:id/finished
|
43
|
+
elsif uri =~ /\/admin\/images\/\d*\/finished/
|
44
|
+
image_id = uri.gsub('/admin/images/', '').gsub('/finished', '').to_i
|
45
|
+
ws = Faye::WebSocket.new(env, nil, { :ping => KEEPALIVE_TIME })
|
46
|
+
ws.on :open do |event|
|
47
|
+
#p [:open, ws.object_id]
|
48
|
+
Caboose.log("Opening server web socket for image #{image_id}...")
|
49
|
+
@image_ids[ws.object_id] = image_id
|
50
|
+
end
|
51
|
+
ws.on :message do |event|
|
52
|
+
#p [:message, event.data]
|
53
|
+
Caboose.log("Receieved server message for image #{image_id}")
|
54
|
+
image_id = @image_ids[ws.object_id]
|
55
|
+
@clients[image_id].each { |client| client.send(event.data) }
|
56
|
+
end
|
57
|
+
ws.on :close do |event|
|
58
|
+
#p [:close, ws.object_id, event.code, event.reason]
|
59
|
+
Caboose.log("Closing server web socket for image #{image_id}...")
|
60
|
+
@image_ids.delete(ws.object_id)
|
61
|
+
ws = nil
|
62
|
+
end
|
63
|
+
ws.rack_response
|
64
|
+
end
|
65
|
+
|
66
|
+
else
|
67
|
+
@app.call(env)
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
@@ -136,14 +136,16 @@ class Caboose::Schema < Caboose::Utilities::Schema
|
|
136
136
|
[ :name , :string ]
|
137
137
|
],
|
138
138
|
Caboose::MediaImage => [
|
139
|
-
[ :media_category_id , :integer
|
140
|
-
[ :name , :string
|
141
|
-
[ :description , :text
|
139
|
+
[ :media_category_id , :integer ],
|
140
|
+
[ :name , :string ],
|
141
|
+
[ :description , :text ],
|
142
|
+
[ :image , :attachment ]
|
142
143
|
],
|
143
144
|
Caboose::MediaFile => [
|
144
|
-
[ :media_category_id , :integer
|
145
|
-
[ :name , :string
|
146
|
-
[ :description , :text
|
145
|
+
[ :media_category_id , :integer ],
|
146
|
+
[ :name , :string ],
|
147
|
+
[ :description , :text ],
|
148
|
+
[ :file , :attachment ]
|
147
149
|
],
|
148
150
|
Caboose::Page => [
|
149
151
|
[ :site_id , :integer ],
|
@@ -0,0 +1,60 @@
|
|
1
|
+
<%
|
2
|
+
img = @media_image
|
3
|
+
%>
|
4
|
+
<div id='crumbtrail'>
|
5
|
+
<a href='/admin'>Admin</a> >
|
6
|
+
<a href='/admin/images'>Images</a>
|
7
|
+
</div>
|
8
|
+
|
9
|
+
<h1>Edit Image</h1>
|
10
|
+
<img src='<%= img.image.url(:thumb) %>' style='float: right;' />
|
11
|
+
<p><div id='mediaimage_<%= img.id %>_name' ></div></p>
|
12
|
+
<p><div id='mediaimage_<%= img.id %>_description' ></div></p>
|
13
|
+
|
14
|
+
<div id='message'></div>
|
15
|
+
<p>
|
16
|
+
<input type='button' value='< Back' onclick="window.location='/admin/images?media_category_id=<%= img.media_category_id %>';" />
|
17
|
+
<input type='button' value='Delete Image' onclick="delete_image(<%= img.id %>);" />
|
18
|
+
</p>
|
19
|
+
|
20
|
+
<% content_for :caboose_js do %>
|
21
|
+
<%= javascript_include_tag "caboose/model/all" %>
|
22
|
+
<script type="text/javascript">
|
23
|
+
|
24
|
+
function delete_image(image_id, confirm)
|
25
|
+
{
|
26
|
+
if (!confirm)
|
27
|
+
{
|
28
|
+
var p = $('<p/>').addClass('note warning')
|
29
|
+
.append('Are you sure you want to delete the image? ')
|
30
|
+
.append($('<input/>').attr('type', 'button').val('Yes').click(function() { delete_image(image_id, true); })).append(" ")
|
31
|
+
.append($('<input/>').attr('type', 'button').val('No' ).click(function() { $('#message').empty(); }));
|
32
|
+
$('#message').empty().append(p);
|
33
|
+
return;
|
34
|
+
}
|
35
|
+
$('#message').empty().append($('<p/>').addClass('loading').html('Deleting image...'));
|
36
|
+
$.ajax({
|
37
|
+
url: '/admin/images/' + image_id,
|
38
|
+
type: 'delete',
|
39
|
+
success: function(resp) {
|
40
|
+
if (resp.error) $('#message').empty().append($('<p/>').addClass('note error').html(resp.error));
|
41
|
+
if (resp.redirect) window.location = resp.redirect;
|
42
|
+
}
|
43
|
+
});
|
44
|
+
}
|
45
|
+
|
46
|
+
$(document).ready(function() {
|
47
|
+
m = new ModelBinder({
|
48
|
+
name: 'MediaImage',
|
49
|
+
id: <%= img.id %>,
|
50
|
+
update_url: '/admin/images/<%= img.id %>',
|
51
|
+
authenticity_token: '<%= form_authenticity_token %>',
|
52
|
+
attributes: [
|
53
|
+
{ name: 'name' , nice_name: 'Name' , type: 'text' , value: <%= raw Caboose.json(img.name) %>, width: 400 },
|
54
|
+
{ name: 'description' , nice_name: 'Description' , type: 'textarea' , value: <%= raw Caboose.json(img.description) %>, width: 400, height: 200 }
|
55
|
+
]
|
56
|
+
});
|
57
|
+
});
|
58
|
+
|
59
|
+
</script>
|
60
|
+
<% end %>
|
@@ -1,106 +1,57 @@
|
|
1
1
|
<h1>Images</h1>
|
2
2
|
|
3
|
-
<% if @
|
3
|
+
<% if @site && @media_category %>
|
4
|
+
<%
|
5
|
+
arr = []
|
6
|
+
cat = @media_category
|
7
|
+
arr << cat
|
8
|
+
while cat.parent_id
|
9
|
+
cat = cat.parent
|
10
|
+
arr << cat
|
11
|
+
end
|
12
|
+
crumb_trail = arr.collect{ |cat| "<a href='/admin/images?media_category_id=#{cat.id}'>#{cat.name}</a>" }.reverse.join(" > ")
|
13
|
+
%>
|
14
|
+
<p id='crumb_trail'><%= raw crumb_trail %></p>
|
15
|
+
|
4
16
|
<form action='/admin/images/sign-s3' method='post' id='new_image_form' enctype='multipart/form-data'>
|
5
17
|
<input type='hidden' name='key' value='' />
|
6
18
|
<input type='hidden' name='AWSAccessKeyId' value='' />
|
7
19
|
<input type='hidden' name='acl' value='' />
|
8
|
-
<input type='hidden' name='success_action_status' value='' />
|
9
|
-
<!--<input type='hidden' name='success_action_redirect' value='' />-->
|
20
|
+
<input type='hidden' name='success_action_status' value='' />
|
10
21
|
<input type='hidden' name='policy' value='' />
|
11
|
-
<input type='hidden' name='signature' value='' />
|
12
|
-
<input type="file" name="file" id="file" multiple='true' />
|
22
|
+
<input type='hidden' name='signature' value='' />
|
23
|
+
<input type="file" name="file" id="file" multiple='true' style='display: none;' />
|
24
|
+
<p>
|
25
|
+
<a href='#' id='new_cat_link'>New Category</a> |
|
26
|
+
<a href='#' onclick="$('#file').click();">Upload Files</a>
|
27
|
+
</p>
|
13
28
|
<div id='progress'><div id='bar'></div></div>
|
14
|
-
</form>
|
15
|
-
<
|
16
|
-
</p>
|
17
|
-
|
18
|
-
|
19
|
-
<% @media_category.children.each do |cat| %>
|
20
|
-
<li class='category' id='cat<%= cat.id %>'><a href='/admin/images?media_category_id=<%= cat.id %>'><%= cat.name %></a></li>
|
21
|
-
<% end %>
|
22
|
-
<% @media_category.media_images.each do |mi| %>
|
23
|
-
<li class='image' id='image<%= mi.id %>'><a href='/admin/images/<%= mi.id %>'><img src='<%= mi.image.url(:thumb) %>' /><span><%= mi.name %></span></a></li>
|
24
|
-
<% end %>
|
25
|
-
</ul>
|
26
|
-
<% else %>
|
27
|
-
<p>This category is empty.</p>
|
28
|
-
<% end %>
|
29
|
-
<% elsif @domain && @media_category.nil? %>
|
29
|
+
</form>
|
30
|
+
<div id='new_cat_message'></div>
|
31
|
+
</p>
|
32
|
+
<div id='media'></div>
|
33
|
+
<% elsif @site && @media_category.nil? %>
|
30
34
|
<p>Invalid media category.</p>
|
31
35
|
<% else %>
|
32
36
|
<p>It doesn't look like this site is configured for the current domain. Please <a href='/admin/sites'>configure your sites</a>.</p>
|
33
37
|
<% end %>
|
34
38
|
|
35
39
|
<% content_for :caboose_css do %>
|
36
|
-
|
37
|
-
|
38
|
-
ul.media li.image { list-style: none; margin: 0; padding: 0; float: left; }
|
39
|
-
ul.media li.image img {}
|
40
|
-
.progress { max-width: 600px; margin: 0.2em 0 0.2em 0; }
|
41
|
-
.progress .bar { height: 1.2em; padding: 0.2em; color: white; display: none; }
|
42
|
-
</style>
|
40
|
+
<%= stylesheet_link_tag 'caboose/icomoon_fonts' %>
|
41
|
+
<%= stylesheet_link_tag 'caboose/admin_images_index' %>
|
43
42
|
<% end %>
|
44
43
|
|
45
44
|
<% content_for :caboose_js do %>
|
46
45
|
<%= javascript_include_tag 'jquery.ui.widget' %>
|
47
46
|
<%= javascript_include_tag 'caboose/jquery.iframe-transport.js' %>
|
48
47
|
<%= javascript_include_tag 'caboose/jquery.fileupload.js' %>
|
48
|
+
<%= javascript_include_tag 'caboose/admin_images_index.js' %>
|
49
49
|
<script type='text/javascript'>
|
50
50
|
|
51
|
-
var
|
52
|
-
$(document).ready(function() {
|
53
|
-
|
54
|
-
|
55
|
-
autoUpload: true,
|
56
|
-
//replaceFileInput: true,
|
57
|
-
//singleFileUploads: false,
|
58
|
-
add: function(e, data) {
|
59
|
-
$.ajax({
|
60
|
-
url: '/admin/images/s3',
|
61
|
-
type: 'get',
|
62
|
-
data: {
|
63
|
-
name: data.files[0].name,
|
64
|
-
media_category_id: <%= @media_category.id %>
|
65
|
-
},
|
66
|
-
async: false,
|
67
|
-
success: function(resp) {
|
68
|
-
image_ids.push(resp.media_image_id);
|
69
|
-
var form = $('#new_image_form');
|
70
|
-
for (var i in resp.fields)
|
71
|
-
form.find("input[name=" + i + "]").val(resp.fields[i]);
|
72
|
-
form.attr('action', resp.url);
|
73
|
-
}
|
74
|
-
});
|
75
|
-
data.submit();
|
76
|
-
},
|
77
|
-
progressall: function (e, data) {
|
78
|
-
$('#bar').css('width', parseInt(data.loaded / data.total * 100, 10) + '%')
|
79
|
-
},
|
80
|
-
start: function (e) {
|
81
|
-
$('#file').hide();
|
82
|
-
$('#bar').css('background', 'green').css('display', 'block').css('width', '0%').html(" ");
|
83
|
-
},
|
84
|
-
done: function(e, data) {
|
85
|
-
console.log("Upload done.");
|
86
|
-
console.log(data);
|
87
|
-
setTimeout(function() {
|
88
|
-
$.each(image_ids, function(i, id) {
|
89
|
-
$.ajax({
|
90
|
-
url: '/admin/images/' + id + '/process',
|
91
|
-
type: 'get',
|
92
|
-
async: false,
|
93
|
-
success: function(resp) {}
|
94
|
-
});
|
95
|
-
});
|
96
|
-
window.location.reload(true);
|
97
|
-
}, 500);
|
98
|
-
},
|
99
|
-
fail: function(e, data) {
|
100
|
-
console.log("Upload failed.");
|
101
|
-
console.log(data);
|
102
|
-
$('#bar').css("background", "red").text("Failed");
|
103
|
-
}
|
51
|
+
var controller = false;
|
52
|
+
$(document).ready(function() {
|
53
|
+
controller = new ImagesController({
|
54
|
+
cat_id: <%= @media_category.id %>
|
104
55
|
});
|
105
56
|
});
|
106
57
|
|
data/config/routes.rb
CHANGED
@@ -73,13 +73,18 @@ Caboose::Engine.routes.draw do
|
|
73
73
|
get "admin/images/s3" => "images#admin_sign_s3"
|
74
74
|
get "admin/images/s3-result" => "images#admin_s3_result"
|
75
75
|
get "admin/images/new" => "images#admin_new"
|
76
|
+
get "admin/images/json" => "images#admin_json"
|
76
77
|
get "admin/images/:id/process" => "images#admin_process"
|
78
|
+
get "admin/images/:id/finished" => "images#admin_process_finished"
|
77
79
|
get "admin/images/:id" => "images#admin_edit"
|
78
80
|
put "admin/images/:id" => "images#admin_update"
|
79
81
|
post "admin/images/:id/image" => "images#admin_update_image"
|
80
82
|
post "admin/images" => "images#admin_add"
|
81
83
|
delete "admin/images/:id" => "images#admin_delete"
|
82
84
|
|
85
|
+
post "admin/media-categories" => "media_categories#admin_add"
|
86
|
+
put "admin/media-categories/:id" => "media_categories#admin_update"
|
87
|
+
delete "admin/media-categories/:id" => "media_categories#admin_delete"
|
83
88
|
|
84
89
|
get "admin/permissions" => "permissions#index"
|
85
90
|
get "admin/permissions/options" => "permissions#options"
|
data/lib/caboose/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: caboose-cms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.72
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William Barry
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -194,6 +194,7 @@ files:
|
|
194
194
|
- app/assets/images/caboose/search.png
|
195
195
|
- app/assets/javascripts/caboose/admin.js
|
196
196
|
- app/assets/javascripts/caboose/admin_block_edit.js
|
197
|
+
- app/assets/javascripts/caboose/admin_images_index.js
|
197
198
|
- app/assets/javascripts/caboose/admin_page_edit_content.js
|
198
199
|
- app/assets/javascripts/caboose/admin_page_edit_content_bak.js
|
199
200
|
- app/assets/javascripts/caboose/admin_page_new_blocks.js
|
@@ -231,6 +232,7 @@ files:
|
|
231
232
|
- app/assets/javascripts/caboose/testing.js
|
232
233
|
- app/assets/javascripts/tinymce/plugins/caboose/plugin.js
|
233
234
|
- app/assets/stylesheets/caboose/admin.css
|
235
|
+
- app/assets/stylesheets/caboose/admin_images_index.css
|
234
236
|
- app/assets/stylesheets/caboose/admin_page_edit_content.css
|
235
237
|
- app/assets/stylesheets/caboose/application.css
|
236
238
|
- app/assets/stylesheets/caboose/bound_input.css
|
@@ -265,6 +267,7 @@ files:
|
|
265
267
|
- app/controllers/caboose/images_controller.rb
|
266
268
|
- app/controllers/caboose/login_controller.rb
|
267
269
|
- app/controllers/caboose/logout_controller.rb
|
270
|
+
- app/controllers/caboose/media_categories_controller.rb
|
268
271
|
- app/controllers/caboose/modal_controller.rb
|
269
272
|
- app/controllers/caboose/page_permissions_controller.rb
|
270
273
|
- app/controllers/caboose/pages_controller.rb
|
@@ -302,6 +305,7 @@ files:
|
|
302
305
|
- app/models/caboose/media_category.rb
|
303
306
|
- app/models/caboose/media_file.rb
|
304
307
|
- app/models/caboose/media_image.rb
|
308
|
+
- app/models/caboose/media_image_socket.rb
|
305
309
|
- app/models/caboose/menu_block.rb
|
306
310
|
- app/models/caboose/page.rb
|
307
311
|
- app/models/caboose/page_bar_generator.rb
|
@@ -342,6 +346,7 @@ files:
|
|
342
346
|
- app/views/caboose/block_types/admin_index.html.erb
|
343
347
|
- app/views/caboose/block_types/admin_new.html.erb
|
344
348
|
- app/views/caboose/blocks/_block.html.erb
|
349
|
+
- app/views/caboose/blocks/_controller_view_content.html.erb
|
345
350
|
- app/views/caboose/blocks/_file.html.erb
|
346
351
|
- app/views/caboose/blocks/_heading.html.erb
|
347
352
|
- app/views/caboose/blocks/_html.html.erb
|
@@ -381,6 +386,8 @@ files:
|
|
381
386
|
- app/views/caboose/blocks/admin_render_second_level.json.erb
|
382
387
|
- app/views/caboose/extras/error.html.erb
|
383
388
|
- app/views/caboose/extras/error404.html.erb
|
389
|
+
- app/views/caboose/extras/error_invalid_site.html.erb
|
390
|
+
- app/views/caboose/images/admin_edit.html.erb
|
384
391
|
- app/views/caboose/images/admin_index.html.erb
|
385
392
|
- app/views/caboose/images/admin_new.html.erb
|
386
393
|
- app/views/caboose/images/admin_s3_result.html.erb
|