flack 0.9.1.1 → 1.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 53ad40ea2e437d87d34f32ddd9239af062bb03aa
4
- data.tar.gz: 262ba6b52d7891724ff81912b0accd9c00e0b4d7
2
+ SHA256:
3
+ metadata.gz: 36dd9d587c7d003cc296db2fc3ac9f7dac0916e267a43904f5ca8be1e25b780e
4
+ data.tar.gz: 1bc04ec7696966e9d197b80c25af1a76309463eabc88222d4777d769f866f9c6
5
5
  SHA512:
6
- metadata.gz: df483e90b692c55a35dcc885f5bb53e258f5a017d97ada4a29bb012dd00fd0acee83075cad989adc25c2aa2459bb2f834b87d6711ed680387b7e3325f7b81eae
7
- data.tar.gz: 8c395360bc1edef076943e04d49576a7447d41596d8d278f6672a63e6347748939bba10c528c2464352ff17a2f34e3e536e7fb44aeb9a1baec07b116b9669186
6
+ metadata.gz: f8f69c70110ed67738d5c0ef95b97d4d0d0612520bbe8bab4c0353018f9bd0476bc48f29644514d3628cd2edb446abacdb38bf5392e2fbf95044a6401c7a3d37
7
+ data.tar.gz: 59784ead309c9df695c416af89087d1fdf5e16d7900c758027da2f771b48337774252ee792e47fac32ba43fce0a86d2600798e155e420aecb357c1a235843bea
data/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
 
2
- # flack CHANGELOG.md
2
+ # CHANGELOG.md
3
+
4
+
5
+ ## flack 1.2.1 released 2021-04-08
6
+
7
+ - Respond with a proper 500 error when necessary (and dump to $stderr)
8
+
9
+
10
+ ## flack 1.2.0 released 2021-03-29
11
+
12
+ - Simplify links
13
+ - Remove dependency on HttpClient gem
14
+ - Introduce DELETE /executions/:exid
15
+ - Ensure METHS order, stabilize across Ruby versions
16
+
17
+
18
+ ## flack 1.0.0 released 2020-11-22
19
+
20
+ - Leave Sequel dependency to flor
21
+
22
+
23
+ ## flack 0.16.1 released 2019-02-05
24
+
25
+ - Depend on Sequel 5 (Sequel 4 and 5 seem OK)
26
+ - GET /executions/:domain
27
+ - GET /executions/:domain*
28
+ - GET /executions/:domain.*
29
+ - GET /messages/:point
30
+ - GET /messages/:exid/:point
31
+ - GET /messages/:exid
32
+ - GET /messages/:id
33
+ - GET /executions/:exid
34
+ - GET /executions/:id
35
+
36
+
37
+ ## flack 0.10.0 released 2017-03-03
38
+
39
+ ## flack 0.10.0 released 2017-03-03
40
+
41
+ - Flack::App#shutdown (@unit.shutdown)
3
42
 
4
43
 
5
44
  ## flack 0.9.1.1 released 2017-01-31
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
- flor_version = s.version.to_s.split('.').take(2).join('.')
30
- s.add_runtime_dependency 'flor', "~> #{flor_version}"
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.1'
11
+ VERSION = '1.2.1'
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
 
@@ -105,6 +92,16 @@ class Flack::App
105
92
  end
106
93
 
107
94
  respond_not_found(env)
95
+
96
+ rescue => err
97
+
98
+ $stderr.puts '=' * 80
99
+ $stderr.puts Time.now.to_s
100
+ $stderr.puts err.inspect
101
+ $stderr.puts err.backtrace
102
+ $stderr.puts ('=' * 79) + '.'
103
+
104
+ respond_internal_server_error(env, err)
108
105
  end
109
106
 
110
107
  def get_debug(env); debug_respond(env); end
@@ -114,7 +111,14 @@ class Flack::App
114
111
  .collect(&:to_s)
115
112
  .select { |m| m.match(/\A(get|head|put|post|delete)_.+\z/) }
116
113
  .select { |m| instance_method(m).arity == 1 }
117
- .collect { |m| s = m.split('_'); [ m, s.shift.upcase, s ] }
114
+ .sort
115
+ .collect { |m|
116
+ s = m.split('_')
117
+ if s.length == 3 && s[2] == 'suffix'
118
+ [ m, s.shift.upcase, [ /\.#{s[0]}\z/ ] ]
119
+ else
120
+ [ m, s.shift.upcase, s ]
121
+ end }
118
122
  .collect(&:freeze).freeze
119
123
  end
120
124
 
@@ -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
 
@@ -165,5 +184,10 @@ class Flack::App
165
184
 
166
185
  respond(env, {}, code: 404, error: error)
167
186
  end
187
+
188
+ def respond_internal_server_error(env, error=nil)
189
+
190
+ respond(env, {}, code: 500, error: error)
191
+ end
168
192
  end
169
193
 
@@ -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,66 +1,58 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1.1
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Mettraux
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-31 00:00:00.000000000 Z
11
+ date: 2021-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
+ name: flor
14
15
  requirement: !ruby/object:Gem::Requirement
15
16
  requirements:
16
- - - "~>"
17
+ - - ">="
17
18
  - !ruby/object:Gem::Version
18
- version: '0.9'
19
- name: flor
20
- prerelease: false
19
+ version: '0'
21
20
  type: :runtime
21
+ prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '0.9'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
+ name: rack
28
29
  requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - "~>"
31
+ - - ">="
31
32
  - !ruby/object:Gem::Version
32
33
  version: '1.6'
33
- name: rack
34
- prerelease: false
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '3.0'
35
37
  type: :runtime
38
+ prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
38
- - - "~>"
41
+ - - ">="
39
42
  - !ruby/object:Gem::Version
40
43
  version: '1.6'
41
- - !ruby/object:Gem::Dependency
42
- requirement: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
44
+ - - "<"
45
45
  - !ruby/object:Gem::Version
46
- version: '4'
47
- name: sequel
48
- prerelease: false
49
- type: :runtime
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '4'
46
+ version: '3.0'
55
47
  - !ruby/object:Gem::Dependency
48
+ name: rspec
56
49
  requirement: !ruby/object:Gem::Requirement
57
50
  requirements:
58
51
  - - "~>"
59
52
  - !ruby/object:Gem::Version
60
53
  version: '3'
61
- name: rspec
62
- prerelease: false
63
54
  type: :development
55
+ prerelease: false
64
56
  version_requirements: !ruby/object:Gem::Requirement
65
57
  requirements:
66
58
  - - "~>"
@@ -77,8 +69,6 @@ files:
77
69
  - LICENSE.txt
78
70
  - Makefile
79
71
  - README.md
80
- - env.txt
81
- - env2.txt
82
72
  - flack.gemspec
83
73
  - lib/flack.rb
84
74
  - lib/flack/app.rb
@@ -86,13 +76,14 @@ files:
86
76
  - lib/flack/app/helpers.rb
87
77
  - lib/flack/app/index.rb
88
78
  - lib/flack/app/message.rb
79
+ - lib/flack/app/messages.rb
80
+ - lib/flack/app/pointers.rb
89
81
  - lib/flack/app/static.rb
90
- - t.txt
91
- homepage: http://github.com/floraison
82
+ homepage: https://github.com/floraison/flack
92
83
  licenses:
93
84
  - MIT
94
85
  metadata: {}
95
- post_install_message:
86
+ post_install_message:
96
87
  rdoc_options: []
97
88
  require_paths:
98
89
  - lib
@@ -107,9 +98,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
98
  - !ruby/object:Gem::Version
108
99
  version: '0'
109
100
  requirements: []
110
- rubyforge_project:
111
- rubygems_version: 2.4.8
112
- signing_key:
101
+ rubygems_version: 3.0.3
102
+ signing_key:
113
103
  specification_version: 4
114
104
  summary: a web front-end to the flor workflow engine
115
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
-