nyoibo 0.0.2 → 0.0.3
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/.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
|