flack 0.9.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 83938d22a1da3371d405bc6f6f9ad5458d2e44ac21616b99df1d3f1058ffbc40
4
+ data.tar.gz: 5c844ae9c4eeca795a70cbcacfd616e40217b120ca75ae6d8368e343bb87746c
5
+ SHA512:
6
+ metadata.gz: 43ca7e422779cc153db5c11db80a7048a9f526de6f2382e88b67a1b3fb12418f9a4a3e87e72b948bb685bd22e18ae8bb3d5d549dd24d00d840ce6b3f16ac5a17
7
+ data.tar.gz: fdca36864febf3ac369363de3fbe1b1687efbeb850f84b5ba3131d7af66d710d4e61d163a33c18c3b4923314c8eb3f7ddad3992e169de085aec80b476ac3d2c2
data/CHANGELOG.md CHANGED
@@ -2,6 +2,44 @@
2
2
  # flack CHANGELOG.md
3
3
 
4
4
 
5
+ ## flack 1.2.0 released 2021-03-29
6
+
7
+ - Simplify links
8
+ - Remove dependency on HttpClient gem
9
+ - Introduce DELETE /executions/:exid
10
+ - Ensure METHS order, stabilize across Ruby versions
11
+
12
+
13
+ ## flack 1.0.0 released 2020-11-22
14
+
15
+ - Leave Sequel dependency to flor
16
+
17
+
18
+ ## flack 0.16.1 released 2019-02-05
19
+
20
+ - Depend on Sequel 5 (Sequel 4 and 5 seem OK)
21
+ - GET /executions/:domain
22
+ - GET /executions/:domain*
23
+ - GET /executions/:domain.*
24
+ - GET /messages/:point
25
+ - GET /messages/:exid/:point
26
+ - GET /messages/:exid
27
+ - GET /messages/:id
28
+ - GET /executions/:exid
29
+ - GET /executions/:id
30
+
31
+
32
+ ## flack 0.10.0 released 2017-03-03
33
+
34
+ ## flack 0.10.0 released 2017-03-03
35
+
36
+ - Flack::App#shutdown (@unit.shutdown)
37
+
38
+
39
+ ## flack 0.9.1.1 released 2017-01-31
40
+
41
+ - Fix relaxed dependency on Flor
42
+
5
43
  ## flack 0.9.1 released 2017-01-31
6
44
 
7
45
  - Relax dependency on Flor
data/Makefile CHANGED
@@ -6,6 +6,9 @@ NAME = \
6
6
  VERSION = \
7
7
  $(shell ruby -e "s = eval(File.read(Dir['*.gemspec'][0])); puts s.version")
8
8
 
9
+ PORT = 7007
10
+ PID_FILE = tmp/$(NAME).pid
11
+
9
12
  count_lines:
10
13
  find lib -name "*.rb" | xargs cat | ruby -e "p STDIN.readlines.count { |l| l = l.strip; l[0, 1] != '#' && l != '' }"
11
14
  cl: count_lines
@@ -24,7 +27,7 @@ build: gemspec_validate
24
27
  mv $(NAME)-$(VERSION).gem pkg/
25
28
 
26
29
  push: build
27
- gem push pkg/$(NAME)-$(VERSION).gem
30
+ gem push --otp "$(OTP)" pkg/$(NAME)-$(VERSION).gem
28
31
 
29
32
 
30
33
  ## flor tasks
@@ -41,11 +44,35 @@ migrate:
41
44
  ## flack tasks
42
45
 
43
46
  serve:
44
- bundle exec rackup -p 7007
47
+ bundle exec rackup -p $(PORT)
45
48
  s: serve
46
49
 
47
50
  curl:
48
- curl -s http://127.0.0.1:7007/ | \
51
+ curl -s http://127.0.0.1:$(PORT)/ | \
49
52
  $(RUBY) -e "require 'json'; puts JSON.pretty_generate(JSON.load(STDIN.read))"
50
53
  c: curl
51
54
 
55
+ start:
56
+ @if [ ! -f $(PID_FILE) ]; then \
57
+ bundle exec rackup -p $(PORT) -P $(PID_FILE) -D; \
58
+ sleep 1; \
59
+ echo "listening on $(PORT), pid `cat $(PID_FILE)`"; \
60
+ else \
61
+ echo "already running at `cat $(PID_FILE)`"; \
62
+ fi
63
+
64
+ stop:
65
+ @if [ -f $(PID_FILE) ]; then \
66
+ echo "stopping flack pid `cat $(PID_FILE)`"; \
67
+ kill `cat $(PID_FILE)`; \
68
+ fi
69
+
70
+ restart:
71
+ @if [ -f $(PID_FILE) ]; then make -s stop; fi; make -s start
72
+
73
+ # Calls / and lists the links available
74
+ #
75
+ links:
76
+ bundle exec ruby -Ilib -r 'flack' \
77
+ -e "app = Flack::App.new('envs/test/', start: false); pp JSON.parse(app.call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/', 'REQUEST_PATH' => '/', 'SCRIPT_NAME' => '')[2].first)"
78
+
data/README.md CHANGED
@@ -1,14 +1,27 @@
1
1
 
2
2
  # flack
3
3
 
4
- [![Build Status](https://secure.travis-ci.org/floraison/flack.svg)](http://travis-ci.org/floraison/flack)
4
+ [![tests](https://github.com/floraison/flack/workflows/test/badge.svg)](https://github.com/floraison/flack/actions)
5
5
  [![Gem Version](https://badge.fury.io/rb/flack.svg)](http://badge.fury.io/rb/flack)
6
6
 
7
7
  Flack is a Rack app for the [flor](https://github.com/floraison/flor) workflow engine.
8
8
 
9
+
10
+ ## test ride
11
+
12
+ ```sh
13
+ make migrate
14
+ make start
15
+ open http://localhost:7007/
16
+ ```
17
+
18
+ Warning: this serves an API, not some fancy web interface.
19
+
20
+
9
21
  ## api
10
22
 
11
- Based on HAL ([spec](http://stateless.co/hal_specification.html) and [draft](https://tools.ietf.org/html/draft-kelly-json-hal-08)).
23
+ Based on HAL ([spec](http://stateless.co/hal_specification.html) and [draft](https://tools.ietf.org/html/draft-kelly-json-hal-08)), [URI Template](https://tools.ietf.org/html/rfc6570), and [CURIE](https://www.w3.org/TR/curie/).
24
+
12
25
 
13
26
  ## license
14
27
 
data/flack.gemspec CHANGED
@@ -10,8 +10,7 @@ Gem::Specification.new do |s|
10
10
  s.platform = Gem::Platform::RUBY
11
11
  s.authors = [ 'John Mettraux' ]
12
12
  s.email = [ 'jmettraux@gmail.com' ]
13
- s.homepage = 'http://github.com/floraison'
14
- #s.rubyforge_project = 'flor'
13
+ s.homepage = 'https://github.com/floraison/flack'
15
14
  s.license = 'MIT'
16
15
  s.summary = 'a web front-end to the flor workflow engine'
17
16
 
@@ -21,16 +20,19 @@ A web front-end to the flor workflow engine
21
20
 
22
21
  #s.files = `git ls-files`.split("\n")
23
22
  s.files = Dir[
23
+ 'README.{md,txt}',
24
+ 'CHANGELOG.{md,txt}', 'CREDITS.{md,txt}', 'LICENSE.{md,txt}',
24
25
  'Makefile',
25
26
  'lib/**/*.rb', #'spec/**/*.rb', 'test/**/*.rb',
26
- '*.gemspec', '*.txt', '*.rdoc', '*.md'
27
+ "#{s.name}.gemspec",
27
28
  ]
28
29
 
29
- v = s.version.to_s
30
- s.add_runtime_dependency 'flor', v[0..v.rindex('.') - 1]
30
+ #flor_version = s.version.to_s.split('.').take(2).join('.')
31
+ #s.add_runtime_dependency 'flor', "~> #{flor_version}"
32
+ s.add_runtime_dependency 'flor'
31
33
 
32
- s.add_runtime_dependency 'rack', '~> 1.6'
33
- s.add_runtime_dependency 'sequel', '~> 4'
34
+ s.add_runtime_dependency 'rack', '>= 1.6', '< 3.0'
35
+ #s.add_runtime_dependency 'httpclient', '~> 2.8'
34
36
 
35
37
  s.add_development_dependency 'rspec', '~> 3'
36
38
 
data/lib/flack.rb CHANGED
@@ -1,27 +1,6 @@
1
- #--
2
- # Copyright (c) 2016-2017, John Mettraux, jmettraux+flor@gmail.com
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- # Made in Japan.
23
- #++
1
+ # frozen_string_literal: true
24
2
 
3
+ require 'cgi'
25
4
  require 'rack'
26
5
 
27
6
  require 'flor/unit'
@@ -29,7 +8,7 @@ require 'flor/unit'
29
8
 
30
9
  module Flack
31
10
 
32
- VERSION = '0.9.1'
11
+ VERSION = '1.2.0'
33
12
  end
34
13
 
35
14
  require 'flack/app'
data/lib/flack/app.rb CHANGED
@@ -1,26 +1,4 @@
1
- #--
2
- # Copyright (c) 2016-2017, John Mettraux, jmettraux+flor@gmail.com
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- # Made in Japan.
23
- #++
1
+ # frozen_string_literal: true
24
2
 
25
3
  require 'flack/app/helpers'
26
4
  #
@@ -28,6 +6,8 @@ require 'flack/app/index'
28
6
  require 'flack/app/static'
29
7
  require 'flack/app/message'
30
8
  require 'flack/app/executions'
9
+ require 'flack/app/messages'
10
+ require 'flack/app/pointers'
31
11
 
32
12
 
33
13
  class Flack::App
@@ -52,6 +32,11 @@ class Flack::App
52
32
  @unit
53
33
  end
54
34
 
35
+ def shutdown
36
+
37
+ @unit.shutdown
38
+ end
39
+
55
40
  def self.unit
56
41
  @unit
57
42
  end
@@ -76,7 +61,7 @@ class Flack::App
76
61
  match = true
77
62
  args = []
78
63
 
79
- for i in 0..flack_path_info.length - 1
64
+ for i in 0..(flack_path_info.length - 1)
80
65
 
81
66
  break unless match
82
67
 
@@ -90,8 +75,10 @@ class Flack::App
90
75
  args << pi.to_i
91
76
  elsif mi == 's'
92
77
  args << pi
78
+ elsif mi.is_a?(Regexp)
79
+ match = pi.match(mi)
93
80
  else
94
- match = pi == mi
81
+ match = (pi == mi)
95
82
  end
96
83
  end
97
84
 
@@ -114,7 +101,14 @@ class Flack::App
114
101
  .collect(&:to_s)
115
102
  .select { |m| m.match(/\A(get|head|put|post|delete)_.+\z/) }
116
103
  .select { |m| instance_method(m).arity == 1 }
117
- .collect { |m| s = m.split('_'); [ m, s.shift.upcase, s ] }
104
+ .sort
105
+ .collect { |m|
106
+ s = m.split('_')
107
+ if s.length == 3 && s[2] == 'suffix'
108
+ [ m, s.shift.upcase, [ /\.#{s[0]}\z/ ] ]
109
+ else
110
+ [ m, s.shift.upcase, s ]
111
+ end }
118
112
  .collect(&:freeze).freeze
119
113
  end
120
114
 
@@ -1,42 +1,127 @@
1
- #--
2
- # Copyright (c) 2016-2017, John Mettraux, jmettraux+flor@gmail.com
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- # Made in Japan.
23
- #++
24
-
1
+ # frozen_string_literal: true
25
2
 
26
3
  # /executions/*
27
4
  #
28
5
  class Flack::App
29
6
 
7
+ # GET /executions
8
+ #
30
9
  def get_executions(env)
31
10
 
32
11
  # TODO implement paging
33
- respond(env, @unit.executions.all)
12
+ env['flack.rel'] = 'flack:executions'
13
+
14
+ qs = CGI.parse(env['QUERY_STRING'] || '')
15
+ statuses = qs['status']
16
+ statuses = nil if statuses == []
17
+
18
+ q = @unit.executions
19
+ q = q.where(status: statuses) if statuses
20
+
21
+ respond(env, q.all)
34
22
  end
35
23
 
24
+ # GET /executions/<id>
25
+ #
36
26
  def get_executions_i(env)
37
27
 
38
- # TODO
39
- debug_respond(env)
28
+ env['flack.rel'] = 'flack:executions/id'
29
+
30
+ if exe = @unit.executions[env['flack.args'][0]]
31
+ respond(env, exe)
32
+ else
33
+ respond_not_found(env)
34
+ end
35
+ end
36
+
37
+ # GET /executions/<exid>
38
+ # GET /executions/<domain>
39
+ # GET /executions/<domain>*
40
+ # GET /executions/<domain>.*
41
+ #
42
+ def get_executions_s(env)
43
+
44
+ arg = env['flack.args'][0]
45
+
46
+ if arg.count('-') == 0
47
+ get_executions_by_domain(env, arg)
48
+ else
49
+ get_executions_by_exid(env, arg)
50
+ end
51
+ end
52
+
53
+ # DELETE /executions/<exid>
54
+ #
55
+ def delete_executions_s(env)
56
+
57
+ exid = env['flack.args'][0]
58
+
59
+ return respond_not_found(env) \
60
+ unless @unit.executions.where(exid: exid).count > 0
61
+
62
+ r = { exid: exid, counts: {} }
63
+ cs = r[:counts]
64
+
65
+ @unit.storage.db.transaction do
66
+
67
+ cs[:messages] = @unit.messages.where(exid: exid).count
68
+ cs[:executions] = @unit.executions.where(exid: exid).count
69
+ cs[:pointers] = @unit.pointers.where(exid: exid).count
70
+ cs[:timers] = @unit.timers.where(exid: exid).count
71
+ cs[:traps] = @unit.traps.where(exid: exid).count
72
+ #
73
+ # not sure if the DB adapter returns the DELETE count,
74
+ # so counting first
75
+
76
+ @unit.messages.where(exid: exid).delete
77
+ @unit.executions.where(exid: exid).delete
78
+ @unit.pointers.where(exid: exid).delete
79
+ @unit.timers.where(exid: exid).delete
80
+ @unit.traps.where(exid: exid).delete
81
+ end
82
+
83
+ respond(env, r)
84
+ end
85
+
86
+ protected
87
+
88
+ def get_executions_by_exid(env, exid)
89
+
90
+ env['flack.rel'] = 'flack:executions/exid'
91
+
92
+ if exe = @unit.executions[exid: exid]
93
+ respond(env, exe)
94
+ else
95
+ respond_not_found(env)
96
+ end
97
+ end
98
+
99
+ def get_executions_by_domain(env, dom)
100
+
101
+ qs = CGI.parse(env['QUERY_STRING'] || '')
102
+ statuses = qs['status']
103
+ statuses = nil if statuses == []
104
+
105
+ q = @unit.executions
106
+
107
+ if m = dom.match(/\A([^*]+)\*+\z/)
108
+ if m[1][-1, 1] == '.'
109
+ env['flack.rel'] = 'flack:executions/domain-dot-star'
110
+ q = q.where(Sequel.like(:domain, "#{m[1]}%"))
111
+ else
112
+ env['flack.rel'] = 'flack:executions/domain-star'
113
+ q = q.where(
114
+ Sequel[{ domain: m[1] }] |
115
+ Sequel.like(:domain, "#{m[1]}.%"))
116
+ end
117
+ else
118
+ env['flack.rel'] = 'flack:executions/domain'
119
+ q = q.where(domain: dom)
120
+ end
121
+
122
+ q = q.where(status: statuses) if statuses
123
+
124
+ respond(env, q.all)
40
125
  end
41
126
  end
42
127
 
@@ -1,27 +1,4 @@
1
- #--
2
- # Copyright (c) 2016-2017, John Mettraux, jmettraux+flor@gmail.com
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- # Made in Japan.
23
- #++
24
-
1
+ # frozen_string_literal: true
25
2
 
26
3
  # helpers
27
4
  #
@@ -38,7 +15,7 @@ class Flack::App
38
15
 
39
16
  o.is_a?(Array) &&
40
17
  o.length == 3 &&
41
- o[0].is_a?(Fixnum) &&
18
+ o[0].is_a?(Integer) &&
42
19
  o[1].is_a?(Hash) &&
43
20
  o[2].is_a?(Array)
44
21
  end
@@ -98,7 +75,13 @@ class Flack::App
98
75
  def serialize_array(env, data, opts)
99
76
 
100
77
  { '_links' => links(env),
101
- '_embedded' => data.collect { |e| serialize(env, e, opts) } }
78
+ '_embedded' => {
79
+ key(env) => data.collect { |e| serialize(env, e, opts) } } }
80
+ end
81
+
82
+ def key(env)
83
+
84
+ env['flack.rel'] || 'flack:unspecified-rel'
102
85
  end
103
86
 
104
87
  def determine_root_uri(env)
@@ -122,9 +105,23 @@ class Flack::App
122
105
 
123
106
  def link(env, h, type)
124
107
 
125
- h["flack:#{type}"] = { href: rel(env, "/#{type}") }
108
+ l = { href: rel(env, "/#{type}") }
109
+ l[:templated] = true if type.index('{')
110
+
111
+ rel_right_part = type
112
+ .gsub(/\{\?[^}]*\}/, '')
113
+ .gsub(/[{}]/, '')
114
+ .gsub(/\./, '-dot')
115
+ .gsub(/\*/, '-star')
116
+
117
+ h["flack:#{rel_right_part}"] = l
126
118
  end
127
119
 
120
+ CURIES = [ {
121
+ name: 'flack',
122
+ href: 'https://github.com/floraison/flack/blob/master/doc/rels.md#{rel}',
123
+ templated: true } ].freeze
124
+
128
125
  def links(env)
129
126
 
130
127
  h = {}
@@ -134,12 +131,26 @@ class Flack::App
134
131
  m = env['REQUEST_METHOD']
135
132
  h['self'][:method] = m unless %w[ GET HEAD ].include?(m)
136
133
 
137
- h['curies'] = [{
138
- name: 'flack',
139
- href: 'https://github.com/floraison/flack/blob/master/doc/rels.md#{rel}',
140
- templated: true }]
134
+ h['curies'] = CURIES
135
+
136
+ link(env, h, 'executions{?status}')
137
+ link(env, h, 'executions/{domain}{?status}')
138
+ link(env, h, 'executions/{domain}*{?status}')
139
+ link(env, h, 'executions/{domain}.*{?status}')
140
+ link(env, h, 'executions/{exid}')
141
+ link(env, h, 'executions/{id}')
141
142
 
142
- link(env, h, :executions)
143
+ link(env, h, 'messages')
144
+ link(env, h, 'messages/{point}')
145
+ link(env, h, 'messages/{exid}/{point}')
146
+ link(env, h, 'messages/{exid}')
147
+ link(env, h, 'messages/{id}')
148
+
149
+ link(env, h, 'pointers{?type}')
150
+ link(env, h, 'pointers/{exid}{?type}')
151
+ link(env, h, 'pointers/{domain}{?type}')
152
+ link(env, h, 'pointers/{domain}*{?type}')
153
+ link(env, h, 'pointers/{domain}.*{?type}')
143
154
 
144
155
  h
145
156
  end
@@ -148,11 +159,19 @@ class Flack::App
148
159
 
149
160
  h = {}
150
161
 
162
+ h['curies'] = CURIES
163
+
151
164
  h['flack:forms/message'] = {
152
165
  action: rel(env, '/message'),
153
166
  method: 'POST',
154
167
  _inputs: { 'flack:forms/message-content' => { type: 'json' } } }
155
168
 
169
+ h['flack:forms/execution-deletion'] = {
170
+ action: rel(env, '/executions/{exid}'),
171
+ method: 'DELETE',
172
+ _inputs: {},
173
+ templated: true }
174
+
156
175
  h
157
176
  end
158
177
 
@@ -1,27 +1,4 @@
1
- #--
2
- # Copyright (c) 2016-2017, John Mettraux, jmettraux+flor@gmail.com
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- # Made in Japan.
23
- #++
24
-
1
+ # frozen_string_literal: true
25
2
 
26
3
  # /
27
4
  #
@@ -1,27 +1,4 @@
1
- #--
2
- # Copyright (c) 2016-2017, John Mettraux, jmettraux+flor@gmail.com
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- # Made in Japan.
23
- #++
24
-
1
+ # frozen_string_literal: true
25
2
 
26
3
  # /message
27
4
  #
@@ -30,14 +7,13 @@ class Flack::App
30
7
  def post_message(env)
31
8
 
32
9
  msg = JSON.load(env['rack.input'].read)
33
- #pp msg
34
10
 
35
11
  pt = msg['point']
36
12
 
37
13
  return respond_bad_request(env, 'missing msg point') \
38
14
  unless pt
39
15
  return respond_bad_request(env, "bad msg point #{pt.inspect}") \
40
- unless %w[ launch cancel ].include?(pt)
16
+ unless %w[ launch cancel reply ].include?(pt)
41
17
 
42
18
  r = self.send("queue_#{pt}", env, msg, { point: pt })
43
19
 
@@ -48,16 +24,18 @@ class Flack::App
48
24
 
49
25
  def queue_launch(env, msg, ret)
50
26
 
51
- dom = msg['domain']
27
+ dom = msg['domain'] || 'domain0'
52
28
  src = msg['tree'] || msg['name']
29
+ vars = msg['vars'] || {}
30
+ fields = msg['fields'] || {}
53
31
 
54
- return respond_bad_request(env, 'missing domain') \
55
- unless dom
56
32
  return respond_bad_request(env, 'missing "tree" or "name" in launch msg') \
57
33
  unless src
58
34
 
59
35
  opts = {}
60
36
  opts[:domain] = dom
37
+ opts[:vars] = vars
38
+ opts[:fields] = fields
61
39
 
62
40
  r = @unit.launch(src, opts)
63
41
 
@@ -86,7 +64,35 @@ class Flack::App
86
64
  return respond_not_found(env, 'missing execution node') \
87
65
  unless exe.nodes[nid]
88
66
 
89
- ret['xxx'] = @unit.queue({ 'point' => 'cancel', 'exid' => exid, 'nid' => nid })
67
+ ret['xxx'] = @unit.queue({ 'point' => 'cancel', 'exid' => exid, 'nid' => nid }) # FIXME change me
68
+
69
+ ret['_status'] = 202
70
+ ret['_location'] = rel(env, '/executions/' + exid)
71
+ ret['_links'] = { 'flack:execution' => { 'href' => ret['_location'] } }
72
+
73
+ ret
74
+ end
75
+
76
+ def queue_reply(env, msg, ret)
77
+
78
+ exid = msg['exid']
79
+ nid = msg['nid']
80
+ payload = msg['payload'] || {}
81
+
82
+ return respond_bad_request(env, 'missing exid') \
83
+ unless exid
84
+
85
+ return respond_bad_request(env, 'missing nid') \
86
+ unless nid
87
+
88
+ exe = @unit.executions[exid: exid]
89
+
90
+ return respond_not_found(env, 'missing execution') \
91
+ unless exe
92
+ return respond_not_found(env, 'missing execution node') \
93
+ unless exe.nodes[nid]
94
+
95
+ ret['xxx'] = @unit.queue({ 'point' => 'return', 'exid' => exid, 'nid' => nid, 'payload' => payload}) # FIXME change me
90
96
 
91
97
  ret['_status'] = 202
92
98
  ret['_location'] = rel(env, '/executions/' + exid)
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ # /messages/*
4
+ #
5
+ class Flack::App
6
+
7
+ # GET /messages
8
+ def get_messages(env)
9
+
10
+ # TODO implement paging
11
+ env['flack.rel'] = 'flack:messages'
12
+
13
+ respond(env, @unit.messages.all)
14
+ end
15
+
16
+ # GET /messages/<id>
17
+ def get_messages_i(env)
18
+
19
+ env['flack.rel'] = 'flack:messages'
20
+
21
+ if exe = @unit.messages[env['flack.args'][0]]
22
+ respond(env, exe)
23
+ else
24
+ respond_not_found(env)
25
+ end
26
+ end
27
+
28
+ # GET /messages/<exid>
29
+ def get_messages_s(env)
30
+
31
+ # TODO implement paging
32
+ arg = env['flack.args'][0]
33
+
34
+ if Flor.point?(arg)
35
+ get_messages_by_point(env, arg)
36
+ else
37
+ get_messages_by_exid(env, arg)
38
+ end
39
+ end
40
+
41
+ # GET /messages/<exid>/<point>
42
+ def get_messages_s_s(env)
43
+
44
+ env['flack.rel'] = 'flack:messages/exid/point'
45
+
46
+ exid, point = env['flack.args']
47
+
48
+ respond(
49
+ env,
50
+ @unit.messages.where(exid: exid, point: point).all)
51
+ end
52
+
53
+ protected
54
+
55
+ def get_messages_by_exid(env, exid)
56
+
57
+ env['flack.rel'] = 'flack:messages/exid'
58
+
59
+ respond(env, @unit.messages.where(exid: exid).all)
60
+ end
61
+
62
+ def get_messages_by_point(env, point)
63
+
64
+ env['flack.rel'] = 'flack:messages/point'
65
+
66
+ respond(env, @unit.messages.where(point: point).all)
67
+ end
68
+ end
69
+
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ # /pointers/*
4
+ #
5
+ class Flack::App
6
+
7
+ # GET /pointers
8
+ #
9
+ def get_pointers(env)
10
+
11
+ # TODO implement paging
12
+ env['flack.rel'] = 'flack:pointers'
13
+
14
+ qs = CGI.parse(env['QUERY_STRING'] || '')
15
+ types = qs['types'].collect { |e| e.split(',') }.flatten
16
+ types = nil if types == []
17
+
18
+ q = @unit.pointers
19
+ q = q.where(type: types) if types
20
+
21
+ respond(env, q.all)
22
+ end
23
+
24
+ # GET /pointers/<exid>
25
+ # GET /pointers/<domain>
26
+ # GET /pointers/<domain>*
27
+ # GET /pointers/<domain>.*
28
+ #
29
+ def get_pointers_s(env)
30
+
31
+ arg = env['flack.args'][0]
32
+
33
+ qs = CGI.parse(env['QUERY_STRING'] || '')
34
+
35
+ types = qs['types'].collect { |e| e.split(',') }.flatten
36
+ types = nil if types == []
37
+
38
+ if arg.count('-') == 0
39
+ get_pointers_by_domain(env, arg, types)
40
+ else
41
+ get_pointers_by_exid(env, arg, types)
42
+ end
43
+ end
44
+
45
+ protected
46
+
47
+ def get_pointers_by_exid(env, exid, types)
48
+
49
+ env['flack.rel'] = 'flack:pointers/exid'
50
+
51
+ q = @unit.pointers.where(exid: exid)
52
+ q = q.where(type: types) if types
53
+
54
+ respond(env, q.all)
55
+ end
56
+
57
+ def get_pointers_by_domain(env, dom, types)
58
+
59
+ q = @unit.pointers
60
+ q = q.where(type: types) if types
61
+
62
+ if m = dom.match(/\A([^*]+)\*+\z/)
63
+ if m[1][-1, 1] == '.'
64
+ env['flack.rel'] = 'flack:pointers/domain-dot-star'
65
+ q = q.where(Sequel.like(:domain, "#{m[1]}%"))
66
+ else
67
+ env['flack.rel'] = 'flack:pointers/domain-star'
68
+ q = q.where(
69
+ Sequel[{ domain: m[1] }] |
70
+ Sequel.like(:domain, "#{m[1]}.%"))
71
+ end
72
+ else
73
+ env['flack.rel'] = 'flack:pointers/domain'
74
+ q = q.where(domain: dom)
75
+ end
76
+
77
+ respond(env, q.all)
78
+ end
79
+ end
80
+
@@ -1,40 +1,23 @@
1
- #--
2
- # Copyright (c) 2016-2017, John Mettraux, jmettraux+flor@gmail.com
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- # Made in Japan.
23
- #++
24
-
1
+ # frozen_string_literal: true
25
2
 
26
- # /static/+
3
+ # /*.html
4
+ # /*.css
5
+ # /*.js
27
6
  #
28
7
  class Flack::App
29
8
 
30
- RACK_FILE = Rack::File.new(
9
+ STATIC_FILE = Rack::File.new(
31
10
  File.absolute_path(
32
11
  File.join(
33
- File.dirname(__FILE__), '..')))
12
+ File.dirname(__FILE__), '..', 'static')))
34
13
 
35
- def get_static_plus(env)
14
+ def serve_file(env)
36
15
 
37
- RACK_FILE.call(env)
16
+ STATIC_FILE.call(env)
38
17
  end
18
+
19
+ alias get_html_suffix serve_file
20
+ alias get_css_suffix serve_file
21
+ alias get_js_suffix serve_file
39
22
  end
40
23
 
metadata CHANGED
@@ -1,78 +1,61 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
5
- prerelease:
4
+ version: 1.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - John Mettraux
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2017-01-31 00:00:00.000000000 Z
11
+ date: 2021-03-29 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: flor
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - '='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
- version: '0.9'
19
+ version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - '='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
- version: '0.9'
26
+ version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rack
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ~>
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
33
  version: '1.6'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '3.0'
38
37
  type: :runtime
39
38
  prerelease: false
40
39
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
40
  requirements:
43
- - - ~>
41
+ - - ">="
44
42
  - !ruby/object:Gem::Version
45
43
  version: '1.6'
46
- - !ruby/object:Gem::Dependency
47
- name: sequel
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
51
- - - ~>
44
+ - - "<"
52
45
  - !ruby/object:Gem::Version
53
- version: '4'
54
- type: :runtime
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ~>
60
- - !ruby/object:Gem::Version
61
- version: '4'
46
+ version: '3.0'
62
47
  - !ruby/object:Gem::Dependency
63
48
  name: rspec
64
49
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
50
  requirements:
67
- - - ~>
51
+ - - "~>"
68
52
  - !ruby/object:Gem::Version
69
53
  version: '3'
70
54
  type: :development
71
55
  prerelease: false
72
56
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
57
  requirements:
75
- - - ~>
58
+ - - "~>"
76
59
  - !ruby/object:Gem::Version
77
60
  version: '3'
78
61
  description: A web front-end to the flor workflow engine
@@ -82,44 +65,41 @@ executables: []
82
65
  extensions: []
83
66
  extra_rdoc_files: []
84
67
  files:
68
+ - CHANGELOG.md
69
+ - LICENSE.txt
85
70
  - Makefile
71
+ - README.md
72
+ - flack.gemspec
73
+ - lib/flack.rb
74
+ - lib/flack/app.rb
86
75
  - lib/flack/app/executions.rb
87
76
  - lib/flack/app/helpers.rb
88
77
  - lib/flack/app/index.rb
89
78
  - lib/flack/app/message.rb
79
+ - lib/flack/app/messages.rb
80
+ - lib/flack/app/pointers.rb
90
81
  - lib/flack/app/static.rb
91
- - lib/flack/app.rb
92
- - lib/flack.rb
93
- - flack.gemspec
94
- - env.txt
95
- - env2.txt
96
- - LICENSE.txt
97
- - t.txt
98
- - CHANGELOG.md
99
- - README.md
100
- homepage: http://github.com/floraison
82
+ homepage: https://github.com/floraison/flack
101
83
  licenses:
102
84
  - MIT
85
+ metadata: {}
103
86
  post_install_message:
104
87
  rdoc_options: []
105
88
  require_paths:
106
89
  - lib
107
90
  required_ruby_version: !ruby/object:Gem::Requirement
108
- none: false
109
91
  requirements:
110
- - - ! '>='
92
+ - - ">="
111
93
  - !ruby/object:Gem::Version
112
94
  version: '0'
113
95
  required_rubygems_version: !ruby/object:Gem::Requirement
114
- none: false
115
96
  requirements:
116
- - - ! '>='
97
+ - - ">="
117
98
  - !ruby/object:Gem::Version
118
99
  version: '0'
119
100
  requirements: []
120
- rubyforge_project:
121
- rubygems_version: 1.8.23.2
101
+ rubygems_version: 3.0.3
122
102
  signing_key:
123
- specification_version: 3
103
+ specification_version: 4
124
104
  summary: a web front-end to the flor workflow engine
125
105
  test_files: []
data/env.txt DELETED
@@ -1,38 +0,0 @@
1
-
2
- GATEWAY_INTERFACE: "CGI/1.1"
3
- PATH_INFO: "/debug/77"
4
- QUERY_STRING: "a=b&c=d"
5
- REMOTE_ADDR: "::1"
6
- REMOTE_HOST: "localhost"
7
- REQUEST_METHOD: "GET"
8
- REQUEST_URI: "http://localhost:7007/debug/77?a=b&c=d"
9
- SCRIPT_NAME: ""
10
- SERVER_NAME: "localhost"
11
- SERVER_PORT: "7007"
12
- SERVER_PROTOCOL: "HTTP/1.1"
13
- SERVER_SOFTWARE: "WEBrick/1.3.1 (Ruby/1.9.3/2014-05-14)"
14
- HTTP_HOST: "localhost:7007"
15
- HTTP_CONNECTION: "keep-alive"
16
- HTTP_UPGRADE_INSECURE_REQUESTS: "1"
17
- HTTP_USER_AGENT: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36"
18
- HTTP_ACCEPT: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
19
- HTTP_ACCEPT_ENCODING: "gzip, deflate, sdch"
20
- HTTP_ACCEPT_LANGUAGE: "ja,en-US;q=0.8,en;q=0.6,fr;q=0.4,de;q=0.2,it;q=0.2,zh-TW;q=0.2,zh;q=0.2"
21
- HTTP_COOKIE: "sg_dev=2ebdd63d694602c96834d5a261fc471732a2a44c37f40d6446c5cab1b724a263"
22
- rack.version: [1, 3]
23
- rack.input: #<Rack::Lint::InputWrapper:0x007fb27b230048 @input=#<StringIO:0x007fb27b238b30>>
24
- rack.errors: #<Rack::Lint::ErrorWrapper:0x007fb27b22fee0 @error=#<IO:<STDERR>>>
25
- rack.multithread: true
26
- rack.multiprocess: false
27
- rack.run_once: false
28
- rack.url_scheme: "http"
29
- rack.hijack?: true
30
- rack.hijack: #<Proc:0x007fb27b230ae8@/Users/jmettraux/.gem/ruby/1.9.3/gems/rack-1.6.4/lib/rack/lint.rb:525>
31
- rack.hijack_io: nil
32
- HTTP_VERSION: "HTTP/1.1"
33
- REQUEST_PATH: "/debug/77"
34
- rack.tempfiles: []
35
- flack.path_info: ["debug", "77"]
36
- flack.args: [77]
37
- flack.query_string: {"a"=>"b", "c"=>"d"}
38
-
data/env2.txt DELETED
@@ -1,33 +0,0 @@
1
- GATEWAY_INTERFACE:CGI/1.1
2
- PATH_INFO:/debug
3
- QUERY_STRING:
4
- REMOTE_ADDR:127.0.0.1
5
- REMOTE_HOST:localhost
6
- REQUEST_METHOD:GET
7
- REQUEST_URI:http://127.0.0.1:7007/flack/debug
8
- SCRIPT_NAME:/flack
9
- SERVER_NAME:127.0.0.1
10
- SERVER_PORT:7007
11
- SERVER_PROTOCOL:HTTP/1.1
12
- SERVER_SOFTWARE:WEBrick/1.3.1 (Ruby/1.9.3/2014-05-14)
13
- HTTP_HOST:127.0.0.1:7007
14
- HTTP_USER_AGENT:curl/7.43.0
15
- HTTP_ACCEPT:*/*
16
- rack.version:[1
17
- 3]
18
- rack.input:#<Rack::Lint::InputWrapper:0x007ff6baa373a8>
19
- rack.errors:#<Rack::Lint::ErrorWrapper:0x007ff6baa37290>
20
- rack.multithread:true
21
- rack.multiprocess:false
22
- rack.run_once:false
23
- rack.url_scheme:http
24
- rack.hijack?:true
25
- rack.hijack:#<Proc:0x007ff6baa38208@/Users/jmettraux/.gem/ruby/1.9.3/gems/rack-1.6.4/lib/rack/lint.rb:525>
26
- rack.hijack_io:null
27
- HTTP_VERSION:HTTP/1.1
28
- REQUEST_PATH:/flack/debug
29
- rack.tempfiles:[]
30
- flack.path_info:[debug]
31
- flack.args:[]
32
- flack.query_string:{}
33
- flack.root_uri:http://127.0.0.1:7007
data/t.txt DELETED
@@ -1,7 +0,0 @@
1
-
2
- https://git.io/viDSd
3
- https://goo.gl/xuOZcu
4
- http://tiny.cc/flack
5
-
6
- http://lambda.io/flack
7
-