helios 0.2.1 → 0.2.2
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +50 -21
- data/README.md +27 -2
- data/helios.gemspec +10 -6
- data/lib/helios.rb +10 -4
- data/lib/helios/backend.rb +29 -22
- data/lib/helios/backend/data.rb +10 -5
- data/lib/helios/backend/in-app-purchase.rb +4 -2
- data/lib/helios/backend/newsstand.rb +97 -0
- data/lib/helios/backend/passbook.rb +8 -2
- data/lib/helios/backend/push-notification.rb +25 -12
- data/lib/helios/commands/console.rb +4 -10
- data/lib/helios/commands/new.rb +0 -1
- data/lib/helios/commands/server.rb +4 -1
- data/lib/helios/frontend.rb +6 -14
- data/lib/helios/frontend/images/helios.svg +33 -0
- data/lib/helios/frontend/javascripts/helios.coffee +39 -3
- data/lib/helios/frontend/javascripts/helios/collections.coffee +10 -2
- data/lib/helios/frontend/javascripts/helios/models.coffee +4 -1
- data/lib/helios/frontend/javascripts/helios/router.coffee +13 -1
- data/lib/helios/frontend/javascripts/helios/views.coffee +82 -8
- data/lib/helios/frontend/javascripts/vendor/jquery/jquery.fileupload-ui.js +807 -0
- data/lib/helios/frontend/javascripts/vendor/jquery/jquery.fileupload.js +1201 -0
- data/lib/helios/frontend/javascripts/vendor/jquery/jquery.ui.widget.js +530 -0
- data/lib/helios/frontend/javascripts/vendor/linkheaders.js +117 -0
- data/lib/helios/frontend/stylesheets/_iphone.sass +1 -1
- data/lib/helios/frontend/stylesheets/screen.sass +2 -6
- data/lib/helios/frontend/templates/{entities.jst.tpl → data/entities.jst.tpl} +0 -0
- data/lib/helios/frontend/templates/{receipts.jst.tpl → in-app-purchase/receipts.jst.tpl} +0 -0
- data/lib/helios/frontend/templates/navigation.jst.tpl +31 -0
- data/lib/helios/frontend/templates/newsstand/issues.jst.tpl +16 -0
- data/lib/helios/frontend/templates/newsstand/new.jst.tpl +28 -0
- data/lib/helios/frontend/templates/{passes.jst.tpl → passbook/passes.jst.tpl} +0 -0
- data/lib/helios/frontend/templates/{compose.jst.tpl → push-notification/compose.jst.tpl} +0 -0
- data/lib/helios/frontend/templates/{devices.jst.tpl → push-notification/devices.jst.tpl} +0 -0
- data/lib/helios/frontend/views/index.haml +4 -28
- data/lib/helios/templates/.env.erb +1 -0
- data/lib/helios/templates/.gitignore +3 -0
- data/lib/helios/version.rb +1 -1
- metadata +86 -20
- data/lib/helios/frontend/stylesheets/_bariol.scss +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 804589d0f2e0ada259f0b9fed0746db10843ef8c
|
4
|
+
data.tar.gz: 05599e5a5f8d21b616dd6ae7e0cfdfd2cf33e34b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12d3ceb7bf25ea1040f3ecb0faffbe2dd433a4733c407cb4f86ccb43db471d623759a678089f10f4f45740ec1dc1d9f3e90b1b07dd393aaae684da4944632053
|
7
|
+
data.tar.gz: 58e382a519b93419ee86cb8a195c80fed29693bbe2ae0f588355dab9e7f22629be19b6fb1f870b45ca711fc72a7355900951a59b593e357aefb1967084ae976f
|
data/Gemfile.lock
CHANGED
@@ -1,22 +1,26 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
helios (0.2.
|
4
|
+
helios (0.2.2)
|
5
5
|
coffee-script (~> 2.2)
|
6
6
|
commander (~> 4.1)
|
7
7
|
compass (~> 0.12)
|
8
|
+
core_data
|
9
|
+
fog (~> 1.10)
|
8
10
|
foreman (~> 0.63)
|
9
11
|
haml (>= 3.1)
|
12
|
+
houston (~> 0.2)
|
10
13
|
json (~> 1.7)
|
11
14
|
rack-contrib (~> 1.1)
|
12
|
-
rack-core-data (~> 0.3)
|
13
15
|
rack-in-app-purchase (~> 0.1)
|
16
|
+
rack-newsstand (~> 0.1)
|
14
17
|
rack-passbook (~> 0.1)
|
15
18
|
rack-push-notification (~> 0.4)
|
19
|
+
rack-scaffold
|
16
20
|
rails-database-url (~> 1.0)
|
17
21
|
sinatra (~> 1.3)
|
18
|
-
sinatra-assetpack (~> 0.
|
19
|
-
sinatra-backbone (~> 0.1.
|
22
|
+
sinatra-assetpack (~> 0.2.2)
|
23
|
+
sinatra-backbone (~> 0.1.1)
|
20
24
|
sinatra-contrib (~> 1.3)
|
21
25
|
sinatra-param (~> 0.1)
|
22
26
|
sinatra-support (~> 1.2)
|
@@ -29,6 +33,7 @@ GEM
|
|
29
33
|
i18n (= 0.6.1)
|
30
34
|
multi_json (~> 1.0)
|
31
35
|
backports (3.3.0)
|
36
|
+
builder (3.2.0)
|
32
37
|
chunky_png (1.2.8)
|
33
38
|
coffee-script (2.2.0)
|
34
39
|
coffee-script-source
|
@@ -40,55 +45,77 @@ GEM
|
|
40
45
|
chunky_png (~> 1.2)
|
41
46
|
fssm (>= 0.2.7)
|
42
47
|
sass (~> 3.1)
|
48
|
+
core_data (0.1.1)
|
49
|
+
nokogiri (~> 1.4)
|
43
50
|
diff-lcs (1.2.4)
|
44
51
|
dotenv (0.7.0)
|
45
52
|
eventmachine (1.0.3)
|
53
|
+
excon (0.21.0)
|
46
54
|
execjs (1.4.0)
|
47
55
|
multi_json (~> 1.0)
|
56
|
+
fog (1.11.1)
|
57
|
+
builder
|
58
|
+
excon (~> 0.20)
|
59
|
+
formatador (~> 0.2.0)
|
60
|
+
json (~> 1.7)
|
61
|
+
mime-types
|
62
|
+
net-scp (~> 1.1)
|
63
|
+
net-ssh (>= 2.1.3)
|
64
|
+
nokogiri (~> 1.5.0)
|
65
|
+
ruby-hmac
|
48
66
|
foreman (0.63.0)
|
49
67
|
dotenv (>= 0.7)
|
50
68
|
thor (>= 0.13.6)
|
69
|
+
formatador (0.2.4)
|
51
70
|
fssm (0.2.10)
|
52
71
|
haml (4.0.2)
|
53
72
|
tilt
|
54
73
|
highline (1.6.18)
|
55
|
-
houston (0.
|
56
|
-
commander (~> 4.1
|
57
|
-
json
|
74
|
+
houston (0.2.2)
|
75
|
+
commander (~> 4.1)
|
76
|
+
json
|
58
77
|
i18n (0.6.1)
|
59
78
|
jsmin (1.0.1)
|
60
79
|
json (1.7.7)
|
61
|
-
|
80
|
+
mime-types (1.23)
|
81
|
+
multi_json (1.7.3)
|
82
|
+
net-scp (1.1.0)
|
83
|
+
net-ssh (>= 2.6.5)
|
84
|
+
net-ssh (2.6.7)
|
62
85
|
nokogiri (1.5.9)
|
86
|
+
plist (3.1.0)
|
63
87
|
rack (1.5.2)
|
64
88
|
rack-contrib (1.1.0)
|
65
89
|
rack (>= 0.9.1)
|
66
|
-
rack-
|
67
|
-
activesupport (>= 3.0)
|
68
|
-
nokogiri (~> 1.4)
|
90
|
+
rack-in-app-purchase (0.1.0)
|
69
91
|
rack (~> 1.4)
|
70
|
-
rack-contrib (~> 1.1)
|
71
92
|
sequel (~> 3.37)
|
72
93
|
sinatra (~> 1.3)
|
73
|
-
|
74
|
-
rack-
|
94
|
+
venice
|
95
|
+
rack-newsstand (0.1.1)
|
96
|
+
builder (>= 3.0)
|
97
|
+
plist (~> 3.1)
|
75
98
|
rack (~> 1.4)
|
76
99
|
sequel (~> 3.37)
|
77
100
|
sinatra (~> 1.3)
|
78
|
-
venice
|
79
101
|
rack-passbook (0.1.1)
|
80
102
|
rack (~> 1.4)
|
81
103
|
sequel (~> 3.37)
|
82
104
|
sinatra (~> 1.3)
|
83
105
|
rack-protection (1.5.0)
|
84
106
|
rack
|
85
|
-
rack-push-notification (0.4.
|
86
|
-
houston (~> 0.1.1)
|
107
|
+
rack-push-notification (0.4.1)
|
87
108
|
rack (~> 1.4)
|
88
109
|
rack-contrib (~> 1.1)
|
89
110
|
sequel (~> 3.37)
|
90
111
|
sinatra (~> 1.3)
|
91
112
|
sinatra-param (~> 0.1)
|
113
|
+
rack-scaffold (0.0.1)
|
114
|
+
activesupport (>= 3.0)
|
115
|
+
rack (~> 1.4)
|
116
|
+
rack-contrib (~> 1.1)
|
117
|
+
sinatra (~> 1.3)
|
118
|
+
sinatra-param (~> 0.1)
|
92
119
|
rack-test (0.6.2)
|
93
120
|
rack (>= 1.0)
|
94
121
|
rails-database-url (1.0.0)
|
@@ -101,13 +128,15 @@ GEM
|
|
101
128
|
rspec-expectations (2.13.0)
|
102
129
|
diff-lcs (>= 1.1.3, < 2.0)
|
103
130
|
rspec-mocks (2.13.1)
|
104
|
-
|
105
|
-
|
131
|
+
ruby-hmac (0.4.0)
|
132
|
+
sass (3.2.9)
|
133
|
+
sequel (3.47.0)
|
106
134
|
sinatra (1.4.2)
|
107
135
|
rack (~> 1.5, >= 1.5.2)
|
108
136
|
rack-protection (~> 1.4)
|
109
137
|
tilt (~> 1.3, >= 1.3.4)
|
110
|
-
sinatra-assetpack (0.
|
138
|
+
sinatra-assetpack (0.2.2)
|
139
|
+
backports
|
111
140
|
jsmin
|
112
141
|
rack-test
|
113
142
|
sinatra
|
@@ -127,7 +156,7 @@ GEM
|
|
127
156
|
sinatra (>= 1.0)
|
128
157
|
terminal-table (1.4.5)
|
129
158
|
thor (0.18.1)
|
130
|
-
tilt (1.
|
159
|
+
tilt (1.4.1)
|
131
160
|
venice (0.1.0)
|
132
161
|
commander (~> 4.1)
|
133
162
|
json
|
data/README.md
CHANGED
@@ -76,7 +76,7 @@ Bundler.require
|
|
76
76
|
|
77
77
|
run Helios::Application.new do
|
78
78
|
service :data, model: 'path/to/DataModel.xcdatamodel'
|
79
|
-
service :push_notification
|
79
|
+
service :push_notification, apn_certificate: 'path/to/apple_push_notification.pem', apn_environment: 'development'
|
80
80
|
service :in_app_purchase
|
81
81
|
service :passbook
|
82
82
|
end
|
@@ -102,7 +102,7 @@ Helios can be run as Rails middleware by adding this to the configuration block
|
|
102
102
|
```ruby
|
103
103
|
config.middleware.use Helios::Application do
|
104
104
|
service :data, model: 'path/to/DataModel.xcdatamodel'
|
105
|
-
service :push_notification
|
105
|
+
service :push_notification, apn_certificate: 'path/to/apple_push_notification.pem', apn_environment: 'development'
|
106
106
|
service :in_app_purchase
|
107
107
|
service :passbook
|
108
108
|
end
|
@@ -164,6 +164,10 @@ Each entity in the specified data model will have a `Sequel::Model` subclass cre
|
|
164
164
|
<td><tt>DELETE /devices/:token</tt></td>
|
165
165
|
<td>Unregister a device from receiving push notifications</td>
|
166
166
|
</tr>
|
167
|
+
<tr>
|
168
|
+
<td><tt>POST /message</tt></td>
|
169
|
+
<td>Send out a push notification to some devices</td>
|
170
|
+
</tr>
|
167
171
|
</table>
|
168
172
|
|
169
173
|
---
|
@@ -266,6 +270,12 @@ To run Helios in development mode on `localhost`, run the `server` command:
|
|
266
270
|
|
267
271
|
$ helios server
|
268
272
|
|
273
|
+
### Testing Push Notifications
|
274
|
+
|
275
|
+
Once you have registered a device and set up your certificate, try this:
|
276
|
+
|
277
|
+
$ curl -X POST -d 'payload={"aps": {"alert":"Blastoff!"}}' http://localhost:5000/message
|
278
|
+
|
269
279
|
### Running the Helios Console
|
270
280
|
|
271
281
|
You can start an IRB session with the runtime environment of the Helios application with the `console` command:
|
@@ -311,6 +321,21 @@ didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
|
|
311
321
|
}
|
312
322
|
```
|
313
323
|
|
324
|
+
### Converting Your Push Notification Certificate
|
325
|
+
|
326
|
+
> These instructions come from the [APN on Rails](https://github.com/PRX/apn_on_rails) project.
|
327
|
+
|
328
|
+
Once you have the certificate from Apple for your application, export your key
|
329
|
+
and the apple certificate as p12 files. Here is a quick walkthrough on how to do this:
|
330
|
+
|
331
|
+
1. Click the disclosure arrow next to your certificate in Keychain Access and select the certificate and the key.
|
332
|
+
2. Right click and choose `Export 2 items…`.
|
333
|
+
3. Choose the p12 format from the drop down and name it `cert.p12`.
|
334
|
+
|
335
|
+
Now covert the p12 file to a pem file:
|
336
|
+
|
337
|
+
$ openssl pkcs12 -in cert.p12 -out apple_push_notification.pem -nodes -clcerts
|
338
|
+
|
314
339
|
## Coming Attractions
|
315
340
|
|
316
341
|
There's still a lot to do to make Helios even better. Here are some ideas that are at the top of the list:
|
data/helios.gemspec
CHANGED
@@ -16,27 +16,31 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.add_dependency "commander", "~> 4.1"
|
17
17
|
s.add_dependency "foreman", "~> 0.63"
|
18
18
|
s.add_dependency "rack-contrib", "~> 1.1"
|
19
|
-
s.add_dependency "rack-core-data", "~> 0.3"
|
20
19
|
s.add_dependency "rack-push-notification", "~> 0.4"
|
21
20
|
s.add_dependency "rack-in-app-purchase", "~> 0.1"
|
22
21
|
s.add_dependency "rack-passbook", "~> 0.1"
|
22
|
+
s.add_dependency "rack-newsstand", "~> 0.1"
|
23
|
+
s.add_dependency "rack-scaffold"
|
24
|
+
s.add_dependency "core_data"
|
23
25
|
s.add_dependency "json", "~> 1.7"
|
24
26
|
s.add_dependency "coffee-script", "~> 2.2"
|
25
27
|
s.add_dependency "sinatra", "~> 1.3"
|
26
28
|
s.add_dependency "sinatra-contrib", "~> 1.3"
|
27
|
-
s.add_dependency "sinatra-assetpack", "~> 0.
|
28
|
-
s.add_dependency "sinatra-backbone", "~> 0.1.
|
29
|
+
s.add_dependency "sinatra-assetpack", "~> 0.2.2"
|
30
|
+
s.add_dependency "sinatra-backbone", "~> 0.1.1"
|
29
31
|
s.add_dependency "sinatra-param", "~> 0.1"
|
30
32
|
s.add_dependency "sinatra-support", "~> 1.2"
|
31
33
|
s.add_dependency "haml", ">= 3.1"
|
32
34
|
s.add_dependency "compass", "~> 0.12"
|
33
35
|
s.add_dependency "zurb-foundation", "4.1.2"
|
34
36
|
s.add_dependency "rails-database-url", "~> 1.0"
|
37
|
+
s.add_dependency "fog", "~> 1.10"
|
38
|
+
s.add_dependency "houston", "~> 0.2"
|
35
39
|
|
36
|
-
s.add_development_dependency "rake"
|
37
|
-
s.add_development_dependency "rspec"
|
40
|
+
s.add_development_dependency "rake"
|
41
|
+
s.add_development_dependency "rspec"
|
38
42
|
|
39
|
-
s.files = Dir["./**/*"].reject{|file| file =~ /\.\/(bin|example|log|pkg|script|spec|test|vendor)/} + Dir.glob("./lib/helios/templates", File::FNM_DOTMATCH)
|
43
|
+
s.files = Dir["./**/*"].reject{|file| file =~ /\.\/(bin|example|log|pkg|script|spec|test|vendor)/} + Dir.glob("./lib/helios/templates/*", File::FNM_DOTMATCH)
|
40
44
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
41
45
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
42
46
|
s.require_paths = ["lib"]
|
data/lib/helios.rb
CHANGED
@@ -3,11 +3,17 @@ require 'rack'
|
|
3
3
|
module Helios
|
4
4
|
class Application
|
5
5
|
def initialize(app = nil, options = {}, &block)
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
@app = Rack::Builder.new do
|
7
|
+
map '/admin' do
|
8
|
+
use Rack::Auth::Basic, "Restricted Area" do |username, password|
|
9
|
+
username == (ENV['HELIOS_ADMIN_USERNAME'] || "") and password == (ENV['HELIOS_ADMIN_PASSWORD'] || "")
|
10
|
+
end if ENV['HELIOS_ADMIN_USERNAME'] or ENV['HELIOS_ADMIN_PASSWORD']
|
9
11
|
|
10
|
-
|
12
|
+
run Helios::Frontend.new
|
13
|
+
end
|
14
|
+
|
15
|
+
run Helios::Backend.new(&block)
|
16
|
+
end
|
11
17
|
end
|
12
18
|
|
13
19
|
def call(env)
|
data/lib/helios/backend.rb
CHANGED
@@ -1,22 +1,31 @@
|
|
1
1
|
require 'rack'
|
2
2
|
|
3
3
|
module Helios
|
4
|
-
class Backend < Rack::
|
4
|
+
class Backend < Rack::Builder
|
5
|
+
DEFAULT_PATHS = {
|
6
|
+
data: '/'
|
7
|
+
}
|
8
|
+
|
5
9
|
require 'rails-database-url' if const_defined?(:Rails)
|
6
10
|
|
7
|
-
def initialize(&block)
|
8
|
-
|
11
|
+
def initialize(*args, &block)
|
12
|
+
raise ArgumentError, "Missing block" unless block_given?
|
13
|
+
super(&nil)
|
9
14
|
|
10
|
-
|
11
|
-
service :data, model: Dir['**/*.xcdatamodeld'].first rescue false
|
12
|
-
service :push_notification
|
13
|
-
service :in_app_purchase
|
14
|
-
service :passbook
|
15
|
-
} unless block_given?
|
15
|
+
@services = {}
|
16
16
|
|
17
17
|
instance_eval(&block)
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
+
def call(env)
|
21
|
+
return super(env) unless env["REQUEST_METHOD"] == "OPTIONS" and env["REQUEST_PATH"] == "/"
|
22
|
+
|
23
|
+
links = []
|
24
|
+
@services.each do |path, middleware|
|
25
|
+
links << %{<#{path}>; rel="#{middleware}"}
|
26
|
+
end
|
27
|
+
|
28
|
+
[206, {"Link" => links.join("\n")}, []]
|
20
29
|
end
|
21
30
|
|
22
31
|
private
|
@@ -28,30 +37,28 @@ module Helios
|
|
28
37
|
begin
|
29
38
|
middleware = Helios::Backend.const_get(constantize(identifier))
|
30
39
|
rescue NameError
|
31
|
-
raise LoadError, "Could not find matching service for #{identifier.inspect}. You may need to install an additional gem (such as helios-#{identifier})."
|
40
|
+
raise LoadError, "Could not find matching service for #{identifier.inspect} (Helios::Backend::#{constantize(identifier)}). You may need to install an additional gem (such as helios-#{identifier})."
|
32
41
|
end
|
33
42
|
end
|
34
43
|
|
35
|
-
|
44
|
+
path = "/#{(options.delete(:root) || DEFAULT_PATHS[identifier] || identifier)}".squeeze("/")
|
45
|
+
|
46
|
+
map path do
|
47
|
+
instance_eval(&block) if block_given?
|
48
|
+
run middleware.new(self, options)
|
49
|
+
end
|
36
50
|
|
37
|
-
@services
|
51
|
+
@services[path] = middleware
|
38
52
|
end
|
39
53
|
|
40
54
|
def constantize(identifier)
|
41
55
|
identifier.to_s.split(/([[:alpha:]]*)/).select{|c| /[[:alpha:]]/ === c}.map(&:capitalize).join("")
|
42
56
|
end
|
43
57
|
end
|
44
|
-
|
45
|
-
module Administerable
|
46
|
-
attr_accessor :admin
|
47
|
-
|
48
|
-
def admin?
|
49
|
-
!!@admin
|
50
|
-
end
|
51
|
-
end
|
52
58
|
end
|
53
59
|
|
54
60
|
require 'helios/backend/data'
|
55
|
-
require 'helios/backend/push-notification'
|
56
61
|
require 'helios/backend/in-app-purchase'
|
57
62
|
require 'helios/backend/passbook'
|
63
|
+
require 'helios/backend/push-notification'
|
64
|
+
require 'helios/backend/newsstand'
|
data/lib/helios/backend/data.rb
CHANGED
@@ -1,21 +1,26 @@
|
|
1
|
-
require '
|
1
|
+
require 'core_data'
|
2
|
+
require 'sequel'
|
3
|
+
|
4
|
+
require 'rack/scaffold'
|
5
|
+
|
6
|
+
require 'sinatra/base'
|
2
7
|
require 'sinatra/param'
|
3
8
|
|
9
|
+
|
4
10
|
class Helios::Backend::Data < Sinatra::Base
|
5
11
|
helpers Sinatra::Param
|
6
12
|
|
7
13
|
def initialize(app, options = {})
|
8
|
-
super(Rack::
|
14
|
+
super(Rack::Scaffold.new(options))
|
9
15
|
|
10
|
-
@model =
|
16
|
+
@model = CoreData::DataModel.new(options[:model]) rescue nil
|
11
17
|
end
|
12
18
|
|
13
19
|
before do
|
14
20
|
content_type :json
|
15
21
|
end
|
16
22
|
|
17
|
-
options '/' do
|
18
|
-
pass unless self.class < Helios::Administerable
|
23
|
+
options '/resources' do
|
19
24
|
|
20
25
|
links = []
|
21
26
|
@model.entities.each do |entity|
|
@@ -1,13 +1,15 @@
|
|
1
1
|
require 'rack/in-app-purchase'
|
2
|
+
|
3
|
+
require 'sinatra/base'
|
2
4
|
require 'sinatra/param'
|
3
5
|
|
4
6
|
class Helios::Backend::InAppPurchase < Sinatra::Base
|
5
7
|
helpers Sinatra::Param
|
6
8
|
|
7
|
-
def initialize(app, options = {})
|
9
|
+
def initialize(app, options = {}, &block)
|
8
10
|
super(Rack::InAppPurchase.new)
|
9
11
|
end
|
10
|
-
|
12
|
+
|
11
13
|
before do
|
12
14
|
content_type :json
|
13
15
|
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'rack/newsstand'
|
2
|
+
|
3
|
+
require 'sinatra/base'
|
4
|
+
require 'sinatra/param'
|
5
|
+
|
6
|
+
require 'fog'
|
7
|
+
|
8
|
+
class Helios::Backend::Newsstand < Sinatra::Base
|
9
|
+
helpers Sinatra::Param
|
10
|
+
|
11
|
+
def initialize(app, options = {}, &block)
|
12
|
+
super(Rack::Newsstand.new)
|
13
|
+
|
14
|
+
@storage = Fog::Storage.new(options[:storage]) if options[:storage]
|
15
|
+
end
|
16
|
+
|
17
|
+
before do
|
18
|
+
content_type :json
|
19
|
+
end
|
20
|
+
|
21
|
+
get '/issues/?' do
|
22
|
+
pass unless request.accept? 'application/json'
|
23
|
+
|
24
|
+
param :q, String
|
25
|
+
|
26
|
+
issues = Rack::Newsstand::Issue.dataset
|
27
|
+
issues = issues.filter("tsv @@ to_tsquery('english', ?)", "#{params[:q]}:*") if params[:q] and not params[:q].empty?
|
28
|
+
|
29
|
+
if params[:page] or params[:per_page]
|
30
|
+
param :page, Integer, default: 1, min: 1
|
31
|
+
param :per_page, Integer, default: 100, in: (1..100)
|
32
|
+
|
33
|
+
{
|
34
|
+
issues: issues.limit(params[:per_page], (params[:page] - 1) * params[:per_page]).naked.all,
|
35
|
+
page: params[:page],
|
36
|
+
total: issues.count
|
37
|
+
}.to_json
|
38
|
+
else
|
39
|
+
param :limit, Integer, default: 100, in: (1..100)
|
40
|
+
param :offset, Integer, default: 0, min: 0
|
41
|
+
|
42
|
+
{
|
43
|
+
issues: issues.limit(params[:limit], params[:offset]).naked.all
|
44
|
+
}.to_json
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
head '/issues/new?' do
|
49
|
+
status 503 and return unless @storage
|
50
|
+
|
51
|
+
status 204
|
52
|
+
end
|
53
|
+
|
54
|
+
post '/issues/?' do
|
55
|
+
status 503 and return unless @storage
|
56
|
+
|
57
|
+
param :name, String, empty: false
|
58
|
+
param :summary, String
|
59
|
+
|
60
|
+
issue = Rack::Newsstand::Issue.new(params)
|
61
|
+
|
62
|
+
if issue.valid?
|
63
|
+
directory = @storage.directories.create(key: "newsstand-issue-#{issue.name}-#{Time.now.to_i}", public: true)
|
64
|
+
|
65
|
+
covers, assets = {}, []
|
66
|
+
[:covers, :assets].each do |attribute|
|
67
|
+
(params[attribute] || []).each do |f|
|
68
|
+
file = directory.files.create(
|
69
|
+
key: File.basename(f[:filename]),
|
70
|
+
body: File.open(f[:tempfile]),
|
71
|
+
public: true
|
72
|
+
)
|
73
|
+
|
74
|
+
case attribute
|
75
|
+
when :covers
|
76
|
+
covers["SOURCE"] = file.public_url
|
77
|
+
when :assets
|
78
|
+
assets << file.public_url
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
issue.set(cover_urls: covers, asset_urls: assets)
|
84
|
+
|
85
|
+
if issue.save
|
86
|
+
status 201
|
87
|
+
issue.to_json
|
88
|
+
else
|
89
|
+
status 400
|
90
|
+
{errors: issue.errors}.to_json
|
91
|
+
end
|
92
|
+
else
|
93
|
+
status 400
|
94
|
+
{errors: issue.errors}.to_json
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|