thin_upload 0.0.1.pre1

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.
Files changed (45) hide show
  1. data/Gemfile +7 -0
  2. data/Gemfile.lock +31 -0
  3. data/Manifest +44 -0
  4. data/README.rdoc +40 -0
  5. data/Rakefile +33 -0
  6. data/html/README_rdoc.html +133 -0
  7. data/html/Thin.html +149 -0
  8. data/html/Thin/Request.html +537 -0
  9. data/html/Thin/Server.html +194 -0
  10. data/html/created.rid +4 -0
  11. data/html/images/brick.png +0 -0
  12. data/html/images/brick_link.png +0 -0
  13. data/html/images/bug.png +0 -0
  14. data/html/images/bullet_black.png +0 -0
  15. data/html/images/bullet_toggle_minus.png +0 -0
  16. data/html/images/bullet_toggle_plus.png +0 -0
  17. data/html/images/date.png +0 -0
  18. data/html/images/find.png +0 -0
  19. data/html/images/loadingAnimation.gif +0 -0
  20. data/html/images/macFFBgHack.png +0 -0
  21. data/html/images/package.png +0 -0
  22. data/html/images/page_green.png +0 -0
  23. data/html/images/page_white_text.png +0 -0
  24. data/html/images/page_white_width.png +0 -0
  25. data/html/images/plugin.png +0 -0
  26. data/html/images/ruby.png +0 -0
  27. data/html/images/tag_green.png +0 -0
  28. data/html/images/wrench.png +0 -0
  29. data/html/images/wrench_orange.png +0 -0
  30. data/html/images/zoom.png +0 -0
  31. data/html/index.html +124 -0
  32. data/html/js/darkfish.js +116 -0
  33. data/html/js/jquery.js +32 -0
  34. data/html/js/quicksearch.js +114 -0
  35. data/html/js/thickbox-compressed.js +10 -0
  36. data/html/lib/thin_upload/parser_rb.html +54 -0
  37. data/html/lib/thin_upload/request_rb.html +54 -0
  38. data/html/lib/thin_upload_rb.html +54 -0
  39. data/html/rdoc.css +763 -0
  40. data/lib/thin_upload.rb +3 -0
  41. data/lib/thin_upload/request.rb +93 -0
  42. data/test/test_helper.rb +30 -0
  43. data/test/thin_upload/request_test.rb +91 -0
  44. data/thin_upload.gemspec +33 -0
  45. metadata +111 -0
@@ -0,0 +1,3 @@
1
+ require 'thin_upload/request'
2
+
3
+ raise "You have to use Thin server for using thin_upload" unless defined? Thin
@@ -0,0 +1,93 @@
1
+ #Thin module from thin server
2
+ module Thin
3
+ # The Request class takes part of the Thin module which is responsible
4
+ # for incomming web requests for thin server.
5
+ # The class is opened up here for adding functionality to track
6
+ # progress of file uploads.
7
+
8
+ class Request
9
+ #Freeze Rack header for progress hash
10
+ RACK_PROGRESS = 'rack.progress'.freeze
11
+
12
+ #Freeze some regexps
13
+ #regexp to identify file upload
14
+ POST_REQUEST_REGEXP = /uuid\"\r\n\r\n(.*)\r/i.freeze
15
+ #regexp to identify upload progress requests
16
+ GET_REQUEST_REGEXP = /uuid=(.*) /.freeze
17
+ attr_reader :parser
18
+ attr_accessor :data_buffer
19
+
20
+ # +new_parse+ method extends the original +parse+ method's
21
+ # functionality with the upload progress tracking
22
+ # Arguments:
23
+ # data: (String)
24
+
25
+ def new_parse(data)
26
+ scan_content(data) unless uuid_found_or_limit_reached?
27
+ success = thin_parse(data) #execute the the original +parse+ method
28
+ store_progress(@upload_uuid)
29
+ cleanup_progress_hash(@request_uuid)
30
+ success #returns the result from Thin's parse method
31
+ end
32
+
33
+ # The +Thin+'s +parse+ method is aliased to +thin_parse+
34
+ # and the +new_parse+ method is aliased to +parse+
35
+ alias_method :thin_parse, :parse
36
+ alias_method :parse, :new_parse
37
+
38
+ # Scans unparsed data for uuids, the unparsed data
39
+ # is stored in a string for buffering purposes
40
+ # which is deleted after the uuid has been found.
41
+ # Arguments:
42
+ # data: (String)
43
+
44
+ def scan_content(data)
45
+ @data_buffer = @data_buffer.to_s + data
46
+ @upload_uuid ||= @data_buffer.scan(POST_REQUEST_REGEXP).flatten.first
47
+ @request_uuid ||= @data_buffer.scan(GET_REQUEST_REGEXP).flatten.first
48
+ end
49
+
50
+ # Checking if we still have to search for uuid's
51
+ # Arguments:
52
+ # none
53
+ def uuid_found_or_limit_reached?
54
+ if @upload_uuid || @request_uuid || (body.size > MAX_BODY)
55
+ @data_buffer = nil
56
+ true
57
+ else
58
+ false
59
+ end
60
+ end
61
+
62
+ # Calculating the progress based on +content_length+ and received body size +body.size+
63
+ # Arguments:
64
+ # none
65
+ def progress
66
+ ((body.size/content_length.to_f)*100).to_i
67
+ end
68
+
69
+ # progress can be accessed via +request.env['rack.progress']+ in the app
70
+ # Arguments:
71
+ # uuid: (String)
72
+ def store_progress(uuid)
73
+ Thin::Server::progress[uuid] = progress if uuid #storing the progress with the uiid
74
+ @env.merge!(RACK_PROGRESS=>Thin::Server::progress.clone) if finished? #merging the progress hash into the environment
75
+ end
76
+
77
+ # deleting progress entry from +Thin::Server::progress+ if the upload is finished and the result was requested
78
+ # Arguments:
79
+ # data: (String)
80
+ def cleanup_progress_hash(req_uuid)
81
+ Thin::Server::progress.delete(req_uuid) if Thin::Server::progress[req_uuid] == 100 && finished?#delete when progress is returned and 100%
82
+ end
83
+ end
84
+ end
85
+ module Thin
86
+ # Thin's server class
87
+ class Server
88
+ #adding a hash to store all the upload progress in the server
89
+ def self.progress
90
+ @@progress||={}
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,30 @@
1
+ require 'test/unit'
2
+ require 'thin'
3
+ require 'thin_upload'
4
+
5
+ def upload_data_string
6
+ "form-data; name=\"uuid\"\r\n\r\n#{uuid}\r\n-----------------------------"
7
+ end
8
+
9
+ def post_request(body)
10
+ "POST / HTTP/1.1\r\nHost: localhost\r\nContent-Type: text/html\r\nContent-Length: #{body.size}\r\n\r\n#{body}"
11
+ end
12
+
13
+ def big_post_request(body)
14
+ "POST / HTTP/1.1\r\nHost: localhost\r\nContent-Type: text/html\r\nContent-Length: #{Thin::Request::MAX_BODY+1}\r\n\r\n#{body}"
15
+ end
16
+ def get_request(url)
17
+ "GET #{url} HTTP/1.1\r\nHost: localhost:3000\r\n\r\n"
18
+ end
19
+
20
+
21
+ def uuid
22
+ "2ce89350-cb31-012e-dc4a-64b9e8c7c202"
23
+ end
24
+
25
+ # Create and parse a request
26
+ def new_request(data)
27
+ request = Thin::Request.new
28
+ request.parse(data)
29
+ request
30
+ end
@@ -0,0 +1,91 @@
1
+ require 'test_helper'
2
+
3
+ class RequestTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @request = new_request(post_request("a"*100))
7
+ end
8
+
9
+ def test_scan_uuid_on_url_request
10
+ @request.scan_content(get_request("?uuid=#{uuid}"))
11
+ assert_equal @request.instance_variable_get(:@request_uuid), uuid
12
+ end
13
+
14
+ def test_scan_uuid_on_form_request
15
+ @request.scan_content(upload_data_string)
16
+ assert_equal @request.instance_variable_get(:@upload_uuid), uuid
17
+ end
18
+
19
+ def test_store_data_in_buffer
20
+ content = "content"
21
+ content2 = "content2"
22
+ @request.parse(content)
23
+ assert @request.data_buffer.match(/#{content}$/)
24
+ @request.parse(content2)
25
+ assert @request.data_buffer.match(/#{content+content2}$/)
26
+ end
27
+
28
+ def test_clear_data_from_buffer_when_url_uuid_found
29
+ content = "content"
30
+ @request.parse(content)
31
+ assert @request.data_buffer.match(/#{content}$/)
32
+ @request.parse(get_request("?uuid=#{uuid}"))
33
+ assert_equal @request.instance_variable_get(:@request_uuid), uuid
34
+ @request.parse content
35
+ assert_equal @request.data_buffer, nil
36
+ end
37
+
38
+ def test_clear_data_from_buffer_when_form_uuid_found
39
+ content = "content"
40
+ @request.parse(content)
41
+ assert @request.data_buffer.match(/#{content}$/)
42
+ @request.parse post_request(upload_data_string)
43
+ assert_equal @request.instance_variable_get(:@upload_uuid), uuid
44
+ @request.parse content
45
+ assert_equal @request.data_buffer, nil
46
+ end
47
+
48
+ def test_should_stop_parsing_when_body_size_limit_reached
49
+ @request = new_request(post_request("a"))
50
+ assert !@request.uuid_found_or_limit_reached?
51
+ @request.body << "a" * (Thin::Request::MAX_BODY+1)
52
+ assert @request.uuid_found_or_limit_reached?
53
+ assert_equal @request.instance_variable_get(:@data_buffer), nil
54
+ end
55
+
56
+ def test_calculate_progress
57
+ @request.instance_variable_set(:@body, "a"*20)
58
+ assert_equal @request.progress, 20
59
+ @request.instance_variable_set(:@body, "a"*45)
60
+ assert_equal @request.progress, 45
61
+ @request.instance_variable_set(:@body, "a"*100)
62
+ assert_equal @request.progress, 100
63
+ end
64
+
65
+ def test_store_progress
66
+ @request.instance_variable_set(:@body, "a"*50)
67
+ @request.store_progress(uuid)
68
+ assert_equal Thin::Server::progress[uuid], 50
69
+ end
70
+
71
+ def test_progress_is_returned_on_parse_finish
72
+ Thin::Server::progress['my_id'] = 45
73
+ assert @request.finished?
74
+ @request.store_progress(uuid)
75
+ assert_equal @request.env[Thin::Request::RACK_PROGRESS]['my_id'], 45
76
+ end
77
+
78
+ def test_progress_is_deleted_when_it_was_finished_and_requested
79
+ Thin::Server::progress[uuid] = 100
80
+ assert @request.parse post_request("uuid=#{uuid} ")
81
+ assert_equal @request.env[Thin::Request::RACK_PROGRESS][uuid], 100
82
+ end
83
+
84
+ def test_progress_is_returned_when_its_finished_and_not_was_requested_yet
85
+ Thin::Server::progress[uuid] = 100
86
+ @request = Thin::Request.new
87
+ assert @request.parse(get_request("/progress?uuid=#{uuid}"))
88
+ assert_equal Thin::Server::progress.has_key?(uuid), false
89
+ end
90
+
91
+ end
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{thin_upload}
5
+ s.version = "0.0.1.pre1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = [%q{Dombi Attila}]
9
+ s.date = %q{2011-10-19}
10
+ s.description = %q{thin_upload provides upload progress measuring functionality for thin ruby server, progresses can be accessed via rack middleware.}
11
+ s.email = %q{dombesz.attila-at-gmail.com}
12
+ s.extra_rdoc_files = [%q{README.rdoc}, %q{lib/thin_upload.rb}, %q{lib/thin_upload/request.rb}]
13
+ s.files = [%q{Gemfile}, %q{Gemfile.lock}, %q{Manifest}, %q{README.rdoc}, %q{Rakefile}, %q{html/README_rdoc.html}, %q{html/Thin.html}, %q{html/Thin/Request.html}, %q{html/Thin/Server.html}, %q{html/created.rid}, %q{html/images/brick.png}, %q{html/images/brick_link.png}, %q{html/images/bug.png}, %q{html/images/bullet_black.png}, %q{html/images/bullet_toggle_minus.png}, %q{html/images/bullet_toggle_plus.png}, %q{html/images/date.png}, %q{html/images/find.png}, %q{html/images/loadingAnimation.gif}, %q{html/images/macFFBgHack.png}, %q{html/images/package.png}, %q{html/images/page_green.png}, %q{html/images/page_white_text.png}, %q{html/images/page_white_width.png}, %q{html/images/plugin.png}, %q{html/images/ruby.png}, %q{html/images/tag_green.png}, %q{html/images/wrench.png}, %q{html/images/wrench_orange.png}, %q{html/images/zoom.png}, %q{html/index.html}, %q{html/js/darkfish.js}, %q{html/js/jquery.js}, %q{html/js/quicksearch.js}, %q{html/js/thickbox-compressed.js}, %q{html/lib/thin_upload/parser_rb.html}, %q{html/lib/thin_upload/request_rb.html}, %q{html/lib/thin_upload_rb.html}, %q{html/rdoc.css}, %q{lib/thin_upload.rb}, %q{lib/thin_upload/request.rb}, %q{test/test_helper.rb}, %q{test/thin_upload/request_test.rb}, %q{thin_upload.gemspec}]
14
+ s.homepage = %q{https://github.com/dombesz/thin_upload}
15
+ s.rdoc_options = [%q{--line-numbers}, %q{--inline-source}, %q{--title}, %q{Thin_upload}, %q{--main}, %q{README.rdoc}]
16
+ s.require_paths = [%q{lib}]
17
+ s.rubyforge_project = %q{thin_upload}
18
+ s.rubygems_version = %q{1.8.8}
19
+ s.summary = %q{Upload progress meter for thin ruby server.}
20
+ s.test_files = [%q{test/test_helper.rb}, %q{test/thin_upload/request_test.rb}]
21
+
22
+ if s.respond_to? :specification_version then
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
26
+ s.add_development_dependency(%q<thin>, [">= 0"])
27
+ else
28
+ s.add_dependency(%q<thin>, [">= 0"])
29
+ end
30
+ else
31
+ s.add_dependency(%q<thin>, [">= 0"])
32
+ end
33
+ end
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: thin_upload
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.pre1
5
+ prerelease: 6
6
+ platform: ruby
7
+ authors:
8
+ - Dombi Attila
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-19 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thin
16
+ requirement: &2162587720 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *2162587720
25
+ description: thin_upload provides upload progress measuring functionality for thin
26
+ ruby server, progresses can be accessed via rack middleware.
27
+ email: dombesz.attila-at-gmail.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files:
31
+ - README.rdoc
32
+ - lib/thin_upload.rb
33
+ - lib/thin_upload/request.rb
34
+ files:
35
+ - Gemfile
36
+ - Gemfile.lock
37
+ - Manifest
38
+ - README.rdoc
39
+ - Rakefile
40
+ - html/README_rdoc.html
41
+ - html/Thin.html
42
+ - html/Thin/Request.html
43
+ - html/Thin/Server.html
44
+ - html/created.rid
45
+ - html/images/brick.png
46
+ - html/images/brick_link.png
47
+ - html/images/bug.png
48
+ - html/images/bullet_black.png
49
+ - html/images/bullet_toggle_minus.png
50
+ - html/images/bullet_toggle_plus.png
51
+ - html/images/date.png
52
+ - html/images/find.png
53
+ - html/images/loadingAnimation.gif
54
+ - html/images/macFFBgHack.png
55
+ - html/images/package.png
56
+ - html/images/page_green.png
57
+ - html/images/page_white_text.png
58
+ - html/images/page_white_width.png
59
+ - html/images/plugin.png
60
+ - html/images/ruby.png
61
+ - html/images/tag_green.png
62
+ - html/images/wrench.png
63
+ - html/images/wrench_orange.png
64
+ - html/images/zoom.png
65
+ - html/index.html
66
+ - html/js/darkfish.js
67
+ - html/js/jquery.js
68
+ - html/js/quicksearch.js
69
+ - html/js/thickbox-compressed.js
70
+ - html/lib/thin_upload/parser_rb.html
71
+ - html/lib/thin_upload/request_rb.html
72
+ - html/lib/thin_upload_rb.html
73
+ - html/rdoc.css
74
+ - lib/thin_upload.rb
75
+ - lib/thin_upload/request.rb
76
+ - test/test_helper.rb
77
+ - test/thin_upload/request_test.rb
78
+ - thin_upload.gemspec
79
+ homepage: https://github.com/dombesz/thin_upload
80
+ licenses: []
81
+ post_install_message:
82
+ rdoc_options:
83
+ - --line-numbers
84
+ - --inline-source
85
+ - --title
86
+ - Thin_upload
87
+ - --main
88
+ - README.rdoc
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '1.2'
103
+ requirements: []
104
+ rubyforge_project: thin_upload
105
+ rubygems_version: 1.8.8
106
+ signing_key:
107
+ specification_version: 3
108
+ summary: Upload progress meter for thin ruby server.
109
+ test_files:
110
+ - test/test_helper.rb
111
+ - test/thin_upload/request_test.rb