picatrix 0.5.0 → 0.5.5

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/README.md +17 -37
  4. data/Rakefile +35 -0
  5. data/bin/console +8 -4
  6. data/bin/post-receive.sh +3 -0
  7. data/bin/setup +7 -1
  8. data/generated/zoo.dot +37 -0
  9. data/generated/zoo.dot.png +0 -0
  10. data/{lib/picatrix/generated/view_submissions.rb → generated/zoo/resources/animals.rb} +10 -13
  11. data/generated/zoo/support/mason.rb +114 -0
  12. data/generated/zoo/support/namespaces.json +7 -0
  13. data/generated/zoo/support/picatrix.mason.pb.rb +95 -0
  14. data/generated/zoo/support/zoo.pb.rb +76 -0
  15. data/generated/zoo/support/zoo.proto +65 -0
  16. data/generated/zoo/zoo.rb +116 -0
  17. data/lib/picatrix.rb +25 -10
  18. data/lib/picatrix/buffy.rb +38 -40
  19. data/lib/picatrix/cruddy.rb +18 -16
  20. data/lib/picatrix/jenny.rb +31 -5
  21. data/lib/picatrix/link_relation_index.rb +1 -1
  22. data/lib/picatrix/pacman.rb +12 -6
  23. data/lib/picatrix/protoc.rb +7 -0
  24. data/lib/picatrix/prototyper.rb +56 -0
  25. data/lib/picatrix/routes.rb +40 -11
  26. data/{definitions/mason.proto → lib/picatrix/support/picatrix.mason.proto} +16 -13
  27. data/lib/picatrix/templates/app.proto +42 -0
  28. data/lib/picatrix/templates/app.rb +24 -136
  29. data/lib/picatrix/templates/mason.rb +114 -0
  30. data/lib/picatrix/templates/namespaces.json +7 -0
  31. data/lib/picatrix/templates/type.rb +6 -3
  32. data/lib/picatrix/transform_to_hash.rb +2 -2
  33. data/lib/picatrix/version.rb +1 -1
  34. data/notes.md +34 -0
  35. metadata +20 -10
  36. data/definitions/app.proto +0 -47
  37. data/lib/picatrix/fixtures/view_submission.rb +0 -19
  38. data/lib/picatrix/generated/app.pb.rb +0 -79
  39. data/lib/picatrix/generated/app.rb +0 -209
  40. data/lib/picatrix/generated/mason.pb.rb +0 -90
  41. data/lib/picatrix/generated/mason/namespaces.json +0 -7
@@ -0,0 +1,114 @@
1
+ module Picatrix
2
+ module Mason
3
+ def mason_up(type)
4
+ if type.to_s.pluralize == type
5
+ proc do |path, params|
6
+ {
7
+ up: Mason::Up.new(
8
+ {
9
+ href: "http://localhost:9292/#{<%= @root_path %>}"
10
+ }
11
+ ).to_hash
12
+ }
13
+ end
14
+ else
15
+ proc do |path, params|
16
+ {
17
+ up: Mason::Up.new(
18
+ {
19
+ href: "http://localhost:9292/#{path.pluralize}"
20
+ }
21
+ ).to_hash
22
+ }
23
+ end
24
+ end
25
+ end
26
+ def mason_self(item)
27
+ proc do |path, params|
28
+ if params[:item_id]
29
+ {
30
+ self: Mason::Self.new(
31
+ {
32
+ href: "http://localhost:9292/#{path}/#{params[:item_id]}"
33
+ }
34
+ ).to_hash
35
+ }
36
+ else
37
+ {
38
+ self: Mason::Self.new(
39
+ {
40
+ href: "http://localhost:9292/#{path}"
41
+ }
42
+ ).to_hash
43
+ }
44
+ end
45
+ end
46
+ end
47
+ def edit(item)
48
+ proc do |path, params|
49
+ {
50
+ "<%= @prefix %>edit": Mason::Edit.new(
51
+ {
52
+ href: "http://localhost:9292/#{path}/#{params[:item_id]}",
53
+ method: Mason::HTTPVerb::PATCH
54
+ }
55
+ ).to_hash
56
+ }
57
+ end
58
+ end
59
+ def remove(item)
60
+ proc do |path, params|
61
+ {
62
+ "<%= @prefix %>remove": Mason::Remove.new(
63
+ {
64
+ href: "http://localhost:9292/#{path}/#{params[:item_id]}",
65
+ method: Mason::HTTPVerb::DELETE
66
+ }
67
+ ).to_hash
68
+ }
69
+ end
70
+ end
71
+ def create(collection)
72
+ proc do |path, params|
73
+ collection_name = collection.to_s.camelize
74
+ {
75
+ "<%= @prefix %>create": Mason::Create.new(
76
+ {
77
+ href: "http://localhost:9292/#{path}",
78
+ method: Mason::HTTPVerb::POST,
79
+ title: "Create a new #{collection_name}",
80
+ create_template: "#{collection_name}CreateTemplate".constantize.new({})
81
+ }
82
+ )
83
+ }
84
+ end
85
+ end
86
+ def filter(collection)
87
+ proc do |path, params|
88
+ if params[:newest]
89
+ {
90
+ "<%= @prefix %>filter": Mason::Filter.new(
91
+ {
92
+ href: "http://localhost:9292/#{path}?filter=newest",
93
+ isHrefTemplate: true,
94
+ method: Mason::HTTPVerb::GET,
95
+ title: "Show the newest additions to #{collection}"
96
+ }
97
+ ).to_hash
98
+ }
99
+ else
100
+ {
101
+ "<%= @prefix %>filter": Mason::Filter.new(
102
+ {
103
+ href: "http://localhost:9292/#{path}?$select&{field1}={value1}&{field2}={value2}",
104
+ isHrefTemplate: true,
105
+ method: Mason::HTTPVerb::GET,
106
+ title: "Filter using $select on schema fields"
107
+ }
108
+ ).to_hash
109
+ }
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,7 @@
1
+ {
2
+ "@namespaces": {
3
+ "<%= @prefix %>": {
4
+ "name": "<%= @host %>rels#"
5
+ }
6
+ }
7
+ }
@@ -30,12 +30,15 @@ class <%= @resource_name %>Resource
30
30
  }
31
31
  <%= @resource_name %>.new(collection: collection)
32
32
  end
33
-
33
+ def self.as_hashes
34
+ self.all.collection.map(&:to_hash)
35
+ end
36
+ # this makes no sense on this class
34
37
  def self.minimal_controls_for(item_id)
35
38
  host = "http://localhost:9292"
36
39
  {
37
- self: Mason::Self.new(href: "#{host}/<%= @resource_name.singularize.underscore %>/#{item_id}"),
38
- up: Mason::Up.new(href: "#{host}/<%= @resource_name.underscore %>")
40
+ self: ::Picatrix::Mason::Self.new(href: "#{host}/<%= @resource_name.underscore %>/#{item_id}"),
41
+ up: ::Picatrix::Mason::Up.new(href: "#{host}/<%= @resource_name.underscore %>")
39
42
  }
40
43
  end
41
44
  end
@@ -4,7 +4,7 @@ module Picatrix
4
4
  {
5
5
  node: {
6
6
  String(node[:name]) => {
7
- label: String(node[:label]),
7
+ label: String(node[:label]).delete('"'),
8
8
  }
9
9
  }
10
10
  }
@@ -26,7 +26,7 @@ module Picatrix
26
26
  edge: {
27
27
  String(edge[:outbound]) => {
28
28
  target: String(edge[:inbound]).delete(" {} "),
29
- link_relation: String(edge[:link_relation]),
29
+ link_relation: String(edge[:link_relation]).delete('"'),
30
30
  method: method
31
31
  }
32
32
  }
@@ -1,3 +1,3 @@
1
1
  module Picatrix
2
- VERSION = "0.5.0"
2
+ VERSION = "0.5.5"
3
3
  end
data/notes.md ADDED
@@ -0,0 +1,34 @@
1
+ ## Development
2
+
3
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
4
+
5
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
6
+
7
+ ## Contributing
8
+
9
+ Bug reports and pull requests are welcome on [GitHub](https://github.com/mooreniemi/picatrix). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
10
+
11
+
12
+ ## About
13
+ Directed graphs get complicated, but can be divided into simpler subgraphs. Picatrix is currently useful for only a single workflow (and barely that right now, as we're way before a real release). Integrated workflows will involve generating several route sets that will be required into a single Sinatra app. Some workflows may even be representable as DAGs/trees.
14
+
15
+ The ideal way to use Picatrix is to do an exercise in designing your API "outside in" where all inputs/outputs are defined, and a state diagram is drawn. This diagram can be translated to a dot file, and the inputs/outputs can be translated into hypermedia assets.
16
+
17
+ ## ongoing work notes
18
+ ### TODO
19
+
20
+ - CRUD+
21
+ - `create` should have form
22
+ - `filter` actions should have a app hook in routes
23
+ - `edit` should have form (form = template in case i forget)
24
+ - generic filter action by schema? re-namespace it?
25
+
26
+ ### the end state
27
+
28
+ process goes: .dot file + `prep` (1)-> proto file from nodes + user input into .proto + `proto` (2)-> ruby representation classes + user input to fixturize (3)-> `g` (4)-> `rackup generated/app.rb`
29
+
30
+ 1. outside in design process produced a diagram, which is written into a .dot file
31
+ 2. all nodes are representations of resources, and thus get proto objects generated for them, here is where the inputs/outputs are formed into a schema
32
+ 3. representation nodes now have ruby classes that reflect the information that will be sent back and forth in messages so we generate the app
33
+ 4. boot up the app
34
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: picatrix
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Moore-Niemi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-11-16 00:00:00.000000000 Z
11
+ date: 2015-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parslet
@@ -251,28 +251,37 @@ files:
251
251
  - Rakefile
252
252
  - bin/console
253
253
  - bin/picapica
254
+ - bin/post-receive.sh
254
255
  - bin/setup
255
- - definitions/app.proto
256
- - definitions/mason.proto
256
+ - generated/zoo.dot
257
+ - generated/zoo.dot.png
258
+ - generated/zoo/resources/animals.rb
259
+ - generated/zoo/support/mason.rb
260
+ - generated/zoo/support/namespaces.json
261
+ - generated/zoo/support/picatrix.mason.pb.rb
262
+ - generated/zoo/support/zoo.pb.rb
263
+ - generated/zoo/support/zoo.proto
264
+ - generated/zoo/zoo.rb
257
265
  - lib/picatrix.rb
258
266
  - lib/picatrix/buffy.rb
259
267
  - lib/picatrix/cruddy.rb
260
268
  - lib/picatrix/digraph_parser.rb
261
- - lib/picatrix/fixtures/view_submission.rb
262
- - lib/picatrix/generated/app.pb.rb
263
- - lib/picatrix/generated/app.rb
264
- - lib/picatrix/generated/mason.pb.rb
265
- - lib/picatrix/generated/mason/namespaces.json
266
- - lib/picatrix/generated/view_submissions.rb
267
269
  - lib/picatrix/jenny.rb
268
270
  - lib/picatrix/link_relation_index.rb
269
271
  - lib/picatrix/pacman.rb
272
+ - lib/picatrix/protoc.rb
273
+ - lib/picatrix/prototyper.rb
270
274
  - lib/picatrix/routes.rb
275
+ - lib/picatrix/support/picatrix.mason.proto
276
+ - lib/picatrix/templates/app.proto
271
277
  - lib/picatrix/templates/app.rb
272
278
  - lib/picatrix/templates/control.rb
279
+ - lib/picatrix/templates/mason.rb
280
+ - lib/picatrix/templates/namespaces.json
273
281
  - lib/picatrix/templates/type.rb
274
282
  - lib/picatrix/transform_to_hash.rb
275
283
  - lib/picatrix/version.rb
284
+ - notes.md
276
285
  - picatrix.gemspec
277
286
  homepage: https://github.com/mooreniemi/picatrix
278
287
  licenses:
@@ -299,3 +308,4 @@ signing_key:
299
308
  specification_version: 4
300
309
  summary: 'input: dot file + yml files, output: ruby api'
301
310
  test_files: []
311
+ has_rdoc:
@@ -1,47 +0,0 @@
1
- import "mason.proto";
2
-
3
- // objects
4
- message ViewSubmission {
5
- optional int32 id = 1;
6
- optional string category = 2;
7
- optional string photo = 3;
8
-
9
- // items probably want a minimal representation
10
- // of available controls when in collection view
11
- message Controls {
12
- optional mason.Self self = 2;
13
- }
14
-
15
- message Attachment {
16
- optional int32 id = 1;
17
- }
18
-
19
- optional Controls controls = 4;
20
- repeated Attachment attachments = 5;
21
- }
22
-
23
- message ViewSubmissions {
24
- repeated ViewSubmission collection = 1;
25
- }
26
-
27
- // controls
28
- message EditViewSubmission {
29
- // someday gen this from schema?
30
- optional mason.Edit form = 3;
31
- message Template {
32
- optional string category = 1;
33
- optional string has_photo = 2;
34
- }
35
- optional Template template = 4;
36
- }
37
-
38
- message CreateViewSubmission {
39
- // someday gen this from schema?
40
- optional mason.Create form = 3;
41
- message Template {
42
- optional string category = 1;
43
- optional string has_photo = 2;
44
- }
45
- optional Template template = 4;
46
- }
47
-
@@ -1,19 +0,0 @@
1
- class ViewSubmissionFixture
2
- # real object has more properties
3
- def self.attributes
4
- {
5
- category: random_category,
6
- photo: random_photo,
7
- secret_data: "that won't be shared",
8
- pci_data: "really won't appear"
9
- }
10
- end
11
-
12
- def self.random_category
13
- %w{ cats }.sample
14
- end
15
-
16
- def self.random_photo
17
- %w{ http://imgur.com/r/cats/myEqIZx }.sample
18
- end
19
- end
@@ -1,79 +0,0 @@
1
- # encoding: utf-8
2
-
3
- ##
4
- # This file is auto-generated. DO NOT EDIT!
5
- #
6
- require 'protobuf/message'
7
-
8
-
9
- ##
10
- # Imports
11
- #
12
- require_relative 'mason.pb.rb'
13
-
14
-
15
- ##
16
- # Message Classes
17
- #
18
- class ViewSubmission < ::Protobuf::Message
19
- class Controls < ::Protobuf::Message; end
20
- class Attachment < ::Protobuf::Message; end
21
-
22
- end
23
-
24
- class ViewSubmissions < ::Protobuf::Message; end
25
- class EditViewSubmission < ::Protobuf::Message
26
- class Template < ::Protobuf::Message; end
27
-
28
- end
29
-
30
- class CreateViewSubmission < ::Protobuf::Message
31
- class Template < ::Protobuf::Message; end
32
-
33
- end
34
-
35
-
36
-
37
- ##
38
- # Message Fields
39
- #
40
- class ViewSubmission
41
- class Controls
42
- optional ::Mason::Self, :self, 2
43
- end
44
-
45
- class Attachment
46
- optional :int32, :id, 1
47
- end
48
-
49
- optional :int32, :id, 1
50
- optional :string, :category, 2
51
- optional :string, :photo, 3
52
- optional ::ViewSubmission::Controls, :controls, 4
53
- repeated ::ViewSubmission::Attachment, :attachments, 5
54
- end
55
-
56
- class ViewSubmissions
57
- repeated ::ViewSubmission, :collection, 1
58
- end
59
-
60
- class EditViewSubmission
61
- class Template
62
- optional :string, :category, 1
63
- optional :string, :has_photo, 2
64
- end
65
-
66
- optional ::Mason::Edit, :form, 3
67
- optional ::EditViewSubmission::Template, :template, 4
68
- end
69
-
70
- class CreateViewSubmission
71
- class Template
72
- optional :string, :category, 1
73
- optional :string, :has_photo, 2
74
- end
75
-
76
- optional ::Mason::Create, :form, 3
77
- optional ::CreateViewSubmission::Template, :template, 4
78
- end
79
-
@@ -1,209 +0,0 @@
1
- require 'sinatra'
2
- require 'sinatra/json'
3
- require 'protobuf'
4
- require 'require_all'
5
-
6
- require_all("./lib/picatrix/generated/*.rb")
7
-
8
- class App < Sinatra::Base
9
- set :public_folder => "public", :static => true
10
-
11
- get '/rels' do
12
- json({:@controls=>{:up=>"http://localhost:9292/", :self=>"http://localhost:9292/rels"}, :link_relations=>{:newest=>["root -(GET)-> view_submissions", "view_submission -(GET)-> view_submissions", "view_submissions -(DELETE)-> view_submissions"], :":item_id"=>["view_submissions -(GET)-> view_submission"], :filter=>["view_submissions -(GET)-> view_submissions"], :submit=>["view_submissions -(POST)-> view_submission"], :edit=>["view_submission -(PATCH)-> view_submission"]}})
13
- end
14
-
15
- get '/' do
16
- status, headers, body = call env.merge("PATH_INFO" => "/view_submissions")
17
- [status, headers, body]
18
- end
19
-
20
- def json(hash = {})
21
- # anything set here will be sent in all responses
22
- super({"@namespaces"=>{"s"=>{"name"=>"http://localhost:9292/rels#"}}}.merge!(hash))
23
- end
24
-
25
-
26
-
27
- get "/view_submissions" do
28
- items = ViewSubmissionsResource.all.collection.collect do |r|
29
- r.to_hash
30
- end
31
-
32
-
33
- controls = send(:filter, ViewSubmissions).call("view_submissions", params)
34
-
35
-
36
- json(
37
- {:@controls => controls}.
38
- merge!({"view_submissions" => items})
39
- )
40
- end
41
-
42
-
43
-
44
- get "/view_submission/:item_id" do
45
- item = ViewSubmissionsResource.find(params[:item_id])
46
-
47
-
48
- controls = send(:mason_self, ViewSubmission).call("view_submission", params)
49
-
50
-
51
- json(
52
- {:@controls => controls}.
53
- merge!(item.to_hash.except(:controls))
54
- )
55
- end
56
-
57
-
58
-
59
- post "/view_submission/:item_id" do
60
- item = ViewSubmissionsResource.create(params[:item_id])
61
-
62
-
63
- controls = {}
64
-
65
-
66
- json(
67
- {:@controls => controls}.
68
- merge!(item.to_hash.except(:controls))
69
- )
70
- end
71
-
72
-
73
-
74
- delete "/view_submissions" do
75
- items = ViewSubmissionsResource.all.collection.collect do |r|
76
- r.to_hash
77
- end
78
-
79
-
80
- controls = {}
81
-
82
-
83
- json(
84
- {:@controls => controls}.
85
- merge!({"view_submissions" => items})
86
- )
87
- end
88
-
89
-
90
-
91
- patch "/view_submission/:item_id" do
92
- item = ViewSubmissionsResource.find(params[:item_id])
93
-
94
-
95
- controls = send(:edit, ViewSubmission).call("view_submission", params)
96
-
97
-
98
- json(
99
- {:@controls => controls}.
100
- merge!(item.to_hash.except(:controls))
101
- )
102
- end
103
-
104
-
105
-
106
- def mason_up(type)
107
- if type == collection
108
- proc do |path, params|
109
- {
110
- up: Mason::Up.new(
111
- {
112
- href: "http://localhost:9292/#{view_submissions}"
113
- }
114
- ).to_hash
115
- }
116
- end
117
- else
118
- proc do |path, params|
119
- {
120
- up: Mason::Up.new(
121
- {
122
- href: "http://localhost:9292/#{path}"
123
- }
124
- ).to_hash
125
- }
126
- end
127
- end
128
- end
129
- def mason_self(item)
130
- proc do |path, params|
131
- if params[:item_id]
132
- {
133
- self: Mason::Self.new(
134
- {
135
- href: "http://localhost:9292/#{path}/#{params[:item_id]}"
136
- }
137
- ).to_hash
138
- }
139
- else
140
- {
141
- self: Mason::Self.new(
142
- {
143
- href: "http://localhost:9292/#{path}"
144
- }
145
- ).to_hash
146
- }
147
- end
148
- end
149
- end
150
- def edit(item)
151
- proc do |path, params|
152
- {
153
- edit: ("Edit" + item.to_s.singularize.camelize).constantize.new(
154
- {
155
- form: Mason::Edit.new(
156
- href: "http://localhost:9292/#{path}/#{params[:item_id]}"
157
- )
158
- }
159
- ).to_hash
160
- }
161
- end
162
- end
163
- def remove(item)
164
- proc do |path, params|
165
- {
166
- remove: Mason::Remove.new(
167
- {
168
- href: "http://localhost:9292/#{path}/#{params[:item_id]}"
169
- }
170
- ).to_hash
171
- }
172
- end
173
- end
174
- def create(item)
175
- proc do |path, params|
176
- {
177
- create: ("Create" + item.to_s.singularize.camelize).constantize.new(
178
- {
179
- form: Mason::Create.new(
180
- href: ""
181
- )
182
- }
183
- )
184
- }
185
- end
186
- end
187
- def filter(collection)
188
- # TODO this prob cant really work here
189
- proc do |path, params|
190
- if params[:item_id]
191
- {
192
- "s:filter": Mason::Filter.new(
193
- {
194
- href: "http://localhost:9292/#{path}/#{params[:item_id]}"
195
- }
196
- ).to_hash
197
- }
198
- else
199
- {
200
- "s:filter": Mason::Filter.new(
201
- {
202
- href: "http://localhost:9292/#{path}"
203
- }
204
- ).to_hash
205
- }
206
- end
207
- end
208
- end
209
- end