riddler 0.1.0 → 0.2.0
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/LICENSE.txt +1 -1
- data/README.md +105 -6
- data/lib/riddler.rb +52 -3
- data/lib/riddler/configuration.rb +11 -0
- data/lib/riddler/context.rb +40 -2
- data/lib/riddler/context_builder.rb +35 -0
- data/lib/riddler/context_builders/faraday_builder.rb +23 -0
- data/lib/riddler/context_builders/user_agent.rb +34 -0
- data/lib/riddler/context_director.rb +67 -0
- data/lib/riddler/drops/hash_drop.rb +29 -0
- data/lib/riddler/element.rb +15 -14
- data/lib/riddler/elements/heading.rb +0 -1
- data/lib/riddler/elements/image.rb +21 -0
- data/lib/riddler/elements/link.rb +30 -0
- data/lib/riddler/elements/text.rb +17 -0
- data/lib/riddler/elements/variant.rb +21 -0
- data/lib/riddler/includeable.rb +19 -0
- data/lib/riddler/protobuf/content_definition.proto +51 -0
- data/lib/riddler/protobuf/content_definition_pb.rb +33 -0
- data/lib/riddler/protobuf/content_management.proto +35 -0
- data/lib/riddler/protobuf/content_management_pb.rb +43 -0
- data/lib/riddler/protobuf/content_management_services_pb.rb +27 -0
- data/lib/riddler/protobuf/slug.proto +61 -0
- data/lib/riddler/protobuf/slug_pb.rb +52 -0
- data/lib/riddler/step.rb +16 -16
- data/lib/riddler/steps/content.rb +5 -5
- data/lib/riddler/steps/variant.rb +23 -0
- data/lib/riddler/test_generator.rb +73 -0
- data/lib/riddler/use_cases.rb +7 -0
- data/lib/riddler/use_cases/admin_preview_step.rb +32 -0
- data/lib/riddler/use_cases/complete_interaction.rb +20 -0
- data/lib/riddler/use_cases/dismiss_interaction.rb +20 -0
- data/lib/riddler/use_cases/preview_context.rb +28 -0
- data/lib/riddler/use_cases/preview_step.rb +16 -5
- data/lib/riddler/use_cases/show_content_definition.rb +42 -0
- data/lib/riddler/use_cases/show_slug.rb +138 -0
- data/lib/riddler/version.rb +1 -1
- data/riddler.gemspec +12 -8
- metadata +100 -10
- data/.gitignore +0 -8
- data/.travis.yml +0 -7
- data/Gemfile +0 -6
- data/Gemfile.lock +0 -58
- data/Rakefile +0 -10
- data/bin/console +0 -14
- data/bin/setup +0 -8
@@ -0,0 +1,29 @@
|
|
1
|
+
module Riddler
|
2
|
+
module Drops
|
3
|
+
|
4
|
+
class HashDrop < ::Liquid::Drop
|
5
|
+
attr_reader :hash
|
6
|
+
|
7
|
+
def initialize hash
|
8
|
+
@hash = Hash[ hash.map { |k,v| [k.to_s, v] } ]
|
9
|
+
end
|
10
|
+
|
11
|
+
def []= key, value
|
12
|
+
@hash[key.to_s] = value
|
13
|
+
end
|
14
|
+
|
15
|
+
def liquid_method_missing method
|
16
|
+
@hash[method]
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_hash
|
20
|
+
hash
|
21
|
+
end
|
22
|
+
|
23
|
+
def method_missing method, *_args
|
24
|
+
liquid_method_missing method.to_s
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
data/lib/riddler/element.rb
CHANGED
@@ -1,14 +1,22 @@
|
|
1
1
|
module Riddler
|
2
|
-
|
3
2
|
class Element
|
3
|
+
include ::Riddler::Includeable
|
4
|
+
|
4
5
|
attr_reader :definition, :context
|
5
6
|
|
7
|
+
def self.subclasses
|
8
|
+
@@subclasses ||= []
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.inherited subclass
|
12
|
+
self.subclasses << subclass
|
13
|
+
end
|
14
|
+
|
6
15
|
def self.for definition, context
|
7
|
-
|
8
|
-
element_type = definition["object"]
|
16
|
+
element_type = definition["type"]
|
9
17
|
|
10
18
|
# Maybe this should be a registry
|
11
|
-
klass = subclasses.detect { |
|
19
|
+
klass = subclasses.detect { |k| k.type == element_type }
|
12
20
|
|
13
21
|
klass.new definition, context
|
14
22
|
end
|
@@ -18,20 +26,13 @@ module Riddler
|
|
18
26
|
@context = context
|
19
27
|
end
|
20
28
|
|
21
|
-
#def id
|
22
|
-
# definition["id"]
|
23
|
-
#end
|
24
|
-
|
25
|
-
#def type
|
26
|
-
# self.class.type
|
27
|
-
#end
|
28
|
-
|
29
29
|
def to_hash
|
30
30
|
{
|
31
|
+
content_type: "element",
|
31
32
|
type: self.class.type,
|
32
|
-
id: definition["id"]
|
33
|
+
id: definition["id"],
|
34
|
+
name: definition["name"]
|
33
35
|
}
|
34
36
|
end
|
35
37
|
end
|
36
|
-
|
37
38
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Riddler
|
2
|
+
module Elements
|
3
|
+
class Image < ::Riddler::Element
|
4
|
+
def self.type
|
5
|
+
"image"
|
6
|
+
end
|
7
|
+
|
8
|
+
def src
|
9
|
+
context.render definition["src"]
|
10
|
+
end
|
11
|
+
|
12
|
+
def alt
|
13
|
+
context.render definition["alt"]
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_hash
|
17
|
+
super.merge alt: alt, src: src
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Riddler
|
2
|
+
module Elements
|
3
|
+
class Link < ::Riddler::Element
|
4
|
+
def self.type
|
5
|
+
"link"
|
6
|
+
end
|
7
|
+
|
8
|
+
def href
|
9
|
+
@href ||= context.render definition["href"]
|
10
|
+
end
|
11
|
+
|
12
|
+
def link
|
13
|
+
return href if context.variable(:interaction).nil?
|
14
|
+
"/interactions/%s/redirect?element_id=%s&url=%s" % [
|
15
|
+
context.interaction.id,
|
16
|
+
definition["id"],
|
17
|
+
href
|
18
|
+
]
|
19
|
+
end
|
20
|
+
|
21
|
+
def text
|
22
|
+
context.render definition["text"]
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_hash
|
26
|
+
super.merge text: text, href: href, link: link
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Riddler
|
2
|
+
module Elements
|
3
|
+
class Varient < ::Riddler::Element
|
4
|
+
def self.type
|
5
|
+
"variant"
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_hash
|
9
|
+
included_element.to_hash
|
10
|
+
end
|
11
|
+
|
12
|
+
def included_element
|
13
|
+
definition["elements"]
|
14
|
+
.map do |hash|
|
15
|
+
::Riddler::Element.for hash, context
|
16
|
+
end
|
17
|
+
.detect(&:include?)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Riddler
|
2
|
+
module Includeable
|
3
|
+
def include?
|
4
|
+
return true unless has_include_predicate?
|
5
|
+
Predicator.evaluate include_predicate, context.to_liquid
|
6
|
+
end
|
7
|
+
|
8
|
+
def include_predicate
|
9
|
+
definition["include_predicate"]
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def has_include_predicate?
|
15
|
+
definition.key? "include_predicate" and
|
16
|
+
definition["include_predicate"].to_s.strip != ""
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
syntax = "proto3";
|
2
|
+
|
3
|
+
package riddler.protobuf;
|
4
|
+
|
5
|
+
import "google/protobuf/timestamp.proto";
|
6
|
+
|
7
|
+
/*
|
8
|
+
ContentDefinition is one of the outputs of the RiddlerAdmin app. After an admin
|
9
|
+
user has created a piece of content - it must first be approved. Once approved
|
10
|
+
it can then be published which will create the ContentDefinition in the remote
|
11
|
+
Riddler service. ContentDefinitions CAN NOT be modified. When changes are needed - a
|
12
|
+
new ContentDefinition (with a bumped version) will be created.
|
13
|
+
*/
|
14
|
+
message ContentDefinition {
|
15
|
+
string id = 1;
|
16
|
+
google.protobuf.Timestamp created_at = 2;
|
17
|
+
|
18
|
+
// Type of content: STEP
|
19
|
+
ContentType content_type = 3;
|
20
|
+
|
21
|
+
// ID of the content: st_12345
|
22
|
+
string content_id = 4;
|
23
|
+
|
24
|
+
// Version of the content. Starts at 1 and increments with each new definition
|
25
|
+
int32 version = 5;
|
26
|
+
|
27
|
+
// Title of the content: User Research Prompt
|
28
|
+
string title = 6;
|
29
|
+
|
30
|
+
// Description of the version: Adds updated images
|
31
|
+
string description = 7;
|
32
|
+
|
33
|
+
// Schema version of the definition
|
34
|
+
// The format and structure of a ContentDefinition may change over time
|
35
|
+
int32 definition_schema_version = 8;
|
36
|
+
|
37
|
+
/*
|
38
|
+
The opaque definition string generated by the admin tool (contains the
|
39
|
+
structure, predicates, liquid templates, ...). This is a snapshot of models
|
40
|
+
which belong to the admin tool.
|
41
|
+
*/
|
42
|
+
oneof definition {
|
43
|
+
string definition_string = 9;
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
enum ContentType {
|
48
|
+
UNKNOWN_CONTENT_TYPE = 0;
|
49
|
+
STEP = 1;
|
50
|
+
ELEMENT = 2;
|
51
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
2
|
+
# source: riddler/protobuf/content_definition.proto
|
3
|
+
|
4
|
+
require 'google/protobuf'
|
5
|
+
|
6
|
+
require 'google/protobuf/timestamp_pb'
|
7
|
+
Google::Protobuf::DescriptorPool.generated_pool.build do
|
8
|
+
add_message "riddler.protobuf.ContentDefinition" do
|
9
|
+
optional :id, :string, 1
|
10
|
+
optional :created_at, :message, 2, "google.protobuf.Timestamp"
|
11
|
+
optional :content_type, :enum, 3, "riddler.protobuf.ContentType"
|
12
|
+
optional :content_id, :string, 4
|
13
|
+
optional :version, :int32, 5
|
14
|
+
optional :title, :string, 6
|
15
|
+
optional :description, :string, 7
|
16
|
+
optional :definition_schema_version, :int32, 8
|
17
|
+
oneof :definition do
|
18
|
+
optional :definition_string, :string, 9
|
19
|
+
end
|
20
|
+
end
|
21
|
+
add_enum "riddler.protobuf.ContentType" do
|
22
|
+
value :UNKNOWN_CONTENT_TYPE, 0
|
23
|
+
value :STEP, 1
|
24
|
+
value :ELEMENT, 2
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module Riddler
|
29
|
+
module Protobuf
|
30
|
+
ContentDefinition = Google::Protobuf::DescriptorPool.generated_pool.lookup("riddler.protobuf.ContentDefinition").msgclass
|
31
|
+
ContentType = Google::Protobuf::DescriptorPool.generated_pool.lookup("riddler.protobuf.ContentType").enummodule
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
syntax = "proto3";
|
2
|
+
|
3
|
+
package riddler.protobuf;
|
4
|
+
|
5
|
+
import "riddler/protobuf/content_definition.proto";
|
6
|
+
import "riddler/protobuf/slug.proto";
|
7
|
+
|
8
|
+
message CreateContentDefinitionRequest {
|
9
|
+
ContentDefinition content_definition = 1;
|
10
|
+
}
|
11
|
+
message CreateContentDefinitionResponse {}
|
12
|
+
|
13
|
+
message CreateSlugRequest {
|
14
|
+
Slug slug = 1;
|
15
|
+
}
|
16
|
+
message CreateSlugResponse {}
|
17
|
+
|
18
|
+
message UpdateSlugRequest {
|
19
|
+
Slug slug = 1;
|
20
|
+
}
|
21
|
+
message UpdateSlugResponse {}
|
22
|
+
|
23
|
+
message GetSlugStatsRequest {
|
24
|
+
Slug slug = 1;
|
25
|
+
}
|
26
|
+
message GetSlugStatsResponse {
|
27
|
+
repeated SlugStats slug_stats = 1;
|
28
|
+
}
|
29
|
+
|
30
|
+
service ContentManagement {
|
31
|
+
rpc CreateContentDefinition(CreateContentDefinitionRequest) returns (CreateContentDefinitionResponse) {}
|
32
|
+
rpc CreateSlug(CreateSlugRequest) returns (CreateSlugResponse) {}
|
33
|
+
rpc UpdateSlug(UpdateSlugRequest) returns (UpdateSlugResponse) {}
|
34
|
+
rpc GetSlugStats(GetSlugStatsRequest) returns (GetSlugStatsResponse) {}
|
35
|
+
}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
2
|
+
# source: riddler/protobuf/content_management.proto
|
3
|
+
|
4
|
+
require 'google/protobuf'
|
5
|
+
|
6
|
+
require 'riddler/protobuf/content_definition_pb'
|
7
|
+
require 'riddler/protobuf/slug_pb'
|
8
|
+
Google::Protobuf::DescriptorPool.generated_pool.build do
|
9
|
+
add_message "riddler.protobuf.CreateContentDefinitionRequest" do
|
10
|
+
optional :content_definition, :message, 1, "riddler.protobuf.ContentDefinition"
|
11
|
+
end
|
12
|
+
add_message "riddler.protobuf.CreateContentDefinitionResponse" do
|
13
|
+
end
|
14
|
+
add_message "riddler.protobuf.CreateSlugRequest" do
|
15
|
+
optional :slug, :message, 1, "riddler.protobuf.Slug"
|
16
|
+
end
|
17
|
+
add_message "riddler.protobuf.CreateSlugResponse" do
|
18
|
+
end
|
19
|
+
add_message "riddler.protobuf.UpdateSlugRequest" do
|
20
|
+
optional :slug, :message, 1, "riddler.protobuf.Slug"
|
21
|
+
end
|
22
|
+
add_message "riddler.protobuf.UpdateSlugResponse" do
|
23
|
+
end
|
24
|
+
add_message "riddler.protobuf.GetSlugStatsRequest" do
|
25
|
+
optional :slug, :message, 1, "riddler.protobuf.Slug"
|
26
|
+
end
|
27
|
+
add_message "riddler.protobuf.GetSlugStatsResponse" do
|
28
|
+
repeated :slug_stats, :message, 1, "riddler.protobuf.SlugStats"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module Riddler
|
33
|
+
module Protobuf
|
34
|
+
CreateContentDefinitionRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("riddler.protobuf.CreateContentDefinitionRequest").msgclass
|
35
|
+
CreateContentDefinitionResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("riddler.protobuf.CreateContentDefinitionResponse").msgclass
|
36
|
+
CreateSlugRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("riddler.protobuf.CreateSlugRequest").msgclass
|
37
|
+
CreateSlugResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("riddler.protobuf.CreateSlugResponse").msgclass
|
38
|
+
UpdateSlugRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("riddler.protobuf.UpdateSlugRequest").msgclass
|
39
|
+
UpdateSlugResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("riddler.protobuf.UpdateSlugResponse").msgclass
|
40
|
+
GetSlugStatsRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("riddler.protobuf.GetSlugStatsRequest").msgclass
|
41
|
+
GetSlugStatsResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("riddler.protobuf.GetSlugStatsResponse").msgclass
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
2
|
+
# Source: riddler/protobuf/content_management.proto for package 'riddler.protobuf'
|
3
|
+
|
4
|
+
require 'grpc'
|
5
|
+
require 'riddler/protobuf/content_management_pb'
|
6
|
+
|
7
|
+
module Riddler
|
8
|
+
module Protobuf
|
9
|
+
module ContentManagement
|
10
|
+
class Service
|
11
|
+
|
12
|
+
include GRPC::GenericService
|
13
|
+
|
14
|
+
self.marshal_class_method = :encode
|
15
|
+
self.unmarshal_class_method = :decode
|
16
|
+
self.service_name = 'riddler.protobuf.ContentManagement'
|
17
|
+
|
18
|
+
rpc :CreateContentDefinition, CreateContentDefinitionRequest, CreateContentDefinitionResponse
|
19
|
+
rpc :CreateSlug, CreateSlugRequest, CreateSlugResponse
|
20
|
+
rpc :UpdateSlug, UpdateSlugRequest, UpdateSlugResponse
|
21
|
+
rpc :GetSlugStats, GetSlugStatsRequest, GetSlugStatsResponse
|
22
|
+
end
|
23
|
+
|
24
|
+
Stub = Service.rpc_stub_class
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
syntax = "proto3";
|
2
|
+
|
3
|
+
package riddler.protobuf;
|
4
|
+
|
5
|
+
import "google/protobuf/timestamp.proto";
|
6
|
+
|
7
|
+
/*
|
8
|
+
Slug is one of the outputs of the RiddlerAdmin app.
|
9
|
+
It maps a URL slug to a specific ContentDefinition and allows for
|
10
|
+
control of if it is available (status) as well as a targeting predicate.
|
11
|
+
Changes to Slugs do NOT need to go through compliance approval (as they don't
|
12
|
+
allow for modification of content).
|
13
|
+
*/
|
14
|
+
message Slug {
|
15
|
+
string id = 1;
|
16
|
+
google.protobuf.Timestamp created_at = 2;
|
17
|
+
google.protobuf.Timestamp updated_at = 3;
|
18
|
+
|
19
|
+
// The URL slug used to access content: user_research_prompt
|
20
|
+
string name = 4;
|
21
|
+
|
22
|
+
// LIVE or PAUSED
|
23
|
+
SlugStatus status = 5;
|
24
|
+
|
25
|
+
// ContentDefinition to be displayed
|
26
|
+
string content_definition_id = 6;
|
27
|
+
|
28
|
+
// Liquid template to define if an interaction should be reused
|
29
|
+
string interaction_identity = 7;
|
30
|
+
|
31
|
+
// Predicate to evaluate if the content should be shown
|
32
|
+
string target_predicate = 8;
|
33
|
+
}
|
34
|
+
|
35
|
+
enum SlugStatus {
|
36
|
+
UNKNOWN_SLUG_STATUS = 0;
|
37
|
+
LIVE = 1;
|
38
|
+
PAUSED = 2;
|
39
|
+
}
|
40
|
+
|
41
|
+
enum Interval {
|
42
|
+
UNKNOWN_INTERVAL = 0;
|
43
|
+
SECOND = 1;
|
44
|
+
MINUTE = 2;
|
45
|
+
HOUR = 3;
|
46
|
+
DAY = 4;
|
47
|
+
WEEK = 5;
|
48
|
+
MONTH = 6;
|
49
|
+
QUARTER = 7;
|
50
|
+
YEAR = 8;
|
51
|
+
}
|
52
|
+
|
53
|
+
message EventCount {
|
54
|
+
string event_name = 1;
|
55
|
+
int32 count = 2;
|
56
|
+
}
|
57
|
+
|
58
|
+
message SlugStats {
|
59
|
+
Interval interval = 1;
|
60
|
+
repeated EventCount event_counts = 2;
|
61
|
+
}
|