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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +17 -37
- data/Rakefile +35 -0
- data/bin/console +8 -4
- data/bin/post-receive.sh +3 -0
- data/bin/setup +7 -1
- data/generated/zoo.dot +37 -0
- data/generated/zoo.dot.png +0 -0
- data/{lib/picatrix/generated/view_submissions.rb → generated/zoo/resources/animals.rb} +10 -13
- data/generated/zoo/support/mason.rb +114 -0
- data/generated/zoo/support/namespaces.json +7 -0
- data/generated/zoo/support/picatrix.mason.pb.rb +95 -0
- data/generated/zoo/support/zoo.pb.rb +76 -0
- data/generated/zoo/support/zoo.proto +65 -0
- data/generated/zoo/zoo.rb +116 -0
- data/lib/picatrix.rb +25 -10
- data/lib/picatrix/buffy.rb +38 -40
- data/lib/picatrix/cruddy.rb +18 -16
- data/lib/picatrix/jenny.rb +31 -5
- data/lib/picatrix/link_relation_index.rb +1 -1
- data/lib/picatrix/pacman.rb +12 -6
- data/lib/picatrix/protoc.rb +7 -0
- data/lib/picatrix/prototyper.rb +56 -0
- data/lib/picatrix/routes.rb +40 -11
- data/{definitions/mason.proto → lib/picatrix/support/picatrix.mason.proto} +16 -13
- data/lib/picatrix/templates/app.proto +42 -0
- data/lib/picatrix/templates/app.rb +24 -136
- data/lib/picatrix/templates/mason.rb +114 -0
- data/lib/picatrix/templates/namespaces.json +7 -0
- data/lib/picatrix/templates/type.rb +6 -3
- data/lib/picatrix/transform_to_hash.rb +2 -2
- data/lib/picatrix/version.rb +1 -1
- data/notes.md +34 -0
- metadata +20 -10
- data/definitions/app.proto +0 -47
- data/lib/picatrix/fixtures/view_submission.rb +0 -19
- data/lib/picatrix/generated/app.pb.rb +0 -79
- data/lib/picatrix/generated/app.rb +0 -209
- data/lib/picatrix/generated/mason.pb.rb +0 -90
- data/lib/picatrix/generated/mason/namespaces.json +0 -7
@@ -0,0 +1,76 @@
|
|
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 'picatrix.mason.pb'
|
13
|
+
|
14
|
+
|
15
|
+
##
|
16
|
+
# Message Classes
|
17
|
+
#
|
18
|
+
class Animals < ::Protobuf::Message
|
19
|
+
class Controls < ::Protobuf::Message; end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
class Animal < ::Protobuf::Message
|
24
|
+
class Controls < ::Protobuf::Message; end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
class AnimalEditTemplate < ::Protobuf::Message; end
|
29
|
+
class AnimalRemoveTemplate < ::Protobuf::Message; end
|
30
|
+
class AnimalsCreateTemplate < ::Protobuf::Message; end
|
31
|
+
class AnimalsFilterTemplate < ::Protobuf::Message; end
|
32
|
+
class NewestAnimals < ::Protobuf::Message; end
|
33
|
+
|
34
|
+
|
35
|
+
##
|
36
|
+
# Message Fields
|
37
|
+
#
|
38
|
+
class Animals
|
39
|
+
class Controls
|
40
|
+
optional ::Picatrix::Mason::Self, :self, 1
|
41
|
+
end
|
42
|
+
|
43
|
+
optional :int32, :id, 1
|
44
|
+
optional ::Animals::Controls, :controls, 2
|
45
|
+
repeated ::Animal, :collection, 3
|
46
|
+
end
|
47
|
+
|
48
|
+
class Animal
|
49
|
+
class Controls
|
50
|
+
optional ::Picatrix::Mason::Self, :self, 1
|
51
|
+
end
|
52
|
+
|
53
|
+
optional :int32, :id, 1
|
54
|
+
optional ::Animal::Controls, :controls, 2
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
##
|
59
|
+
# Extended Message Fields
|
60
|
+
#
|
61
|
+
class ::Picatrix::Mason::Edit < ::Protobuf::Message
|
62
|
+
optional ::AnimalEditTemplate, :edit_template, 10, :extension => true
|
63
|
+
end
|
64
|
+
|
65
|
+
class ::Picatrix::Mason::Remove < ::Protobuf::Message
|
66
|
+
optional ::AnimalRemoveTemplate, :remove_template, 10, :extension => true
|
67
|
+
end
|
68
|
+
|
69
|
+
class ::Picatrix::Mason::Create < ::Protobuf::Message
|
70
|
+
optional ::AnimalsCreateTemplate, :create_template, 10, :extension => true
|
71
|
+
end
|
72
|
+
|
73
|
+
class ::Picatrix::Mason::Filter < ::Protobuf::Message
|
74
|
+
optional ::AnimalsFilterTemplate, :filter_template, 10, :extension => true
|
75
|
+
end
|
76
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
import "picatrix.mason.proto";
|
2
|
+
|
3
|
+
// representation objects
|
4
|
+
|
5
|
+
message Animals {
|
6
|
+
optional int32 id = 1;
|
7
|
+
|
8
|
+
message Controls {
|
9
|
+
optional picatrix.mason.Self self = 1;
|
10
|
+
}
|
11
|
+
|
12
|
+
optional Controls controls = 2;
|
13
|
+
|
14
|
+
repeated Animal collection = 3;
|
15
|
+
|
16
|
+
}
|
17
|
+
|
18
|
+
message Animal {
|
19
|
+
optional int32 id = 1;
|
20
|
+
|
21
|
+
message Controls {
|
22
|
+
optional picatrix.mason.Self self = 1;
|
23
|
+
}
|
24
|
+
|
25
|
+
optional Controls controls = 2;
|
26
|
+
|
27
|
+
}
|
28
|
+
|
29
|
+
|
30
|
+
// generic CRUFD controls to extend
|
31
|
+
// per item representation
|
32
|
+
|
33
|
+
message AnimalEditTemplate {
|
34
|
+
}
|
35
|
+
extend picatrix.mason.Edit {
|
36
|
+
optional AnimalEditTemplate edit_template = 10;
|
37
|
+
}
|
38
|
+
|
39
|
+
message AnimalRemoveTemplate {
|
40
|
+
}
|
41
|
+
extend picatrix.mason.Remove {
|
42
|
+
optional AnimalRemoveTemplate remove_template = 10;
|
43
|
+
}
|
44
|
+
|
45
|
+
|
46
|
+
// per collection representation
|
47
|
+
|
48
|
+
message AnimalsCreateTemplate {
|
49
|
+
}
|
50
|
+
extend picatrix.mason.Create {
|
51
|
+
optional AnimalsCreateTemplate create_template = 10;
|
52
|
+
}
|
53
|
+
|
54
|
+
message AnimalsFilterTemplate {
|
55
|
+
}
|
56
|
+
extend picatrix.mason.Filter {
|
57
|
+
optional AnimalsFilterTemplate filter_template = 10;
|
58
|
+
}
|
59
|
+
|
60
|
+
|
61
|
+
// totally custom controls
|
62
|
+
|
63
|
+
message NewestAnimals {
|
64
|
+
}
|
65
|
+
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'sinatra/json'
|
3
|
+
require 'protobuf'
|
4
|
+
require 'require_all'
|
5
|
+
|
6
|
+
$:.unshift(File.join(File.dirname(__FILE__)))
|
7
|
+
$:.unshift(File.join(File.dirname(__FILE__), 'support'))
|
8
|
+
$:.unshift(File.join(File.dirname(__FILE__), 'resources'))
|
9
|
+
|
10
|
+
require("./generated/zoo/support/picatrix.mason.pb")
|
11
|
+
require("./generated/zoo/support/mason")
|
12
|
+
require("./generated/zoo/support/zoo.pb")
|
13
|
+
require_all("generated/zoo/resources/*.rb")
|
14
|
+
|
15
|
+
class Zoo < Sinatra::Base
|
16
|
+
include Picatrix::Mason
|
17
|
+
|
18
|
+
set :public_folder => "public", :static => true
|
19
|
+
|
20
|
+
get '/rels' do
|
21
|
+
json({:@controls=>{:up=>"http://localhost:9292/", :self=>"http://localhost:9292/rels"}, :link_relations=>{:newest=>["root -(GET)-> animals", "animal -(GET)-> animals", "animals -(DELETE)-> animals"], :":item_id"=>["animals -(GET)-> animal"], :filter=>["animals -(GET)-> animals"], :create=>["animals -(POST)-> animal"], :edit=>["animal -(PATCH)-> animal"]}})
|
22
|
+
end
|
23
|
+
|
24
|
+
get '/' do
|
25
|
+
status, headers, body = call env.merge("PATH_INFO" => "/animals")
|
26
|
+
[status, headers, body]
|
27
|
+
end
|
28
|
+
|
29
|
+
def json(hash = {})
|
30
|
+
# anything set here will be sent in all responses
|
31
|
+
super({"@namespaces"=>{"z"=>{"name"=>"http://localhost:9292/rels#"}}}.merge!(hash))
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
get "/animals" do
|
36
|
+
|
37
|
+
response_body = {"animals" => AnimalsResource.as_hashes}
|
38
|
+
|
39
|
+
controls = {}
|
40
|
+
|
41
|
+
|
42
|
+
controls.merge!(send("create".to_sym, Animals).call("animals".pluralize, params))
|
43
|
+
|
44
|
+
controls.merge!(send("filter".to_sym, Animals).call("animals".pluralize, params))
|
45
|
+
|
46
|
+
controls.merge!(send("mason_self".to_sym, Animals).call("animals".pluralize, params))
|
47
|
+
|
48
|
+
controls.merge!(send("mason_up".to_sym, Animals).call("animals".pluralize, params))
|
49
|
+
|
50
|
+
|
51
|
+
json({
|
52
|
+
:@controls => controls
|
53
|
+
}.merge!(response_body))
|
54
|
+
end
|
55
|
+
|
56
|
+
get "/animals/:item_id" do
|
57
|
+
|
58
|
+
response_body = AnimalsResource.find(params[:item_id]).to_hash.except(:controls)
|
59
|
+
|
60
|
+
controls = {}
|
61
|
+
|
62
|
+
|
63
|
+
controls.merge!(send("edit".to_sym, Animal).call("animal".pluralize, params))
|
64
|
+
|
65
|
+
controls.merge!(send("remove".to_sym, Animal).call("animal".pluralize, params))
|
66
|
+
|
67
|
+
controls.merge!(send("mason_self".to_sym, Animal).call("animal".pluralize, params))
|
68
|
+
|
69
|
+
controls.merge!(send("mason_up".to_sym, Animal).call("animal".pluralize, params))
|
70
|
+
|
71
|
+
|
72
|
+
json({
|
73
|
+
:@controls => controls
|
74
|
+
}.merge!(response_body))
|
75
|
+
end
|
76
|
+
|
77
|
+
post "/animals" do
|
78
|
+
|
79
|
+
response_body = AnimalsResource.create(params[:item_id]).to_hash.except(:controls)
|
80
|
+
|
81
|
+
controls = {}
|
82
|
+
|
83
|
+
json({
|
84
|
+
:@controls => controls
|
85
|
+
}.merge!(response_body))
|
86
|
+
end
|
87
|
+
|
88
|
+
delete "/animals/:item_id" do
|
89
|
+
|
90
|
+
response_body = {"animals" => AnimalsResource.as_hashes}
|
91
|
+
|
92
|
+
controls = {}
|
93
|
+
|
94
|
+
json({
|
95
|
+
:@controls => controls
|
96
|
+
}.merge!(response_body))
|
97
|
+
end
|
98
|
+
|
99
|
+
patch "/animals/:item_id" do
|
100
|
+
|
101
|
+
response_body = AnimalsResource.find(params[:item_id]).to_hash.except(:controls)
|
102
|
+
|
103
|
+
controls = {}
|
104
|
+
|
105
|
+
|
106
|
+
controls.merge!(send("mason_self".to_sym, Animal).call("animal".pluralize, params))
|
107
|
+
|
108
|
+
controls.merge!(send("mason_up".to_sym, Animal).call("animal".pluralize, params))
|
109
|
+
|
110
|
+
|
111
|
+
json({
|
112
|
+
:@controls => controls
|
113
|
+
}.merge!(response_body))
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
data/lib/picatrix.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib/picatrix/generated', __FILE__)
|
2
|
+
|
1
3
|
require "picatrix/version"
|
2
4
|
require "protobuf"
|
3
5
|
require "parslet"
|
@@ -9,31 +11,39 @@ require "thor"
|
|
9
11
|
require "picatrix/pacman"
|
10
12
|
require "picatrix/digraph_parser"
|
11
13
|
require "picatrix/transform_to_hash"
|
14
|
+
require "picatrix/buffy"
|
12
15
|
require "picatrix/link_relation_index"
|
13
16
|
require "picatrix/routes"
|
17
|
+
require "picatrix/protoc"
|
14
18
|
require "picatrix/cruddy"
|
15
|
-
require "picatrix/
|
19
|
+
require "picatrix/prototyper"
|
16
20
|
require "picatrix/jenny"
|
17
21
|
|
18
22
|
module Picatrix
|
19
23
|
class CLI < Thor
|
20
|
-
desc "g <dot file name> <
|
24
|
+
desc "g <dot file name> <optional: app name>",
|
25
|
+
"generates Sinatra app, uses dot file name for app name if none given"
|
21
26
|
option :force, :type => :boolean
|
22
27
|
|
23
|
-
def g(dot_file_name,
|
28
|
+
def g(dot_file_name, app_name = nil)
|
29
|
+
app_name = File.basename(dot_file_name, ".dot") if app_name.nil?
|
30
|
+
|
24
31
|
puts "using: #{dot_file_name}"
|
25
|
-
puts "output: #{
|
32
|
+
puts "output: #{app_name}"
|
26
33
|
|
27
34
|
Jenny.new(
|
28
35
|
Pacman.new(
|
29
36
|
dot_file_name
|
30
|
-
)
|
31
|
-
options
|
37
|
+
),
|
38
|
+
options,
|
39
|
+
app_name
|
32
40
|
).just_do_it
|
33
41
|
end
|
34
42
|
|
35
|
-
desc "prep <dot file name>", "outputs an image and
|
36
|
-
def prep(dot_file_name)
|
43
|
+
desc "prep <dot file name> <app name>", "outputs an image and protobuf templates"
|
44
|
+
def prep(dot_file_name, app_name = nil)
|
45
|
+
app_name = File.basename(dot_file_name, ".dot") if app_name.nil?
|
46
|
+
|
37
47
|
GraphViz.parse(dot_file_name, :path => "/usr/local/bin").
|
38
48
|
output(:png => "#{dot_file_name}.png")
|
39
49
|
puts "output to #{dot_file_name}.png"
|
@@ -41,9 +51,14 @@ module Picatrix
|
|
41
51
|
Buffy.new(
|
42
52
|
Pacman.new(
|
43
53
|
dot_file_name
|
44
|
-
)
|
45
|
-
|
54
|
+
),
|
55
|
+
options,
|
56
|
+
app_name
|
57
|
+
).slay
|
58
|
+
|
46
59
|
puts "output to generated/"
|
60
|
+
puts "You will need to edit your #{app_name}.proto file to match your schema." +
|
61
|
+
" Then you can run `picapica g <app_name>` to generate your application."
|
47
62
|
end
|
48
63
|
end
|
49
64
|
end
|
data/lib/picatrix/buffy.rb
CHANGED
@@ -1,56 +1,54 @@
|
|
1
|
-
require 'protobuf'
|
2
|
-
require 'faker'
|
3
|
-
|
4
1
|
module Picatrix
|
5
2
|
class Buffy
|
6
3
|
include Thor::Base
|
7
4
|
include Thor::Actions
|
8
5
|
|
9
|
-
attr_accessor :
|
10
|
-
:
|
6
|
+
attr_accessor :resources, :link_relations, :representation_klasses,
|
7
|
+
:app_name
|
11
8
|
|
12
|
-
|
9
|
+
# must be disjoint due to nature of protobuf
|
10
|
+
ITEM_ACTIONS = %w{ Edit Remove }
|
11
|
+
COL_ACTIONS = %w{ Create Filter }
|
12
|
+
CRUFD = %w{ Create Edit Remove Filter }
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
Protobuf::Field::StringField => "Faker::Lorem.word"
|
17
|
-
}
|
14
|
+
argument :name
|
15
|
+
source_root File.dirname(__FILE__)
|
18
16
|
|
19
|
-
def initialize(
|
17
|
+
def initialize(pacman, options = {}, app_name = "app")
|
20
18
|
# thor related
|
21
19
|
@options = options
|
22
20
|
@destination_stack = [self.class.source_root]
|
21
|
+
@app_name = app_name
|
22
|
+
|
23
|
+
@representation_klasses = pacman.nodes.keys.map(&:camelize)
|
24
|
+
|
25
|
+
@item_representations = @representation_klasses.map(&:singularize).uniq
|
26
|
+
@col_representations = @representation_klasses.map(&:pluralize).uniq
|
27
|
+
@resources = @item_representations + @col_representations
|
23
28
|
|
24
|
-
@
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
field_value =
|
31
|
-
if PROTOBUF_FIXTURES[field.type_class]
|
32
|
-
# TODO this is too general need some way to signal
|
33
|
-
# primary key which is addressable
|
34
|
-
if field.name.to_s.include?("id")
|
35
|
-
"id = #{PROTOBUF_FIXTURES[field.type_class]}"
|
36
|
-
else
|
37
|
-
PROTOBUF_FIXTURES[field.type_class]
|
38
|
-
end
|
39
|
-
elsif field.type_class.to_s.demodulize == "Controls"
|
40
|
-
"#{field.type_class}.new(minimal_controls_for(item_id))"
|
41
|
-
else
|
42
|
-
# TODO recursively gen these relations
|
43
|
-
"[#{field.type_class}.new(params = {})]"
|
44
|
-
end
|
45
|
-
|
46
|
-
memo[field.name] = field_value
|
47
|
-
memo
|
29
|
+
@link_relations = pacman.edges.collect do |edge|
|
30
|
+
target = edge[edge.keys.first][:target]
|
31
|
+
link_relation = edge[edge.keys.first][:link_relation]
|
32
|
+
if link_relation[0] != ':' && !CRUFD.map(&:downcase).include?(link_relation)
|
33
|
+
"#{link_relation.camelize}" + "#{target.camelize}"
|
48
34
|
end
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
35
|
+
end.compact.uniq
|
36
|
+
end
|
37
|
+
|
38
|
+
def slay
|
39
|
+
# TODO need to make prefix setter
|
40
|
+
@prefix = app_name[0]
|
41
|
+
@host = "http://localhost:9292/"
|
42
|
+
|
43
|
+
template(
|
44
|
+
'templates/namespaces.json',
|
45
|
+
File.join("../../generated/#{app_name}/support/namespaces.json")
|
46
|
+
)
|
47
|
+
|
48
|
+
template(
|
49
|
+
'templates/app.proto',
|
50
|
+
File.join("../../generated/#{app_name}/support/#{app_name}.proto")
|
51
|
+
)
|
54
52
|
end
|
55
53
|
end
|
56
54
|
end
|
data/lib/picatrix/cruddy.rb
CHANGED
@@ -2,6 +2,9 @@ module Picatrix
|
|
2
2
|
class Cruddy
|
3
3
|
attr_accessor :controls
|
4
4
|
|
5
|
+
# iow if it is addressable it has a self
|
6
|
+
DEFAULT_CONTROLS = [:mason_self, :mason_up]
|
7
|
+
|
5
8
|
def initialize(edges)
|
6
9
|
@controls = edges.inject({}) do |memo, edge|
|
7
10
|
source = edge.keys.first
|
@@ -16,30 +19,29 @@ module Picatrix
|
|
16
19
|
|
17
20
|
private
|
18
21
|
def appropriate_controls_for(source)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
}
|
24
|
-
else
|
25
|
-
{
|
26
|
-
source => template_map(:item)
|
27
|
-
}
|
28
|
-
end
|
22
|
+
by_size = collection?(source) ? :collection : :item
|
23
|
+
{
|
24
|
+
source => template_map(by_size)
|
25
|
+
}
|
29
26
|
end
|
30
27
|
def template_map(type)
|
31
28
|
{
|
29
|
+
# what controls do you want to get back
|
30
|
+
# from a given method on a item/collection
|
32
31
|
item: {
|
33
|
-
get: :
|
34
|
-
patch:
|
35
|
-
put:
|
36
|
-
delete: :
|
32
|
+
get: [:edit, :remove] + DEFAULT_CONTROLS,
|
33
|
+
patch: DEFAULT_CONTROLS,
|
34
|
+
put: DEFAULT_CONTROLS,
|
35
|
+
delete: [:mason_up]
|
37
36
|
},
|
38
37
|
collection: {
|
39
|
-
|
40
|
-
|
38
|
+
get: [:create, :filter] + DEFAULT_CONTROLS,
|
39
|
+
post: [:mason_self]
|
41
40
|
}
|
42
41
|
}[type]
|
43
42
|
end
|
43
|
+
def collection?(source)
|
44
|
+
source.pluralize == source
|
45
|
+
end
|
44
46
|
end
|
45
47
|
end
|