hamster_powered 0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +40 -0
- data/Rakefile +4 -0
- data/app/views/layouts/hamster_powered_layout.html.erb +160 -0
- data/hamster_powered.gemspec +24 -0
- data/lib/hamster_powered.rb +18 -0
- data/lib/hamster_powered/.DS_Store +0 -0
- data/lib/hamster_powered/railtie.rb +7 -0
- data/lib/hamster_powered/version.rb +3 -0
- data/spec/hamster_powered_spec.rb +22 -0
- data/spec/spec_helper.rb +1 -0
- metadata +103 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 73bdbde102a5c579a8e4d4064c98a6409a53d3ae
|
4
|
+
data.tar.gz: d3bf7bea231588464e6df1f0e90eb22231a05477
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8cae33ebc3ae0e2a36b6741b2a7e3405baea2d008416360ff1adf5245c225cc7f19a012bf28dbb3b19ae2f97fcc78e33b557f1aed488a08164491a0ce64fe87d
|
7
|
+
data.tar.gz: df6112d448d0c545ba905379b6ddf6e4b4290a959d487f1032326bb2360e94534f9de24de445d944da3f8b7a914d921be864bb6b54f98efe5836431b49e07f69
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Jonathan Kirst
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# Hamster Powered
|
2
|
+
|
3
|
+
Not everything deserves a background task, especially when you want to quickly prototype something. Use HTTP Streaming to process those long running processes in real time instead! This approach is well suited for situations where you have a large number of atomic operations that would take > 10 seconds to complete.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
Let's say you need to save a large number of newly instantiated objects to the database (after reading from a CSV file, for instance). Well, here's a simpler example:
|
8
|
+
|
9
|
+
objects_to_act_on = (1..10000).to_a
|
10
|
+
action = :to_s
|
11
|
+
redirect = root_url
|
12
|
+
|
13
|
+
render as_processing_screen(objects_to_act_on, action, redirect)
|
14
|
+
|
15
|
+
The actions will be processed in the view layer and the results streamed to the user, who sees a simple message and progress bar.
|
16
|
+
Once the actions have been completed, the user will be directed to follow a link to the location you specify in the redirect argument.
|
17
|
+
|
18
|
+
Simple as pie made by hamsters.
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
|
22
|
+
Add this line to your application's Gemfile:
|
23
|
+
|
24
|
+
gem 'hamster_powered'
|
25
|
+
|
26
|
+
And then execute:
|
27
|
+
|
28
|
+
$ bundle
|
29
|
+
|
30
|
+
Or install it yourself as:
|
31
|
+
|
32
|
+
$ gem install hamster_powered
|
33
|
+
|
34
|
+
## Contributing
|
35
|
+
|
36
|
+
1. Fork it
|
37
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
38
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
39
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
40
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<style>
|
5
|
+
html { font-family: sans-serif; }
|
6
|
+
|
7
|
+
body { text-align: center; }
|
8
|
+
|
9
|
+
.container { width: 750px; margin: 100px auto 100px auto; }
|
10
|
+
|
11
|
+
.jumbotron {
|
12
|
+
padding: 30px;
|
13
|
+
font-size: 22.5px;
|
14
|
+
font-weight: 200;
|
15
|
+
line-height: 2.1428571435;
|
16
|
+
color: inherit;
|
17
|
+
background-color: #ecf0f1;
|
18
|
+
margin-bottom: 30px;
|
19
|
+
|
20
|
+
-webkit-transition: height 2.0s ease;
|
21
|
+
transition: height 2.0s ease;
|
22
|
+
}
|
23
|
+
|
24
|
+
.jumbotron h1 {
|
25
|
+
font-weight: lighter;
|
26
|
+
line-height: 1;
|
27
|
+
color: inherit;
|
28
|
+
}
|
29
|
+
|
30
|
+
.jumbotron h2 {
|
31
|
+
font-weight: lighter;
|
32
|
+
line-height: 1.4;
|
33
|
+
}
|
34
|
+
|
35
|
+
.jumbotron h3 {
|
36
|
+
font-weight: lighter;
|
37
|
+
line-height: 1.4;
|
38
|
+
}
|
39
|
+
|
40
|
+
.progress {
|
41
|
+
height: 21px;
|
42
|
+
margin-bottom: 21px;
|
43
|
+
overflow: hidden;
|
44
|
+
background-color: #ecf0f1;
|
45
|
+
border-radius: 4px;
|
46
|
+
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
47
|
+
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
48
|
+
}
|
49
|
+
|
50
|
+
.progress-bar {
|
51
|
+
float: left;
|
52
|
+
width: 0;
|
53
|
+
height: 100%;
|
54
|
+
font-size: 13px;
|
55
|
+
color: #ffffff;
|
56
|
+
text-align: center;
|
57
|
+
background-color: #2c3e50;
|
58
|
+
-webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
|
59
|
+
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
|
60
|
+
-webkit-transition: width 0.6s ease;
|
61
|
+
transition: width 0.6s ease;
|
62
|
+
}
|
63
|
+
|
64
|
+
.progress-bar-success {
|
65
|
+
background-color: #18bc9c;
|
66
|
+
}
|
67
|
+
|
68
|
+
.btn {
|
69
|
+
display: inline-block;
|
70
|
+
padding: 10px 15px;
|
71
|
+
margin-bottom: 0;
|
72
|
+
font-size: 15px;
|
73
|
+
font-weight: normal;
|
74
|
+
line-height: 1.428571429;
|
75
|
+
text-align: center;
|
76
|
+
white-space: nowrap;
|
77
|
+
vertical-align: middle;
|
78
|
+
cursor: pointer;
|
79
|
+
border: 1px solid transparent;
|
80
|
+
border-radius: 4px;
|
81
|
+
-webkit-user-select: none;
|
82
|
+
-moz-user-select: none;
|
83
|
+
-ms-user-select: none;
|
84
|
+
-o-user-select: none;
|
85
|
+
user-select: none;
|
86
|
+
background-color: #7f9293;
|
87
|
+
}
|
88
|
+
|
89
|
+
.btn:focus {
|
90
|
+
outline: thin dotted #333;
|
91
|
+
outline: 5px auto -webkit-focus-ring-color;
|
92
|
+
outline-offset: -2px;
|
93
|
+
}
|
94
|
+
|
95
|
+
.btn:hover,
|
96
|
+
.btn:focus {
|
97
|
+
color: #ffffff;
|
98
|
+
text-decoration: none;
|
99
|
+
}
|
100
|
+
|
101
|
+
.btn:active,
|
102
|
+
.btn.active {
|
103
|
+
background-image: none;
|
104
|
+
outline: 0;
|
105
|
+
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
106
|
+
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
107
|
+
}
|
108
|
+
|
109
|
+
.btn-default {
|
110
|
+
color: #ffffff;
|
111
|
+
background-color: #95a5a6;
|
112
|
+
border-color: #95a5a6;
|
113
|
+
text-decoration: none;
|
114
|
+
}
|
115
|
+
|
116
|
+
.btn-default:hover,
|
117
|
+
.btn-default:focus,
|
118
|
+
.btn-default:active,
|
119
|
+
.btn-default.active,
|
120
|
+
.open .dropdown-toggle.btn-default {
|
121
|
+
color: #ffffff;
|
122
|
+
background-color: #7f9293;
|
123
|
+
border-color: #74898a;
|
124
|
+
}
|
125
|
+
|
126
|
+
.btn-default:active,
|
127
|
+
.btn-default.active,
|
128
|
+
.open .dropdown-toggle.btn-default {
|
129
|
+
background-image: none;
|
130
|
+
}
|
131
|
+
</style>
|
132
|
+
<body>
|
133
|
+
<div class="container">
|
134
|
+
<div class="jumbotron">
|
135
|
+
<h1>We are processing your request...</h1>
|
136
|
+
<h2>This will only take a minute!</h2>
|
137
|
+
<p>Don't close this window! You can go roam the internets on other windows, but stay here till we tell you its time to go. Our hamsters are working hard, promise.</p>
|
138
|
+
</div>
|
139
|
+
<div class="progress">
|
140
|
+
<div id="progress_bar" class="progress-bar progress-success"></div>
|
141
|
+
</div>
|
142
|
+
<div id="output" style="display: none;">
|
143
|
+
<% total = @hp_objects.size %>
|
144
|
+
<% @hp_objects.each_with_index do |o, i| %>
|
145
|
+
<% o.send(@hp_action) %>
|
146
|
+
<span><%= "#{i+1}/#{total}" %></span>
|
147
|
+
<% if (i+1) % 10 %>
|
148
|
+
<script>document.getElementById("progress_bar").style.width = "<%= ((i+1).to_f / total)*100 %>%";</script>
|
149
|
+
<% end %>
|
150
|
+
<% end %>
|
151
|
+
<% sleep 2 %>
|
152
|
+
</div>
|
153
|
+
|
154
|
+
<script>
|
155
|
+
document.getElementsByClassName("jumbotron")[0].innerHTML = "<h1 class='finished'>All Done!</h1><h3>You may continue on now. The hamsters appreciate your patience.</h3>"
|
156
|
+
</script>
|
157
|
+
<a class="btn btn-default" href="<%= @hp_redirect%>">Continue</a>
|
158
|
+
</div>
|
159
|
+
</body>
|
160
|
+
</html>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'hamster_powered/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "hamster_powered"
|
8
|
+
spec.version = HamsterPowered::VERSION
|
9
|
+
spec.authors = ["Jonathan Kirst"]
|
10
|
+
spec.email = ["jskirst@gmail.com"]
|
11
|
+
spec.description = %q{Uses Rails HTTP Streaming to render a 'processing request' page that will keep the connection alive during long processes.}
|
12
|
+
spec.summary = %q{This is a very hacky way to utilize HTTP Streaming, but it can be very useful if you are using Heroku and want to avoid the cost/complexit of worker threads.}
|
13
|
+
spec.homepage = "https://github.com/jskirst/hamster_powered"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rspec"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "hamster_powered/version"
|
2
|
+
require "hamster_powered/railtie" if defined? Rails
|
3
|
+
|
4
|
+
module HamsterPowered
|
5
|
+
module HamsterHelper
|
6
|
+
def as_processing_screen(objects, action, redirect)
|
7
|
+
unless objects and action and redirect
|
8
|
+
raise "HamsterPowered: missing required arguments"
|
9
|
+
end
|
10
|
+
|
11
|
+
@hp_objects = objects
|
12
|
+
@hp_action = action
|
13
|
+
@hp_redirect = redirect
|
14
|
+
|
15
|
+
return { inline: "", stream: true, layout: "hamster_powered_layout" }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
Binary file
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe HamsterPowered do
|
4
|
+
include HamsterPowered::HamsterHelper
|
5
|
+
|
6
|
+
describe "as_processing_screen" do
|
7
|
+
it "should return the appropriate arguments for render to use" do
|
8
|
+
objects = [1,2,3]
|
9
|
+
action = :to_s
|
10
|
+
redirect = "http://www.google.com"
|
11
|
+
|
12
|
+
args = as_processing_screen(objects, action, redirect)
|
13
|
+
args[:inline].should eq("")
|
14
|
+
args[:stream].should eq(true)
|
15
|
+
args[:layout].should eq("hamster_powered_layout")
|
16
|
+
|
17
|
+
@hp_objects.should eq(objects)
|
18
|
+
@hp_action.should eq(action)
|
19
|
+
@hp_redirect.should eq(redirect)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'hamster_powered'
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hamster_powered
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.2'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jonathan Kirst
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-09-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Uses Rails HTTP Streaming to render a 'processing request' page that
|
56
|
+
will keep the connection alive during long processes.
|
57
|
+
email:
|
58
|
+
- jskirst@gmail.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- .gitignore
|
64
|
+
- Gemfile
|
65
|
+
- LICENSE.txt
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- app/views/layouts/hamster_powered_layout.html.erb
|
69
|
+
- hamster_powered.gemspec
|
70
|
+
- lib/hamster_powered.rb
|
71
|
+
- lib/hamster_powered/.DS_Store
|
72
|
+
- lib/hamster_powered/railtie.rb
|
73
|
+
- lib/hamster_powered/version.rb
|
74
|
+
- spec/hamster_powered_spec.rb
|
75
|
+
- spec/spec_helper.rb
|
76
|
+
homepage: https://github.com/jskirst/hamster_powered
|
77
|
+
licenses:
|
78
|
+
- MIT
|
79
|
+
metadata: {}
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
requirements: []
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 2.0.2
|
97
|
+
signing_key:
|
98
|
+
specification_version: 4
|
99
|
+
summary: This is a very hacky way to utilize HTTP Streaming, but it can be very useful
|
100
|
+
if you are using Heroku and want to avoid the cost/complexit of worker threads.
|
101
|
+
test_files:
|
102
|
+
- spec/hamster_powered_spec.rb
|
103
|
+
- spec/spec_helper.rb
|