poto 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +4 -0
  5. data/.travis.yml +3 -0
  6. data/CODE_OF_CONDUCT.md +49 -0
  7. data/Dockerfile +21 -0
  8. data/Gemfile +14 -0
  9. data/LICENSE.txt +21 -0
  10. data/Procfile +1 -0
  11. data/README.md +97 -0
  12. data/Rakefile +10 -0
  13. data/bin/console +14 -0
  14. data/bin/setup +8 -0
  15. data/docker-compose.yml +16 -0
  16. data/exe/poto-aws-s3 +29 -0
  17. data/exe/poto-google-cloud-storage +34 -0
  18. data/lib/poto.rb +11 -0
  19. data/lib/poto/api.rb +62 -0
  20. data/lib/poto/app.rb +11 -0
  21. data/lib/poto/ext/open_uri.rb +7 -0
  22. data/lib/poto/file_repository/aws/s3.rb +32 -0
  23. data/lib/poto/file_repository/aws/s3/client.rb +33 -0
  24. data/lib/poto/file_repository/aws/s3/file_collection_mapper.rb +36 -0
  25. data/lib/poto/file_repository/aws/s3/file_mapper.rb +37 -0
  26. data/lib/poto/file_repository/dsl.rb +25 -0
  27. data/lib/poto/file_repository/file.rb +5 -0
  28. data/lib/poto/file_repository/file_collection.rb +5 -0
  29. data/lib/poto/file_repository/google/cloud/storage.rb +34 -0
  30. data/lib/poto/file_repository/google/cloud/storage/file_collection_mapper.rb +37 -0
  31. data/lib/poto/file_repository/google/cloud/storage/file_mapper.rb +39 -0
  32. data/lib/poto/file_repository/proxy.rb +27 -0
  33. data/lib/poto/image_proxy.rb +45 -0
  34. data/lib/poto/representers/file_collection_representer.rb +22 -0
  35. data/lib/poto/representers/file_representer.rb +19 -0
  36. data/lib/poto/services/download.rb +24 -0
  37. data/lib/poto/services/file_cache.rb +28 -0
  38. data/lib/poto/services/resize.rb +23 -0
  39. data/lib/poto/version.rb +3 -0
  40. data/poto.gemspec +40 -0
  41. data/public/ajax-loader.gif +0 -0
  42. data/public/index.html +150 -0
  43. metadata +244 -0
@@ -0,0 +1,28 @@
1
+ require 'digest'
2
+
3
+ module Poto
4
+ module Services
5
+ class FileCache
6
+ attr_reader :path
7
+
8
+ def initialize(path:)
9
+ @path = path
10
+ end
11
+
12
+ def cache(key)
13
+ File.join(path, filename(key)).tap do |cache_path|
14
+ unless File.exist?(cache_path)
15
+ file_path = yield
16
+ FileUtils.cp(file_path, cache_path)
17
+ end
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def filename(key)
24
+ Digest::SHA256.hexdigest(key)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,23 @@
1
+ require 'mini_magick'
2
+
3
+ module Poto
4
+ module Services
5
+ class Resize
6
+ attr_reader :path, :width, :height
7
+
8
+ def initialize(path:, width:, height:)
9
+ @path = path
10
+ @width = width
11
+ @height = height
12
+ end
13
+
14
+ def call
15
+ image = MiniMagick::Image.open(path)
16
+ image.resize([width, height].compact.join('x'))
17
+ image.format('png')
18
+ image.write(path)
19
+ image.path
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ module Poto
2
+ VERSION = '2.0.2'.freeze
3
+ end
@@ -0,0 +1,40 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'poto/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "poto"
8
+ spec.version = Poto::VERSION
9
+ spec.authors = ["James Moriarty"]
10
+ spec.email = ["jamespaulmoriarty@gmail.com"]
11
+
12
+ spec.summary = %q{Cloud storage to image gallery + image proxy + file api}
13
+ spec.homepage = "https://github.com/jamesmoriarty/poto"
14
+ spec.license = "MIT"
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ # if spec.respond_to?(:metadata)
19
+ # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
20
+ # else
21
+ # raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
22
+ # end
23
+
24
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ spec.bindir = "exe"
26
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ["lib"]
28
+
29
+ spec.add_runtime_dependency 'activesupport'
30
+ spec.add_runtime_dependency 'aws-sdk'
31
+ spec.add_runtime_dependency 'google-cloud-storage'
32
+ spec.add_runtime_dependency 'grape', '~> 0.11'
33
+ spec.add_runtime_dependency 'grape-roar', '~> 0.3'
34
+ spec.add_runtime_dependency 'mini_magick'
35
+ spec.add_runtime_dependency 'puma'
36
+ spec.add_runtime_dependency 'roar'
37
+ spec.add_runtime_dependency 'sinatra'
38
+ spec.add_development_dependency "bundler", "~> 1.11"
39
+ spec.add_development_dependency "rake", "~> 10.0"
40
+ end
Binary file
@@ -0,0 +1,150 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv='Content-type' content='text/html; charset=utf-8'>
5
+ <title>Poto</title>
6
+ <style>
7
+ button {
8
+ float: left;
9
+ width: 100%;
10
+ margin-bottom: 1em;
11
+ height: 3em;
12
+ background-color: #fff;
13
+ border: solid 1px #ccc;
14
+ cursor: pointer;
15
+ }
16
+
17
+ button:hover {
18
+ border: solid 1px #777;
19
+ }
20
+
21
+ button:disabled {
22
+ cursor: wait;
23
+ }
24
+
25
+ .imageList {
26
+ display: flex;
27
+ flex-wrap: wrap;
28
+ }
29
+
30
+ .imageList *, button {
31
+ font-family: Arial, Helvetica, sans-serif;
32
+ font-size: 1em;
33
+ }
34
+
35
+ .imageList .image {
36
+ margin: 5px;
37
+ border: 1px solid #ccc;
38
+ float: left;
39
+ width: 180px;
40
+ }
41
+
42
+ .imageList .image:hover {
43
+ border: 1px solid #777;
44
+ }
45
+
46
+ .imageList .image img {
47
+ width: 100%;
48
+ height: auto;
49
+ min-height: 96px;
50
+ background-image: url(/ajax-loader.gif);
51
+ background-position: 50% 50%;
52
+ background-repeat: no-repeat;
53
+ }
54
+
55
+ .imageList .image .desc {
56
+ padding: 15px;
57
+ text-align: center;
58
+ white-space: nowrap;
59
+ overflow: hidden;
60
+ text-overflow: ellipsis;
61
+ }
62
+ </style>
63
+ </head>
64
+ <body>
65
+ <div id="container" />
66
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.js"></script>
67
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
68
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/2.10.0/bluebird.js"></script>
69
+ <script type="text/jsx">
70
+ var ImageGallery = React.createClass({
71
+ getInitialState: function() {
72
+ return { images: this.props.images, href: this.props.href, disabled: "" };
73
+ },
74
+
75
+ getUrl: function(url){
76
+ var xhr = new XMLHttpRequest;
77
+ return new Promise(function (resolve, reject) {
78
+ xhr.addEventListener("error", reject);
79
+ xhr.addEventListener("load", resolve);
80
+ xhr.open("GET", url);
81
+ xhr.send(null);
82
+ }).cancellable().catch(Promise.CancellationError, function(e) {
83
+ xhr.abort();
84
+ throw e;
85
+ });
86
+ },
87
+
88
+ processResult: function(result) {
89
+ var url = "/image_proxy?width=500&height=500&src=";
90
+ var json = JSON.parse(result.target.response);
91
+ var href = json._links.next.href;
92
+ var newImages = json._embedded.files.map(function(file) {
93
+ var src = url + encodeURIComponent(file._links.file.href);
94
+ return { name: file.name, src: src, href: file._links.file.href };
95
+ })
96
+
97
+ return this.setState({ images: this.state.images.concat(newImages), href: href });
98
+ },
99
+
100
+ disableButton: function() {
101
+ this.setState({ disabled: "disabled" });
102
+ },
103
+
104
+ enableButton: function() {
105
+ this.setState({ disabled: ""});
106
+ },
107
+
108
+ handleClick: function(event) {
109
+ this.disableButton();
110
+
111
+ this.getUrl(this.state.href).then(this.processResult).finally(this.enableButton);
112
+ },
113
+
114
+ render: function() {
115
+ return (
116
+ <div>
117
+ <ImageList images={this.state.images}/>
118
+ <button disabled={this.state.disabled} href={this.state.href} onClick={this.handleClick}>Load Images</button>
119
+ </div>
120
+ );
121
+ }
122
+ });
123
+
124
+ var ImageList = React.createClass({
125
+ render: function() {
126
+ var images = this.props.images.map(function (image) {
127
+ return (
128
+ <div className="image">
129
+ <a target="_blank" href={image.href}>
130
+ <img key={image.src} src={image.src} />
131
+ </a>
132
+ <div className="desc">{image.name}</div>
133
+ </div>
134
+ );
135
+ });
136
+ return (
137
+ <div className="imageList">
138
+ {images}
139
+ </div>
140
+ );
141
+ }
142
+ });
143
+
144
+ React.render(
145
+ <ImageGallery images={[]} href={"/api/files?per_page=9"} />,
146
+ document.getElementById('container')
147
+ );
148
+ </script>
149
+ </body>
150
+ </html>
metadata ADDED
@@ -0,0 +1,244 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: poto
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.2
5
+ platform: ruby
6
+ authors:
7
+ - James Moriarty
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-12-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: aws-sdk
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
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: google-cloud-storage
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: grape
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '0.11'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '0.11'
69
+ - !ruby/object:Gem::Dependency
70
+ name: grape-roar
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '0.3'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '0.3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: mini_magick
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: puma
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: roar
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: sinatra
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: bundler
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ~>
144
+ - !ruby/object:Gem::Version
145
+ version: '1.11'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ~>
151
+ - !ruby/object:Gem::Version
152
+ version: '1.11'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rake
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ~>
158
+ - !ruby/object:Gem::Version
159
+ version: '10.0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ~>
165
+ - !ruby/object:Gem::Version
166
+ version: '10.0'
167
+ description:
168
+ email:
169
+ - jamespaulmoriarty@gmail.com
170
+ executables:
171
+ - poto-aws-s3
172
+ - poto-google-cloud-storage
173
+ extensions: []
174
+ extra_rdoc_files: []
175
+ files:
176
+ - .gitignore
177
+ - .rspec
178
+ - .rubocop.yml
179
+ - .travis.yml
180
+ - CODE_OF_CONDUCT.md
181
+ - Dockerfile
182
+ - Gemfile
183
+ - Gemfile.lock
184
+ - LICENSE.txt
185
+ - Procfile
186
+ - README.md
187
+ - Rakefile
188
+ - bin/console
189
+ - bin/setup
190
+ - doc/Demo.gif
191
+ - doc/Poto.png
192
+ - docker-compose.yml
193
+ - exe/poto-aws-s3
194
+ - exe/poto-google-cloud-storage
195
+ - lib/poto.rb
196
+ - lib/poto/api.rb
197
+ - lib/poto/app.rb
198
+ - lib/poto/ext/open_uri.rb
199
+ - lib/poto/file_repository/aws/s3.rb
200
+ - lib/poto/file_repository/aws/s3/client.rb
201
+ - lib/poto/file_repository/aws/s3/file_collection_mapper.rb
202
+ - lib/poto/file_repository/aws/s3/file_mapper.rb
203
+ - lib/poto/file_repository/dsl.rb
204
+ - lib/poto/file_repository/file.rb
205
+ - lib/poto/file_repository/file_collection.rb
206
+ - lib/poto/file_repository/google/cloud/storage.rb
207
+ - lib/poto/file_repository/google/cloud/storage/file_collection_mapper.rb
208
+ - lib/poto/file_repository/google/cloud/storage/file_mapper.rb
209
+ - lib/poto/file_repository/proxy.rb
210
+ - lib/poto/image_proxy.rb
211
+ - lib/poto/representers/file_collection_representer.rb
212
+ - lib/poto/representers/file_representer.rb
213
+ - lib/poto/services/download.rb
214
+ - lib/poto/services/file_cache.rb
215
+ - lib/poto/services/resize.rb
216
+ - lib/poto/version.rb
217
+ - poto.gemspec
218
+ - public/ajax-loader.gif
219
+ - public/index.html
220
+ homepage: https://github.com/jamesmoriarty/poto
221
+ licenses:
222
+ - MIT
223
+ metadata: {}
224
+ post_install_message:
225
+ rdoc_options: []
226
+ require_paths:
227
+ - lib
228
+ required_ruby_version: !ruby/object:Gem::Requirement
229
+ requirements:
230
+ - - '>='
231
+ - !ruby/object:Gem::Version
232
+ version: '0'
233
+ required_rubygems_version: !ruby/object:Gem::Requirement
234
+ requirements:
235
+ - - '>='
236
+ - !ruby/object:Gem::Version
237
+ version: '0'
238
+ requirements: []
239
+ rubyforge_project:
240
+ rubygems_version: 2.0.14.1
241
+ signing_key:
242
+ specification_version: 4
243
+ summary: Cloud storage to image gallery + image proxy + file api
244
+ test_files: []