beet 0.4.2 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/beet.gemspec +8 -2
- data/lib/beet/files/swfupload/images/cancelbutton.gif +0 -0
- data/lib/beet/files/swfupload/images/header-bg.jpg +0 -0
- data/lib/beet/files/swfupload/images/logo.gif +0 -0
- data/lib/beet/files/swfupload/js/handlers.js +290 -0
- data/lib/beet/recipes/rails/auth/devise.rb +3 -4
- data/lib/beet/recipes/rails/db/mongo.rb +57 -0
- data/lib/beet/recipes/rails/swfupload.rb +305 -0
- metadata +8 -2
data/README.rdoc
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.3
|
data/beet.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{beet}
|
8
|
-
s.version = "0.4.
|
8
|
+
s.version = "0.4.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jack Dempsey"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2010-01-09}
|
13
13
|
s.default_executable = %q{beet}
|
14
14
|
s.email = %q{jack.dempsey@gmail.com}
|
15
15
|
s.executables = ["beet"]
|
@@ -37,6 +37,10 @@ Gem::Specification.new do |s|
|
|
37
37
|
"lib/beet/execution.rb",
|
38
38
|
"lib/beet/executor.rb",
|
39
39
|
"lib/beet/file_system.rb",
|
40
|
+
"lib/beet/files/swfupload/images/cancelbutton.gif",
|
41
|
+
"lib/beet/files/swfupload/images/header-bg.jpg",
|
42
|
+
"lib/beet/files/swfupload/images/logo.gif",
|
43
|
+
"lib/beet/files/swfupload/js/handlers.js",
|
40
44
|
"lib/beet/gem_location_map.rb",
|
41
45
|
"lib/beet/interaction.rb",
|
42
46
|
"lib/beet/logger.rb",
|
@@ -52,10 +56,12 @@ Gem::Specification.new do |s|
|
|
52
56
|
"lib/beet/recipes/rails/css/blueprint.rb",
|
53
57
|
"lib/beet/recipes/rails/css/nifty_layout.rb",
|
54
58
|
"lib/beet/recipes/rails/css/reset.rb",
|
59
|
+
"lib/beet/recipes/rails/db/mongo.rb",
|
55
60
|
"lib/beet/recipes/rails/db/mysql.rb",
|
56
61
|
"lib/beet/recipes/rails/db/postgres.rb",
|
57
62
|
"lib/beet/recipes/rails/git.rb",
|
58
63
|
"lib/beet/recipes/rails/jquery.rb",
|
64
|
+
"lib/beet/recipes/rails/swfupload.rb",
|
59
65
|
"lib/beet/recipes/rails/testing/rspec.rb",
|
60
66
|
"lib/beet/recipes/rails/testing/shoulda.rb",
|
61
67
|
"lib/beet/scm.rb",
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,290 @@
|
|
1
|
+
function fileQueueError(file, errorCode, message) {
|
2
|
+
try {
|
3
|
+
var imageName = "error.gif";
|
4
|
+
var errorName = "";
|
5
|
+
if (errorCode === SWFUpload.errorCode_QUEUE_LIMIT_EXCEEDED) {
|
6
|
+
errorName = "You have attempted to queue too many files.";
|
7
|
+
}
|
8
|
+
|
9
|
+
if (errorName !== "") {
|
10
|
+
alert(errorName);
|
11
|
+
return;
|
12
|
+
}
|
13
|
+
|
14
|
+
switch (errorCode) {
|
15
|
+
case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
|
16
|
+
imageName = "zerobyte.gif";
|
17
|
+
break;
|
18
|
+
case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
|
19
|
+
imageName = "toobig.gif";
|
20
|
+
break;
|
21
|
+
case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
|
22
|
+
case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
|
23
|
+
default:
|
24
|
+
alert(message);
|
25
|
+
break;
|
26
|
+
}
|
27
|
+
|
28
|
+
addImage("images/swfupload/" + imageName);
|
29
|
+
|
30
|
+
} catch (ex) {
|
31
|
+
this.debug(ex);
|
32
|
+
}
|
33
|
+
|
34
|
+
}
|
35
|
+
|
36
|
+
function fileDialogComplete(numFilesSelected, numFilesQueued) {
|
37
|
+
try {
|
38
|
+
if (numFilesQueued > 0) {
|
39
|
+
this.startUpload();
|
40
|
+
}
|
41
|
+
} catch (ex) {
|
42
|
+
this.debug(ex);
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
function uploadProgress(file, bytesLoaded) {
|
47
|
+
|
48
|
+
try {
|
49
|
+
var percent = Math.ceil((bytesLoaded / file.size) * 100);
|
50
|
+
|
51
|
+
var progress = new FileProgress(file, this.customSettings.upload_target);
|
52
|
+
progress.setProgress(percent);
|
53
|
+
if (percent === 100) {
|
54
|
+
progress.setStatus("Processing file...");
|
55
|
+
progress.toggleCancel(false, this);
|
56
|
+
} else {
|
57
|
+
progress.setStatus("Uploading...");
|
58
|
+
progress.toggleCancel(true, this);
|
59
|
+
}
|
60
|
+
} catch (ex) {
|
61
|
+
this.debug(ex);
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
function uploadSuccess(file, serverData) {
|
66
|
+
try {
|
67
|
+
$('#mp3info').append("<p>"+serverData+"</p>");
|
68
|
+
var progress = new FileProgress(file, this.customSettings.upload_target);
|
69
|
+
|
70
|
+
if (serverData.substring(0, 2) === "OK") {
|
71
|
+
//addImage("thumbnail.php?id=" + serverData.substring(7));
|
72
|
+
|
73
|
+
progress.setStatus("Upload Successfull.");
|
74
|
+
progress.toggleCancel(false);
|
75
|
+
} else {
|
76
|
+
addImage("/images/swfupload/error.gif");
|
77
|
+
progress.setStatus("Error.");
|
78
|
+
progress.toggleCancel(false);
|
79
|
+
alert(serverData);
|
80
|
+
|
81
|
+
}
|
82
|
+
|
83
|
+
|
84
|
+
} catch (ex) {
|
85
|
+
this.debug(ex);
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
function uploadComplete(file) {
|
90
|
+
try {
|
91
|
+
/* I want the next upload to continue automatically so I'll call startUpload here */
|
92
|
+
if (this.getStats().files_queued > 0) {
|
93
|
+
this.startUpload();
|
94
|
+
} else {
|
95
|
+
var progress = new FileProgress(file, this.customSettings.upload_target);
|
96
|
+
progress.setComplete();
|
97
|
+
progress.setStatus("All files received.");
|
98
|
+
progress.toggleCancel(false);
|
99
|
+
}
|
100
|
+
} catch (ex) {
|
101
|
+
this.debug(ex);
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
function uploadError(file, errorCode, message) {
|
106
|
+
var imageName = "error.gif";
|
107
|
+
var progress;
|
108
|
+
try {
|
109
|
+
switch (errorCode) {
|
110
|
+
case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
|
111
|
+
try {
|
112
|
+
progress = new FileProgress(file, this.customSettings.upload_target);
|
113
|
+
progress.setCancelled();
|
114
|
+
progress.setStatus("Cancelled");
|
115
|
+
progress.toggleCancel(false);
|
116
|
+
}
|
117
|
+
catch (ex1) {
|
118
|
+
this.debug(ex1);
|
119
|
+
}
|
120
|
+
break;
|
121
|
+
case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
|
122
|
+
try {
|
123
|
+
progress = new FileProgress(file, this.customSettings.upload_target);
|
124
|
+
progress.setCancelled();
|
125
|
+
progress.setStatus("Stopped");
|
126
|
+
progress.toggleCancel(true);
|
127
|
+
}
|
128
|
+
catch (ex2) {
|
129
|
+
this.debug(ex2);
|
130
|
+
}
|
131
|
+
case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
|
132
|
+
imageName = "uploadlimit.gif";
|
133
|
+
break;
|
134
|
+
default:
|
135
|
+
alert(message);
|
136
|
+
break;
|
137
|
+
}
|
138
|
+
|
139
|
+
addImage("/images/swfupload/" + imageName);
|
140
|
+
|
141
|
+
} catch (ex3) {
|
142
|
+
this.debug(ex3);
|
143
|
+
}
|
144
|
+
|
145
|
+
}
|
146
|
+
|
147
|
+
|
148
|
+
function addImage(src) {
|
149
|
+
var newImg = document.createElement("img");
|
150
|
+
newImg.style.margin = "5px";
|
151
|
+
|
152
|
+
document.getElementById("thumbnails").appendChild(newImg);
|
153
|
+
if (newImg.filters) {
|
154
|
+
try {
|
155
|
+
newImg.filters.item("DXImageTransform.Microsoft.Alpha").opacity = 0;
|
156
|
+
} catch (e) {
|
157
|
+
// If it is not set initially, the browser will throw an error. This will set it if it is not set yet.
|
158
|
+
newImg.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + 0 + ')';
|
159
|
+
}
|
160
|
+
} else {
|
161
|
+
newImg.style.opacity = 0;
|
162
|
+
}
|
163
|
+
|
164
|
+
newImg.onload = function () {
|
165
|
+
fadeIn(newImg, 0);
|
166
|
+
};
|
167
|
+
newImg.src = src;
|
168
|
+
}
|
169
|
+
|
170
|
+
function fadeIn(element, opacity) {
|
171
|
+
var reduceOpacityBy = 5;
|
172
|
+
var rate = 30; // 15 fps
|
173
|
+
|
174
|
+
|
175
|
+
if (opacity < 100) {
|
176
|
+
opacity += reduceOpacityBy;
|
177
|
+
if (opacity > 100) {
|
178
|
+
opacity = 100;
|
179
|
+
}
|
180
|
+
|
181
|
+
if (element.filters) {
|
182
|
+
try {
|
183
|
+
element.filters.item("DXImageTransform.Microsoft.Alpha").opacity = opacity;
|
184
|
+
} catch (e) {
|
185
|
+
// If it is not set initially, the browser will throw an error. This will set it if it is not set yet.
|
186
|
+
element.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + opacity + ')';
|
187
|
+
}
|
188
|
+
} else {
|
189
|
+
element.style.opacity = opacity / 100;
|
190
|
+
}
|
191
|
+
}
|
192
|
+
|
193
|
+
if (opacity < 100) {
|
194
|
+
setTimeout(function () {
|
195
|
+
fadeIn(element, opacity);
|
196
|
+
}, rate);
|
197
|
+
}
|
198
|
+
}
|
199
|
+
|
200
|
+
|
201
|
+
|
202
|
+
/* ******************************************
|
203
|
+
* FileProgress Object
|
204
|
+
* Control object for displaying file info
|
205
|
+
* ****************************************** */
|
206
|
+
|
207
|
+
function FileProgress(file, targetID) {
|
208
|
+
this.fileProgressID = "divFileProgress";
|
209
|
+
|
210
|
+
this.fileProgressWrapper = document.getElementById(this.fileProgressID);
|
211
|
+
if (!this.fileProgressWrapper) {
|
212
|
+
this.fileProgressWrapper = document.createElement("div");
|
213
|
+
this.fileProgressWrapper.className = "progressWrapper";
|
214
|
+
this.fileProgressWrapper.id = this.fileProgressID;
|
215
|
+
|
216
|
+
this.fileProgressElement = document.createElement("div");
|
217
|
+
this.fileProgressElement.className = "progressContainer";
|
218
|
+
|
219
|
+
var progressCancel = document.createElement("a");
|
220
|
+
progressCancel.className = "progressCancel";
|
221
|
+
progressCancel.href = "#";
|
222
|
+
progressCancel.style.visibility = "hidden";
|
223
|
+
progressCancel.appendChild(document.createTextNode(" "));
|
224
|
+
|
225
|
+
var progressText = document.createElement("div");
|
226
|
+
progressText.className = "progressName";
|
227
|
+
progressText.appendChild(document.createTextNode(file.name));
|
228
|
+
|
229
|
+
var progressBar = document.createElement("div");
|
230
|
+
progressBar.className = "progressBarInProgress";
|
231
|
+
|
232
|
+
var progressStatus = document.createElement("div");
|
233
|
+
progressStatus.className = "progressBarStatus";
|
234
|
+
progressStatus.innerHTML = " ";
|
235
|
+
|
236
|
+
this.fileProgressElement.appendChild(progressCancel);
|
237
|
+
this.fileProgressElement.appendChild(progressText);
|
238
|
+
this.fileProgressElement.appendChild(progressStatus);
|
239
|
+
this.fileProgressElement.appendChild(progressBar);
|
240
|
+
|
241
|
+
this.fileProgressWrapper.appendChild(this.fileProgressElement);
|
242
|
+
|
243
|
+
document.getElementById(targetID).appendChild(this.fileProgressWrapper);
|
244
|
+
fadeIn(this.fileProgressWrapper, 0);
|
245
|
+
|
246
|
+
} else {
|
247
|
+
this.fileProgressElement = this.fileProgressWrapper.firstChild;
|
248
|
+
this.fileProgressElement.childNodes[1].firstChild.nodeValue = file.name;
|
249
|
+
}
|
250
|
+
|
251
|
+
this.height = this.fileProgressWrapper.offsetHeight;
|
252
|
+
|
253
|
+
}
|
254
|
+
FileProgress.prototype.setProgress = function (percentage) {
|
255
|
+
this.fileProgressElement.className = "progressContainer green";
|
256
|
+
this.fileProgressElement.childNodes[3].className = "progressBarInProgress";
|
257
|
+
this.fileProgressElement.childNodes[3].style.width = percentage + "%";
|
258
|
+
};
|
259
|
+
FileProgress.prototype.setComplete = function () {
|
260
|
+
this.fileProgressElement.className = "progressContainer blue";
|
261
|
+
this.fileProgressElement.childNodes[3].className = "progressBarComplete";
|
262
|
+
this.fileProgressElement.childNodes[3].style.width = "";
|
263
|
+
|
264
|
+
};
|
265
|
+
FileProgress.prototype.setError = function () {
|
266
|
+
this.fileProgressElement.className = "progressContainer red";
|
267
|
+
this.fileProgressElement.childNodes[3].className = "progressBarError";
|
268
|
+
this.fileProgressElement.childNodes[3].style.width = "";
|
269
|
+
|
270
|
+
};
|
271
|
+
FileProgress.prototype.setCancelled = function () {
|
272
|
+
this.fileProgressElement.className = "progressContainer";
|
273
|
+
this.fileProgressElement.childNodes[3].className = "progressBarError";
|
274
|
+
this.fileProgressElement.childNodes[3].style.width = "";
|
275
|
+
|
276
|
+
};
|
277
|
+
FileProgress.prototype.setStatus = function (status) {
|
278
|
+
this.fileProgressElement.childNodes[2].innerHTML = status;
|
279
|
+
};
|
280
|
+
|
281
|
+
FileProgress.prototype.toggleCancel = function (show, swfuploadInstance) {
|
282
|
+
this.fileProgressElement.childNodes[0].style.visibility = show ? "visible" : "hidden";
|
283
|
+
if (swfuploadInstance) {
|
284
|
+
var fileID = this.fileProgressID;
|
285
|
+
this.fileProgressElement.childNodes[0].onclick = function () {
|
286
|
+
swfuploadInstance.cancelUpload(fileID);
|
287
|
+
return false;
|
288
|
+
};
|
289
|
+
}
|
290
|
+
};
|
@@ -1,5 +1,5 @@
|
|
1
|
-
gem 'warden', :version => '~> 0.5
|
2
|
-
gem 'devise', :version => '~> 0.
|
1
|
+
gem 'warden', :version => '~> 0.6.5'
|
2
|
+
gem 'devise', :version => '~> 0.7.1'
|
3
3
|
|
4
4
|
rake 'gems:install'
|
5
5
|
generate "devise_install"
|
@@ -13,8 +13,7 @@ add_after 'config/routes.rb', '# map.root :controller => "welcome"', "\n map.ro
|
|
13
13
|
rake "db:migrate"
|
14
14
|
|
15
15
|
file 'app/controllers/home_controller.rb' do
|
16
|
-
%{
|
17
|
-
class HomeController < ApplicationController
|
16
|
+
%{class HomeController < ApplicationController
|
18
17
|
def index
|
19
18
|
render :text => "Welcome!"
|
20
19
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# based on jnunemaker's gist at http://gist.github.com/232953
|
2
|
+
file 'config/database.yml' do
|
3
|
+
%{
|
4
|
+
development: &global_settings
|
5
|
+
database: #{project_name}_development
|
6
|
+
host: 127.0.0.1
|
7
|
+
port: 27017
|
8
|
+
|
9
|
+
test:
|
10
|
+
database: #{project_name}_test
|
11
|
+
<<: *global_settings
|
12
|
+
|
13
|
+
production:
|
14
|
+
host: hostname
|
15
|
+
database: databasename
|
16
|
+
username: username
|
17
|
+
password: password
|
18
|
+
<<: *global_settings
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
file 'config/initializers/mongo.rb' do
|
23
|
+
%{
|
24
|
+
config = YAML.load_file(Rails.root + 'config' + 'database.yml')[Rails.env]
|
25
|
+
|
26
|
+
MongoMapper.connection = Mongo::Connection.new(config['host'], config['port'], {
|
27
|
+
:logger => Rails.logger
|
28
|
+
})
|
29
|
+
|
30
|
+
MongoMapper.database = config['database']
|
31
|
+
if config['username'].present?
|
32
|
+
MongoMapper.database.authenticate(config['username'], config['password'])
|
33
|
+
end
|
34
|
+
|
35
|
+
Dir[Rails.root + 'app/models/**/*.rb'].each do |model_path|
|
36
|
+
File.basename(model_path, '.rb').classify.constantize
|
37
|
+
end
|
38
|
+
MongoMapper.ensure_indexes!
|
39
|
+
|
40
|
+
if defined?(PhusionPassenger)
|
41
|
+
PhusionPassenger.on_event(:starting_worker_process) do |forked|
|
42
|
+
# if using older than 0.6.5 of MM then you want database instead of connection
|
43
|
+
# MongoMapper.database.connect_to_master if forked
|
44
|
+
MongoMapper.connection.connect_to_master if forked
|
45
|
+
end
|
46
|
+
end
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
# for those who don't like keeping database.yml in version control
|
51
|
+
# we slot in an example file to serve as reference
|
52
|
+
|
53
|
+
FileUtils.copy "config/database.yml", "config/database.yml.example"
|
54
|
+
|
55
|
+
environment 'config.frameworks -= [:active_record]'
|
56
|
+
|
57
|
+
gem 'mongo_mapper'
|
@@ -0,0 +1,305 @@
|
|
1
|
+
# lots of code and ideas borrowed from http://jetpackweb.com/blog/2009/10/21/rails-2-3-4-and-swfupload-rack-middleware-for-flash-uploads-that-degrade-gracefully/
|
2
|
+
# setup directories to hold files
|
3
|
+
FileUtils.mkdir_p 'public/javascripts/swfupload'
|
4
|
+
FileUtils.mkdir_p 'public/flash/swfupload'
|
5
|
+
FileUtils.mkdir_p 'public/images/swfupload'
|
6
|
+
FileUtils.mkdir_p 'app/views/swfupload'
|
7
|
+
FileUtils.mkdir_p 'app/stylesheets'
|
8
|
+
|
9
|
+
# download plugin files
|
10
|
+
base_url = 'http://swfupload.googlecode.com/svn/swfupload/trunk/core/plugins'
|
11
|
+
|
12
|
+
js_files = %w(swfupload.cookies swfupload.queue swfupload.speed swfupload.swfobject handlers swfupload)
|
13
|
+
|
14
|
+
js_files.each do |js_file|
|
15
|
+
run "curl -L #{base_url}/#{js_file}.js > public/javascripts/swfupload/#{js_file}.js"
|
16
|
+
end
|
17
|
+
|
18
|
+
run "curl -L http://github.com/jackdempsey/beet/raw/master/lib/beet/files/swfupload/js/handlers.js > public/javascripts/swfupload/handlers.js"
|
19
|
+
run "curl -L http://swfupload.googlecode.com/svn/swfupload/trunk/core/swfupload.js > public/javascripts/swfupload/swfupload.js"
|
20
|
+
run "curl -L http://swfupload.googlecode.com/svn/swfupload/trunk/core/Flash/swfupload.swf > public/flash/swfupload/swfupload.swf"
|
21
|
+
run "chmod +x public/flash/swfupload/swfupload.swf"
|
22
|
+
run "curl -L http://github.com/jackdempsey/beet/raw/master/lib/beet/files/swfupload/images/cancelbutton.gif > public/images/swfupload/cancelbutton.gif"
|
23
|
+
|
24
|
+
file 'app/stylesheets/swfupload.sass', <<-FILE
|
25
|
+
divFileProgressContainer
|
26
|
+
height: 75px
|
27
|
+
|
28
|
+
#divFileProgress
|
29
|
+
|
30
|
+
.progressWrapper
|
31
|
+
width: 100%
|
32
|
+
overflow: hidden
|
33
|
+
|
34
|
+
.progressContainer
|
35
|
+
margin: 5px
|
36
|
+
padding: 4px
|
37
|
+
border: solid 1px #E8E8E8
|
38
|
+
background-color: #F7F7F7
|
39
|
+
overflow: hidden
|
40
|
+
|
41
|
+
.progressName
|
42
|
+
font-size: 8pt
|
43
|
+
font-weight: 700
|
44
|
+
color: #555
|
45
|
+
width: 100%
|
46
|
+
height: 14px
|
47
|
+
text-align: left
|
48
|
+
white-space: nowrap
|
49
|
+
overflow: hidden
|
50
|
+
|
51
|
+
.progressBarInProgress, .progressBarComplete, .progressBarError
|
52
|
+
font-size: 0
|
53
|
+
width: 0%
|
54
|
+
height: 2px
|
55
|
+
background-color: blue
|
56
|
+
margin-top: 2px
|
57
|
+
|
58
|
+
.progressBarComplete
|
59
|
+
width: 100%
|
60
|
+
background-color: green
|
61
|
+
visibility: hidden
|
62
|
+
|
63
|
+
.progressBarError
|
64
|
+
width: 100%
|
65
|
+
background-color: red
|
66
|
+
visibility: hidden
|
67
|
+
|
68
|
+
.progressBarStatus
|
69
|
+
margin-top: 2px
|
70
|
+
width: 337px
|
71
|
+
font-size: 7pt
|
72
|
+
font-family: Arial
|
73
|
+
text-align: left
|
74
|
+
white-space: nowrap
|
75
|
+
|
76
|
+
a.progressCancel
|
77
|
+
font-size: 0
|
78
|
+
display: block
|
79
|
+
height: 14px
|
80
|
+
width: 14px
|
81
|
+
background-image: url(/images/swfupload/cancelbutton.gif)
|
82
|
+
background-repeat: no-repeat
|
83
|
+
background-position: -14px 0px
|
84
|
+
float: right
|
85
|
+
|
86
|
+
a.progressCancel:hover
|
87
|
+
background-position: 0px 0px
|
88
|
+
FILE
|
89
|
+
|
90
|
+
# create upload partial
|
91
|
+
file 'app/views/swfupload/_upload.html.haml', %q{
|
92
|
+
- content_for :head do
|
93
|
+
= javascript_include_tag 'swfupload/swfupload', 'swfupload/swfupload.swfobject', 'swfupload/handlers'
|
94
|
+
= stylesheet_link_tag %w(compiled/swfupload)
|
95
|
+
- session_key_name = ActionController::Base.session_options[:key]
|
96
|
+
|
97
|
+
- upload_url = songs_path
|
98
|
+
- form_tag upload_url, :multipart => true do
|
99
|
+
#swfupload_degraded_container
|
100
|
+
%noscript= "You should have Javascript enabled for a nicer upload experience"
|
101
|
+
= file_field_tag :Filedata
|
102
|
+
= submit_tag "Add a File"
|
103
|
+
#swfupload_container{ :style => "display: none" }
|
104
|
+
%span#spanButtonPlaceholder
|
105
|
+
#divFileProgressContainer
|
106
|
+
|
107
|
+
|
108
|
+
:javascript
|
109
|
+
SWFUpload.onload = function() {
|
110
|
+
var swf_settings = {
|
111
|
+
|
112
|
+
// SWFObject settings
|
113
|
+
minimum_flash_version: "9.0.28",
|
114
|
+
swfupload_pre_load_handler: function() {
|
115
|
+
$('#swfupload_degraded_container').hide();
|
116
|
+
$('#swfupload_container').show();
|
117
|
+
},
|
118
|
+
swfupload_load_failed_handler: function() {
|
119
|
+
},
|
120
|
+
|
121
|
+
post_params: {
|
122
|
+
"#{session_key_name}": "#{cookies[session_key_name]}",
|
123
|
+
"authenticity_token": "#{form_authenticity_token}",
|
124
|
+
},
|
125
|
+
|
126
|
+
//upload_url: "#{upload_url}?#{session_key_name}="+encodeURIComponent("#{cookies[session_key_name]}")+"&authenticity_token="+encodeURIComponent("#{form_authenticity_token}"),
|
127
|
+
upload_url: "#{upload_url}",
|
128
|
+
flash_url: '/flash/swfupload/swfupload.swf',
|
129
|
+
|
130
|
+
//example below lets you scope to only allowing image uploads
|
131
|
+
//file_types: "*.jpg;*.jpeg;*.gif;*.png;",
|
132
|
+
file_types: "*",
|
133
|
+
file_types_description: "pictures",
|
134
|
+
file_size_limit: "20 MB",
|
135
|
+
|
136
|
+
button_placeholder_id: "spanButtonPlaceholder",
|
137
|
+
button_width: 380,
|
138
|
+
button_height: 32,
|
139
|
+
button_text : '<span class="button">Select Files <span class="buttonSmall">(10 MB Max)</span></span>',
|
140
|
+
button_text_style : '.button { font-family: Helvetica, Arial, sans-serif; font-size: 24pt; } .buttonSmall { font-size: 18pt; }',
|
141
|
+
button_text_top_padding: 0,
|
142
|
+
button_text_left_padding: 18,
|
143
|
+
button_window_mode: SWFUpload.WINDOW_MODE.TRANSPARENT,
|
144
|
+
button_cursor: SWFUpload.CURSOR.HAND,
|
145
|
+
file_queue_error_handler : fileQueueError,
|
146
|
+
file_dialog_complete_handler : fileDialogComplete,
|
147
|
+
upload_progress_handler : uploadProgress,
|
148
|
+
upload_error_handler : uploadError,
|
149
|
+
upload_success_handler : uploadSuccess,
|
150
|
+
upload_complete_handler : uploadComplete,
|
151
|
+
|
152
|
+
custom_settings : {
|
153
|
+
upload_target: "divFileProgressContainer"
|
154
|
+
}
|
155
|
+
}
|
156
|
+
var swf_upload = new SWFUpload(swf_settings);
|
157
|
+
};
|
158
|
+
}
|
159
|
+
|
160
|
+
append_file 'config/initializers/session_store.rb', <<-FILE
|
161
|
+
require 'rack/utils'
|
162
|
+
|
163
|
+
class FlashSessionCookieMiddleware
|
164
|
+
def initialize(app, session_key = '_session_id')
|
165
|
+
@app = app
|
166
|
+
@session_key = session_key
|
167
|
+
end
|
168
|
+
|
169
|
+
def call(env)
|
170
|
+
if env['HTTP_USER_AGENT'] =~ /^(Adobe|Shockwave) Flash/
|
171
|
+
params = ::Rack::Request.new(env).params
|
172
|
+
env['HTTP_COOKIE'] = [ @session_key, params[@session_key] ].join('=').freeze unless params[@session_key].nil?
|
173
|
+
end
|
174
|
+
@app.call(env)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
ActionController::Dispatcher.middleware.insert_before(ActionController::Base.session_store, FlashSessionCookieMiddleware, ActionController::Base.session_options[:key])
|
179
|
+
FILE
|
180
|
+
|
181
|
+
# example Song resource for those who want it
|
182
|
+
controller_file = <<-FILE
|
183
|
+
class SongsController < ApplicationController
|
184
|
+
layout 'swfupload'
|
185
|
+
|
186
|
+
def index
|
187
|
+
@songs = Song.all
|
188
|
+
end
|
189
|
+
|
190
|
+
def create
|
191
|
+
require 'mime/types'
|
192
|
+
mp3_info = Mp3Info.new(params[:Filedata].path)
|
193
|
+
|
194
|
+
song = Song.new
|
195
|
+
song.artist = mp3_info.tag.artist
|
196
|
+
song.title = mp3_info.tag.title
|
197
|
+
song.length_in_seconds = mp3_info.length.to_i
|
198
|
+
|
199
|
+
params[:Filedata].content_type = MIME::Types.type_for(params[:Filedata].original_filename).to_s
|
200
|
+
song.track = params[:Filedata]
|
201
|
+
song.save
|
202
|
+
|
203
|
+
render :text => [song.artist, song.title, song.convert_seconds_to_time].join(" - ")
|
204
|
+
rescue Mp3InfoError => e
|
205
|
+
render :text => "File error"
|
206
|
+
rescue Exception => e
|
207
|
+
render :text => e.message
|
208
|
+
end
|
209
|
+
end
|
210
|
+
FILE
|
211
|
+
|
212
|
+
|
213
|
+
model_file = <<-FILE
|
214
|
+
class Song < ActiveRecord::Base
|
215
|
+
|
216
|
+
has_attached_file :track
|
217
|
+
|
218
|
+
# validates_presence_of :title, :artist, :length_in_seconds
|
219
|
+
validates_attachment_presence :track
|
220
|
+
validates_attachment_content_type :track, :content_type => [ 'application/mp3', 'application/x-mp3', 'audio/mpeg', 'audio/mp3' ]
|
221
|
+
validates_attachment_size :track, :less_than => 20.megabytes
|
222
|
+
|
223
|
+
attr_accessible :title, :artist, :length_in_seconds
|
224
|
+
|
225
|
+
def convert_seconds_to_time
|
226
|
+
total_minutes = length_in_seconds / 1.minutes
|
227
|
+
seconds_in_last_minute = length_in_seconds - total_minutes.minutes.seconds
|
228
|
+
"\#{total_minutes}m \#{seconds_in_last_minute}s"
|
229
|
+
end
|
230
|
+
|
231
|
+
|
232
|
+
end
|
233
|
+
FILE
|
234
|
+
|
235
|
+
view_file = <<-FILE
|
236
|
+
%h1 Songs
|
237
|
+
|
238
|
+
- @songs.each do |song|
|
239
|
+
%p= song.title
|
240
|
+
|
241
|
+
= render 'swfupload/upload'
|
242
|
+
FILE
|
243
|
+
|
244
|
+
migration_file = <<-FILE
|
245
|
+
class CreateSongs < ActiveRecord::Migration
|
246
|
+
def self.up
|
247
|
+
create_table :songs do |t|
|
248
|
+
t.string :artist
|
249
|
+
t.string :title
|
250
|
+
t.integer :length_in_seconds
|
251
|
+
t.string :track_file_name
|
252
|
+
t.string :track_content_type
|
253
|
+
t.integer :track_file_size
|
254
|
+
t.timestamps
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def self.down
|
259
|
+
drop_table :songs
|
260
|
+
end
|
261
|
+
end
|
262
|
+
FILE
|
263
|
+
|
264
|
+
layout_file = <<-FILE
|
265
|
+
!!! Strict
|
266
|
+
%html
|
267
|
+
%head
|
268
|
+
%title
|
269
|
+
= h(yield(:title) || "Untitled")
|
270
|
+
= '<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>'
|
271
|
+
= '<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery-ui.min.js"></script>'
|
272
|
+
= yield(:head)
|
273
|
+
%body
|
274
|
+
#container
|
275
|
+
= yield
|
276
|
+
FILE
|
277
|
+
|
278
|
+
puts '=' * 80
|
279
|
+
if yes? "Create an example resource using Paperclip? (y/n)"
|
280
|
+
FileUtils.mkdir_p 'app/views/songs'
|
281
|
+
FileUtils.mkdir_p 'public/stylesheets/compiled'
|
282
|
+
|
283
|
+
file 'app/views/layouts/swfupload.html.haml', layout_file
|
284
|
+
file 'app/controllers/songs_controller.rb', controller_file
|
285
|
+
file 'app/models/song.rb', model_file
|
286
|
+
file 'app/views/songs/index.html.haml', view_file
|
287
|
+
|
288
|
+
generate "migration", "create_songs"
|
289
|
+
filename = Dir['db/migrate/*create_songs.rb'].first
|
290
|
+
file filename, migration_file
|
291
|
+
rake "db:migrate"
|
292
|
+
|
293
|
+
gem 'paperclip'
|
294
|
+
gem 'haml'
|
295
|
+
gem 'ruby-mp3info', :lib => 'mp3info'
|
296
|
+
|
297
|
+
run "sass app/stylesheets/swfupload.sass > public/stylesheets/compiled/swfupload.css"
|
298
|
+
|
299
|
+
route 'map.resources :songs'
|
300
|
+
|
301
|
+
puts "Now fire up the app and go to /songs to test it out!"
|
302
|
+
else
|
303
|
+
puts "\nYour controller should have a create action that looks something like this:\n#{controller_file}"
|
304
|
+
puts "\nYou can create a model that looks like this:\n#{model_file}"
|
305
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: beet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jack Dempsey
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-01-09 00:00:00 -05:00
|
13
13
|
default_executable: beet
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -51,6 +51,10 @@ files:
|
|
51
51
|
- lib/beet/execution.rb
|
52
52
|
- lib/beet/executor.rb
|
53
53
|
- lib/beet/file_system.rb
|
54
|
+
- lib/beet/files/swfupload/images/cancelbutton.gif
|
55
|
+
- lib/beet/files/swfupload/images/header-bg.jpg
|
56
|
+
- lib/beet/files/swfupload/images/logo.gif
|
57
|
+
- lib/beet/files/swfupload/js/handlers.js
|
54
58
|
- lib/beet/gem_location_map.rb
|
55
59
|
- lib/beet/interaction.rb
|
56
60
|
- lib/beet/logger.rb
|
@@ -66,10 +70,12 @@ files:
|
|
66
70
|
- lib/beet/recipes/rails/css/blueprint.rb
|
67
71
|
- lib/beet/recipes/rails/css/nifty_layout.rb
|
68
72
|
- lib/beet/recipes/rails/css/reset.rb
|
73
|
+
- lib/beet/recipes/rails/db/mongo.rb
|
69
74
|
- lib/beet/recipes/rails/db/mysql.rb
|
70
75
|
- lib/beet/recipes/rails/db/postgres.rb
|
71
76
|
- lib/beet/recipes/rails/git.rb
|
72
77
|
- lib/beet/recipes/rails/jquery.rb
|
78
|
+
- lib/beet/recipes/rails/swfupload.rb
|
73
79
|
- lib/beet/recipes/rails/testing/rspec.rb
|
74
80
|
- lib/beet/recipes/rails/testing/shoulda.rb
|
75
81
|
- lib/beet/scm.rb
|