nyoibo 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.rdoc +57 -0
- data/lib/generators/nyoibo/install_generator.rb +1 -1
- data/lib/generators/nyoibo/templates/nyoibo.js.coffee +37 -58
- data/lib/generators/nyoibo/templates/upload.js.coffee +21 -0
- data/lib/nyoibo/callback.rb +13 -11
- data/lib/nyoibo/daemon.rb +13 -5
- data/lib/nyoibo/railtie.rb +6 -0
- data/lib/nyoibo/version.rb +1 -1
- data/test/example.rb +16 -2
- data/test/unit/callback_test.rb +14 -3
- data/test/unit/daemon_test.rb +3 -1
- metadata +4 -3
- data/lib/generators/nyoibo/templates/nyoibo_en.yml +0 -3
data/.gitignore
CHANGED
data/README.rdoc
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
= Nyoibo
|
2
|
+
|
3
|
+
A websocket file uploader with progressbar module.
|
4
|
+
|
5
|
+
== Features
|
6
|
+
|
7
|
+
=== Any frameworks
|
8
|
+
You can use Rails or Sinatra and so on, especially this contains rails generator.
|
9
|
+
|
10
|
+
== Install(gem)
|
11
|
+
$ gem install nyoibo
|
12
|
+
|
13
|
+
== Install(bundler)
|
14
|
+
Put this line in your Gemfile:
|
15
|
+
gem 'nyoibo'
|
16
|
+
|
17
|
+
Then bundle:
|
18
|
+
$ bundle install
|
19
|
+
|
20
|
+
== Usage(Rails 3.1)
|
21
|
+
==== Generate config and coffee-script files
|
22
|
+
$ rails g nyoibo:install
|
23
|
+
|
24
|
+
=== View
|
25
|
+
<%= ws_form_for(@post) do |f| %>
|
26
|
+
file: <%= f.file_field :photo, :size => 40 %><br>
|
27
|
+
comment: <%= f.text_field :comment, :size => 40 %><br>
|
28
|
+
<%= f.submit 'upload' %>
|
29
|
+
<% end %>
|
30
|
+
|
31
|
+
=== Write callback on Controlller
|
32
|
+
class SomeController < ApplicationController
|
33
|
+
before_upload "/" do |params|
|
34
|
+
if params["confirm"] == false
|
35
|
+
return false # Not to start uploading if return false.
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
after_upload "/" do |params, binary|
|
40
|
+
File.open("/tmp/#{params['filename']}", "wb:binary") do |f|
|
41
|
+
f.write(binary)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
== Usage(Sinatra)
|
47
|
+
See test/example.rb
|
48
|
+
|
49
|
+
== Questions, Feedback
|
50
|
+
|
51
|
+
Message me on Github (yalab) or Twitter (@yalab)
|
52
|
+
|
53
|
+
== Licence
|
54
|
+
MIT-LICENSE
|
55
|
+
|
56
|
+
== Copyright
|
57
|
+
Copyright (c) 2011 Atsushi Yoshida(yalab).
|
@@ -9,8 +9,8 @@ module Nyoibo
|
|
9
9
|
desc "Creates a Nyoibo initializer and copy javascript and locale files to your application."
|
10
10
|
def copy_initializer
|
11
11
|
template "nyoibo.rb.erb", "config/initializers/nyoibo.rb"
|
12
|
-
template "nyoibo_en.yml", "config/locales/nyoibo_en.yml"
|
13
12
|
template "nyoibo.js.coffee", "app/assets/javascripts/nyoibo.js.coffee"
|
13
|
+
template "upload.js.coffee", "app/assets/javascripts/upload.js.coffee"
|
14
14
|
copy_file "../../../../vendor/html5jp/progress.js", "app/assets/javascripts/progress.js"
|
15
15
|
copy_file "../../../../vendor/web-socket-js/web_socket.js", "app/assets/javascripts/web_socket.js"
|
16
16
|
copy_file "../../../../vendor/web-socket-js/swfobject.js", "app/assets/javascripts/swfobject.js"
|
@@ -1,77 +1,58 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
class Nyoibo
|
2
|
+
constructor: (@url, id) ->
|
3
|
+
if $("##{id}").length > 0
|
4
|
+
@progressbar = new html5jp.progress(id)
|
5
|
+
@progressbar.draw()
|
6
|
+
@prepare_upload = -> true
|
7
|
+
@before_upload = -> true
|
8
|
+
@after_upload = -> true
|
9
|
+
@upload_abort = -> true
|
10
|
+
upload: (file, params={}) ->
|
11
|
+
@errors = []
|
12
|
+
return false unless @prepare_upload.apply(@)
|
3
13
|
|
4
|
-
jQuery.fn.serializeObject = () ->
|
5
|
-
arrayData = this.serializeArray()
|
6
|
-
objectData = {}
|
7
|
-
|
8
|
-
$.each arrayData, () ->
|
9
|
-
if this.value?
|
10
|
-
value = this.value
|
11
|
-
else
|
12
|
-
value = ''
|
13
|
-
|
14
|
-
if objectData[this.name]?
|
15
|
-
unless objectData[this.name].push
|
16
|
-
objectData[this.name] = [objectData[this.name]]
|
17
|
-
|
18
|
-
objectData[this.name].push value
|
19
|
-
else
|
20
|
-
objectData[this.name] = value
|
21
|
-
|
22
|
-
return objectData
|
23
|
-
|
24
|
-
jQuery ($)->
|
25
|
-
if $("#ws-progress").length > 0
|
26
|
-
progress = new html5jp.progress("ws-progress")
|
27
|
-
progress.draw()
|
28
|
-
|
29
|
-
form = $('#ws-form')
|
30
|
-
progress_bar = $("#ws-progress")
|
31
|
-
|
32
|
-
fire = (obj, name, data) ->
|
33
|
-
event = $.Event(name)
|
34
|
-
obj.trigger(event, data)
|
35
|
-
return event.result != false
|
36
|
-
|
37
|
-
form.bind 'ws:upload', (event) ->
|
38
|
-
file = form.find('input[type=file]').get(0).files[0]
|
39
14
|
try
|
40
|
-
|
15
|
+
filesize = file.size
|
41
16
|
catch e
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
17
|
+
@errors.push "file not found"
|
18
|
+
if filesize == 0
|
19
|
+
@errors.push "file size is zero"
|
20
|
+
|
21
|
+
return false if @errors.length > 0
|
22
|
+
|
47
23
|
chunk = 102400
|
48
24
|
start = 0
|
49
|
-
ws = new WebSocket("ws://localhost:3030/")
|
50
25
|
|
51
|
-
|
26
|
+
ws = new WebSocket(@url)
|
27
|
+
@before_upload.apply(@)
|
28
|
+
ws.progressbar = @progressbar
|
29
|
+
ws.after_upload = @after_upload
|
30
|
+
ws.upload_abort = @upload_abort
|
52
31
|
ws.onclose = ->
|
53
|
-
|
54
|
-
fire(form, 'ws:after_upload')
|
55
|
-
progress.reset()
|
32
|
+
ws.progressbar.reset()
|
56
33
|
ws = null
|
57
34
|
|
58
35
|
ws.onmessage = (evt) ->
|
59
36
|
switch evt.data
|
60
37
|
when 'OK Ready'
|
61
|
-
params =
|
62
|
-
|
63
|
-
params[k] = v
|
38
|
+
params['filename'] = file.name
|
39
|
+
params['size'] = filesize
|
64
40
|
ws.send("JSON: " + JSON.stringify(params))
|
65
41
|
when 'OK Bye'
|
42
|
+
ws.progressbar.set_val(100)
|
43
|
+
ws.after_upload.apply(@)
|
66
44
|
ws.close()
|
45
|
+
when 'ABORT'
|
46
|
+
ws.upload_abort.apply(@)
|
67
47
|
when 'EMPTY'
|
68
48
|
ws.send("QUIT")
|
49
|
+
ws.progressbar.set_val(100)
|
69
50
|
when 'NEXT'
|
70
|
-
val = Math.floor(start /
|
71
|
-
|
51
|
+
val = Math.floor(start / filesize * 100)
|
52
|
+
ws.progressbar.set_val(val)
|
72
53
|
stop = start + chunk - 1
|
73
|
-
if stop >=
|
74
|
-
stop =
|
54
|
+
if stop >= filesize
|
55
|
+
stop = filesize
|
75
56
|
|
76
57
|
blob = if typeof(file.mozSlice) == "function"
|
77
58
|
file.mozSlice(start, stop)
|
@@ -86,6 +67,4 @@ jQuery ($)->
|
|
86
67
|
reader.readAsBinaryString(blob)
|
87
68
|
, 300
|
88
69
|
|
89
|
-
|
90
|
-
fire(form, 'ws:upload') if fire(form, 'ws:prepare_upload')
|
91
|
-
return false
|
70
|
+
@Nyoibo = Nyoibo
|
@@ -0,0 +1,21 @@
|
|
1
|
+
`WEB_SOCKET_DEBUG = true;
|
2
|
+
WEB_SOCKET_SWF_LOCATION = '/WebSocketMain.swf';`
|
3
|
+
jQuery ($)->
|
4
|
+
nyoibo = new Nyoibo("ws://localhost:3030/", "ws-progress")
|
5
|
+
form = $('#ws-form')
|
6
|
+
nyoibo.prepare_upload = -> true
|
7
|
+
nyoibo.before_upload = ->
|
8
|
+
form.hide()
|
9
|
+
nyoibo.after_upload = ->
|
10
|
+
form.get(0).reset()
|
11
|
+
form.show()
|
12
|
+
nyoibo.upload_abort = -> true
|
13
|
+
|
14
|
+
$('#ws-form input[type=submit]').click ->
|
15
|
+
params = {}
|
16
|
+
for i, input of form.serializeArray()
|
17
|
+
params[input.name] = input.value
|
18
|
+
|
19
|
+
unless nyoibo.upload(form.find('input[type=file]').get(0).files[0], params)
|
20
|
+
alert nyoibo.errors.join(", ")
|
21
|
+
return false
|
data/lib/nyoibo/callback.rb
CHANGED
@@ -1,27 +1,29 @@
|
|
1
1
|
module Nyoibo
|
2
2
|
module Callback
|
3
3
|
def self.callbacks
|
4
|
-
@callbacks ||= {}
|
4
|
+
@callbacks ||= {:before => {}, :after => {}}
|
5
5
|
end
|
6
6
|
def self.included(base)
|
7
7
|
base.extend ClassMethod
|
8
8
|
end
|
9
9
|
|
10
10
|
module ClassMethod
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
11
|
+
[:before, :after].each do |prefix|
|
12
|
+
module_eval <<-EOS, __FILE__, __LINE__
|
13
|
+
def #{prefix}_upload(path, &block)
|
14
|
+
if ENV["NYOIBO_ENV"] == "production" && Nyoibo::Callback.callbacks[#{prefix}][path]
|
15
|
+
raise "Already defined #{prefix} updated callback."
|
16
|
+
end
|
17
|
+
Nyoibo::Callback.callbacks[:#{prefix}][path] = block
|
18
|
+
end
|
19
|
+
EOS
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
21
23
|
module Runner
|
22
|
-
def run_callback(path="/", *args)
|
23
|
-
block = Nyoibo::Callback.callbacks[path]
|
24
|
-
block.call(*args)
|
24
|
+
def run_callback(prefix, path="/", *args)
|
25
|
+
block = Nyoibo::Callback.callbacks[prefix][path]
|
26
|
+
block.call(*args) if block
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
data/lib/nyoibo/daemon.rb
CHANGED
@@ -12,7 +12,7 @@ module Nyoibo
|
|
12
12
|
ws.send "OK Ready"
|
13
13
|
}
|
14
14
|
ws.onclose{
|
15
|
-
ws.
|
15
|
+
ws.close_websocket
|
16
16
|
}
|
17
17
|
ws.onmessage{|msg|
|
18
18
|
@binary ||= ""
|
@@ -24,15 +24,20 @@ module Nyoibo
|
|
24
24
|
elsif @binary.encoding == Encoding::UTF_8
|
25
25
|
@binary = @binary.unpack('U*').pack('c*')
|
26
26
|
end
|
27
|
-
Nyoibo.run_callback(ws.request["path"], @json, @binary)
|
28
|
-
|
27
|
+
Nyoibo.run_callback(:after, ws.request["path"], @json, @binary)
|
28
|
+
@binary = @json = nil
|
29
|
+
ws.send("OK Bye")
|
29
30
|
when CMD_JSON
|
30
31
|
msg.gsub!(CMD_JSON, '')
|
31
32
|
@json = JSON.parse(msg)
|
32
33
|
@json['size'] = @json['size'].to_i
|
33
|
-
ws.
|
34
|
+
if Nyoibo.run_callback(:before, ws.request["path"], @json, @binary) == false
|
35
|
+
ws.send("ABORT")
|
36
|
+
ws.close_websocket
|
37
|
+
else
|
38
|
+
ws.send("NEXT")
|
39
|
+
end
|
34
40
|
else
|
35
|
-
|
36
41
|
if msg =~ TYPE_BASE64
|
37
42
|
msg.gsub!(TYPE_BASE64, '')
|
38
43
|
@binary_type = 'base64'
|
@@ -52,6 +57,9 @@ module Nyoibo
|
|
52
57
|
daemon.call
|
53
58
|
else
|
54
59
|
@pid = Process.fork &daemon
|
60
|
+
at_exit do
|
61
|
+
Process.kill(:KILL, Nyoibo.pid) if Nyoibo.pid
|
62
|
+
end
|
55
63
|
end
|
56
64
|
end
|
57
65
|
end
|
data/lib/nyoibo/railtie.rb
CHANGED
@@ -4,5 +4,11 @@ class Nyoibo::Railtie < Rails::Railtie
|
|
4
4
|
config.after_initialize do
|
5
5
|
ENV["NYOIBO_ENV"] = Rails.env
|
6
6
|
Nyoibo.run
|
7
|
+
::ApplicationController.send(:prepend_before_filter, lambda{
|
8
|
+
if Rails.env == "development"
|
9
|
+
Process.kill(:INT, Nyoibo.pid)
|
10
|
+
Nyoibo.run
|
11
|
+
end
|
12
|
+
true})
|
7
13
|
end
|
8
14
|
end
|
data/lib/nyoibo/version.rb
CHANGED
data/test/example.rb
CHANGED
@@ -13,7 +13,7 @@ class Post
|
|
13
13
|
attr_accessor :file
|
14
14
|
|
15
15
|
include Nyoibo::Callback
|
16
|
-
|
16
|
+
after_upload "/" do |params, binary|
|
17
17
|
File.open('/tmp/test.jpg', 'w:binary') do |f|
|
18
18
|
f.write(binary)
|
19
19
|
end
|
@@ -22,6 +22,9 @@ class Post
|
|
22
22
|
f.write(params)
|
23
23
|
end
|
24
24
|
end
|
25
|
+
before_upload "/" do |params|
|
26
|
+
params['name'] == "yalab"
|
27
|
+
end
|
25
28
|
end
|
26
29
|
Nyoibo.configure do
|
27
30
|
host 'localhost'
|
@@ -30,6 +33,10 @@ end
|
|
30
33
|
Process.fork do
|
31
34
|
Nyoibo.run
|
32
35
|
end
|
36
|
+
|
37
|
+
|
38
|
+
set :public, File.expand_path('../../vendor/web-socket-js', __FILE__)
|
39
|
+
|
33
40
|
get '/' do
|
34
41
|
@post = Post.new
|
35
42
|
erubis <<EOS
|
@@ -38,12 +45,18 @@ get '/' do
|
|
38
45
|
<head>
|
39
46
|
<title>nyoibo</title>
|
40
47
|
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
|
48
|
+
<script src="/swfobject.js"></script>
|
49
|
+
<script src="/web_socket.js"></script>
|
41
50
|
<script>
|
42
|
-
#{File.read File.expand_path(
|
51
|
+
#{File.read File.open(File.expand_path("../../vendor/html5jp/progress.js", __FILE__))}
|
43
52
|
</script>
|
53
|
+
|
44
54
|
<script>
|
45
55
|
#{CoffeeScript.compile(File.read(File.expand_path('../../lib/generators/nyoibo/templates/nyoibo.js.coffee', __FILE__)))}
|
46
56
|
</script>
|
57
|
+
<script>
|
58
|
+
#{CoffeeScript.compile(File.read(File.expand_path('../../lib/generators/nyoibo/templates/upload.js.coffee', __FILE__)))}
|
59
|
+
</script>
|
47
60
|
</head>
|
48
61
|
<body>
|
49
62
|
|
@@ -52,6 +65,7 @@ get '/' do
|
|
52
65
|
<input type="file">
|
53
66
|
<input type="submit">
|
54
67
|
<input type="text" name="name" value="yalab">
|
68
|
+
<input type="hidden" name="age" value="28">
|
55
69
|
</form>
|
56
70
|
<div id="ws-progress"></div>
|
57
71
|
</body>
|
data/test/unit/callback_test.rb
CHANGED
@@ -2,16 +2,27 @@ require 'test_helper'
|
|
2
2
|
class Nyoibo::CallbackTest < Test::Unit::TestCase
|
3
3
|
class TestApp
|
4
4
|
include Nyoibo::Callback
|
5
|
-
|
5
|
+
after_upload "/" do
|
6
6
|
"uploaded!"
|
7
7
|
end
|
8
|
+
before_upload '/' do
|
9
|
+
"before"
|
10
|
+
end
|
8
11
|
end
|
9
|
-
context "Run callback" do
|
12
|
+
context "Run after callback" do
|
10
13
|
setup do
|
11
|
-
@response = Nyoibo.run_callback("/")
|
14
|
+
@response = Nyoibo.run_callback(:after, "/")
|
12
15
|
end
|
13
16
|
should "fetch response" do
|
14
17
|
assert_equal "uploaded!", @response
|
15
18
|
end
|
16
19
|
end
|
20
|
+
context "Run before callback" do
|
21
|
+
setup do
|
22
|
+
@response = Nyoibo.run_callback(:before, "/")
|
23
|
+
end
|
24
|
+
should "fetch response" do
|
25
|
+
assert_equal "before", @response
|
26
|
+
end
|
27
|
+
end
|
17
28
|
end
|
data/test/unit/daemon_test.rb
CHANGED
@@ -2,7 +2,7 @@ require 'test_helper'
|
|
2
2
|
class Nyoibo::DaemonTest < Test::Unit::TestCase
|
3
3
|
class TestApp < Test::Unit::TestCase
|
4
4
|
include Nyoibo::Callback
|
5
|
-
|
5
|
+
after_upload "/" do |json, binary|
|
6
6
|
File.open("/tmp/test.jpg", "w:binary"){|f|
|
7
7
|
f.write(binary)
|
8
8
|
}
|
@@ -31,6 +31,8 @@ class Nyoibo::DaemonTest < Test::Unit::TestCase
|
|
31
31
|
case msg
|
32
32
|
when "OK Ready"
|
33
33
|
http.send("JSON: " + {:filename => File.basename(@file.path), :size => @file.size}.to_json)
|
34
|
+
when "OK Bye"
|
35
|
+
http.close_connection
|
34
36
|
when "NEXT"
|
35
37
|
@end = @start + @sendsize
|
36
38
|
@encoded ||= Base64.encode64(@file.read)
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: nyoibo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- yalab
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-07-
|
13
|
+
date: 2011-07-10 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: em-websocket
|
@@ -102,12 +102,13 @@ files:
|
|
102
102
|
- .gitignore
|
103
103
|
- Gemfile
|
104
104
|
- MIT-LICENSE
|
105
|
+
- README.rdoc
|
105
106
|
- Rakefile
|
106
107
|
- app/helpers/nyoibo_helper.rb
|
107
108
|
- lib/generators/nyoibo/install_generator.rb
|
108
109
|
- lib/generators/nyoibo/templates/nyoibo.js.coffee
|
109
110
|
- lib/generators/nyoibo/templates/nyoibo.rb.erb
|
110
|
-
- lib/generators/nyoibo/templates/
|
111
|
+
- lib/generators/nyoibo/templates/upload.js.coffee
|
111
112
|
- lib/nyoibo.rb
|
112
113
|
- lib/nyoibo/callback.rb
|
113
114
|
- lib/nyoibo/configure.rb
|