bianchi 0.1.1 → 0.1.3
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/.github/workflows/ci.yml +45 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +2 -0
- data/.vscode/settings.json +5 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +14 -10
- data/README.md +9 -10
- data/bianchi.gemspec +5 -1
- data/lib/bianchi/cli/main.rb +4 -2
- data/lib/bianchi/ussd/engine.rb +1 -4
- data/lib/bianchi/ussd/{errors.rb → exceptions.rb} +2 -0
- data/lib/bianchi/ussd/page.rb +11 -0
- data/lib/bianchi/ussd/page_delegators.rb +2 -0
- data/lib/bianchi/ussd/provider_configurations.rb +5 -2
- data/lib/bianchi/ussd/provider_parsers/africastalking.rb +3 -1
- data/lib/bianchi/ussd/provider_parsers/appsnmobile.rb +51 -0
- data/lib/bianchi/ussd/store.rb +7 -1
- data/lib/bianchi/version.rb +1 -1
- data/lib/bianchi.rb +2 -1
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d0a4841767acc10455e325dee277cf81119914192754b2da010b99626850986
|
4
|
+
data.tar.gz: 544c49afaa014e0163d86730b5338ead295ddd1f02bf6364aaa480d4a1da38f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 993ad14fd38daaf4ee9cf0d55f2450111675195d778c92c4663edff75f8f657cbcb816837bb41ec3ad75b7256e0a6e800b051808c46a0224f3d54cfea16f22e7
|
7
|
+
data.tar.gz: 183c4fbd9c4113c4bf6fcc399e119f1e4f54f5a39b24a220dca9ce8c8fdec81195f0c802e002b36f2e2998b3fd1bfe8b0aa081ac3e88b30d823d5f78a2037e3e
|
@@ -0,0 +1,45 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- '*'
|
7
|
+
pull_request:
|
8
|
+
branches:
|
9
|
+
- main
|
10
|
+
|
11
|
+
jobs:
|
12
|
+
rubocop:
|
13
|
+
runs-on: ubuntu-latest
|
14
|
+
|
15
|
+
services:
|
16
|
+
redis:
|
17
|
+
image: redis
|
18
|
+
ports:
|
19
|
+
- 6379:6379
|
20
|
+
options: --entrypoint redis-server
|
21
|
+
|
22
|
+
steps:
|
23
|
+
- name: Checkout code
|
24
|
+
uses: actions/checkout@v4.1.1
|
25
|
+
|
26
|
+
- name: Set up Ruby
|
27
|
+
uses: ruby/setup-ruby@v1.171.0
|
28
|
+
with:
|
29
|
+
ruby-version: 3.0
|
30
|
+
|
31
|
+
- name: Install dependencies
|
32
|
+
run: |
|
33
|
+
gem install bundler
|
34
|
+
bundle install
|
35
|
+
|
36
|
+
- name: Run RuboCop
|
37
|
+
run: bundle exec rubocop
|
38
|
+
|
39
|
+
- name: Start Redis
|
40
|
+
run: docker ps -a
|
41
|
+
|
42
|
+
- name: Run RSpec tests
|
43
|
+
env:
|
44
|
+
REDIS_URL: redis://localhost:6379
|
45
|
+
run: bundle exec rspec
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
bianchi (0.1.
|
4
|
+
bianchi (0.1.2)
|
5
5
|
activesupport
|
6
6
|
json
|
7
7
|
redis
|
@@ -32,10 +32,11 @@ GEM
|
|
32
32
|
i18n (1.14.1)
|
33
33
|
concurrent-ruby (~> 1.0)
|
34
34
|
json (2.7.1)
|
35
|
+
language_server-protocol (3.17.0.3)
|
35
36
|
minitest (5.21.2)
|
36
37
|
mutex_m (0.2.0)
|
37
38
|
parallel (1.24.0)
|
38
|
-
parser (3.3.0.
|
39
|
+
parser (3.3.0.5)
|
39
40
|
ast (~> 2.4.1)
|
40
41
|
racc
|
41
42
|
racc (1.7.3)
|
@@ -60,15 +61,17 @@ GEM
|
|
60
61
|
diff-lcs (>= 1.2.0, < 2.0)
|
61
62
|
rspec-support (~> 3.12.0)
|
62
63
|
rspec-support (3.12.1)
|
63
|
-
rubocop (
|
64
|
+
rubocop (1.60.2)
|
65
|
+
json (~> 2.3)
|
66
|
+
language_server-protocol (>= 3.17.0)
|
64
67
|
parallel (~> 1.10)
|
65
|
-
parser (>=
|
68
|
+
parser (>= 3.3.0.2)
|
66
69
|
rainbow (>= 2.2.2, < 4.0)
|
67
|
-
regexp_parser (>= 1.8)
|
68
|
-
rexml
|
69
|
-
rubocop-ast (>=
|
70
|
+
regexp_parser (>= 1.8, < 3.0)
|
71
|
+
rexml (>= 3.2.5, < 4.0)
|
72
|
+
rubocop-ast (>= 1.30.0, < 2.0)
|
70
73
|
ruby-progressbar (~> 1.7)
|
71
|
-
unicode-display_width (>=
|
74
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
72
75
|
rubocop-ast (1.30.0)
|
73
76
|
parser (>= 3.2.1.0)
|
74
77
|
ruby-progressbar (1.13.0)
|
@@ -76,9 +79,10 @@ GEM
|
|
76
79
|
thor (1.3.0)
|
77
80
|
tzinfo (2.0.6)
|
78
81
|
concurrent-ruby (~> 1.0)
|
79
|
-
unicode-display_width (
|
82
|
+
unicode-display_width (2.5.0)
|
80
83
|
|
81
84
|
PLATFORMS
|
85
|
+
arm64-darwin-22
|
82
86
|
x86_64-darwin-23
|
83
87
|
|
84
88
|
DEPENDENCIES
|
@@ -86,7 +90,7 @@ DEPENDENCIES
|
|
86
90
|
byebug
|
87
91
|
rake (~> 13.0)
|
88
92
|
rspec (~> 3.0)
|
89
|
-
rubocop (~>
|
93
|
+
rubocop (~> 1.60, >= 1.60.2)
|
90
94
|
|
91
95
|
BUNDLED WITH
|
92
96
|
2.2.3
|
data/README.md
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# Bianchi
|
2
2
|
A DSL (Domain-Specific Language) and a minimalist framework in Ruby, tailored for USSD development. Structured around a menu page approach, Bianchi offers a comprehensive suite of methods and generators, streamlining the process of building USSD applications efficiently and easily.
|
3
|
+
A basic test run with bianchi can be found here https://github.com/SydDaps/sinatra_bianchi_example
|
3
4
|
|
4
5
|
## Installation
|
5
|
-
Add `gem 'bianchi', '~> 0.1.
|
6
|
+
Add `gem 'bianchi', '~> 0.1.1'` to your gem file and run `bundle install`
|
6
7
|
|
7
|
-
Bianchi relies on Redis and requires the `REDIS_URL` environment variable to be set, pointing to your Redis instance. Ensure Redis is installed, running, and that REDIS_URL is correctly configured before using Bianchi.
|
8
|
+
Bianchi relies on Redis and requires the `REDIS_URL` environment variable to be set, pointing to your Redis instance. Ensure Redis is installed, and running, and that REDIS_URL is correctly configured before using Bianchi.
|
8
9
|
|
9
10
|
## Getting Started
|
10
11
|
|
@@ -14,7 +15,7 @@ To initialize a new USSD project, generate a project directory using Bianchi's c
|
|
14
15
|
bundle exec bianchi setup -p provider_name
|
15
16
|
```
|
16
17
|
|
17
|
-
Replace `provider_name` with your desired provider. Currently supported providers include:
|
18
|
+
Replace `provider_name` with your desired provider. Currently supported providers include: africastalking.
|
18
19
|
|
19
20
|
This command creates a `ussd/engine.rb` file in the project root directory. Here's a sample content of `ussd/engine.rb`:
|
20
21
|
|
@@ -22,7 +23,7 @@ This command creates a `ussd/engine.rb` file in the project root directory. Here
|
|
22
23
|
module USSD
|
23
24
|
class Engine
|
24
25
|
def self.start(params)
|
25
|
-
Bianchi::USSD::Engine.start(params, provider: :
|
26
|
+
Bianchi::USSD::Engine.start(params, provider: :africastalking) do
|
26
27
|
# e.g menu :main, options
|
27
28
|
end
|
28
29
|
end
|
@@ -52,11 +53,9 @@ This creates a `ussd/main_menu/page_1` file in the project root directory. Here'
|
|
52
53
|
module USSD
|
53
54
|
module MainMenu
|
54
55
|
class Page1 < Bianchi::USSD::Page
|
55
|
-
def request
|
56
|
-
end
|
56
|
+
def request; end
|
57
57
|
|
58
|
-
def response
|
59
|
-
end
|
58
|
+
def response; end
|
60
59
|
end
|
61
60
|
end
|
62
61
|
end
|
@@ -183,8 +182,8 @@ Here's an example of how you can retrieve the provider prompt data in your USSD
|
|
183
182
|
module USSD
|
184
183
|
class Engine
|
185
184
|
def self.start(params)
|
186
|
-
Bianchi::USSD::Engine.start(params, provider: :
|
187
|
-
menu :main,
|
185
|
+
Bianchi::USSD::Engine.start(params, provider: :africastalking) do
|
186
|
+
menu :main, initial: true
|
188
187
|
menu :greetings
|
189
188
|
menu :repeat
|
190
189
|
end
|
data/bianchi.gemspec
CHANGED
@@ -8,7 +8,10 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ["Dapilah Sydney"]
|
9
9
|
spec.email = ["dapilah.sydney@gmail.com"]
|
10
10
|
|
11
|
-
spec.summary =
|
11
|
+
spec.summary = <<~MSG
|
12
|
+
A DSL (Domain-Specific Language) and a minimalist framework in Ruby, tailored for USSD development.
|
13
|
+
MSG
|
14
|
+
|
12
15
|
spec.homepage = "https://github.com/SydDaps/Bianchi"
|
13
16
|
spec.license = "MIT"
|
14
17
|
spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0")
|
@@ -34,4 +37,5 @@ Gem::Specification.new do |spec|
|
|
34
37
|
spec.add_dependency "json"
|
35
38
|
spec.add_dependency "redis"
|
36
39
|
spec.add_dependency "thor"
|
40
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
37
41
|
end
|
data/lib/bianchi/cli/main.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rubocop:disable Metrics/ParameterLists
|
3
4
|
module Bianchi
|
4
5
|
module Cli
|
5
6
|
class Main < Thor
|
@@ -19,7 +20,7 @@ module Bianchi
|
|
19
20
|
desc "setup", "sets up a new ussd project"
|
20
21
|
long_desc <<-LONG_DESC
|
21
22
|
Usage: bianchi setup optional(-p|--provider)
|
22
|
-
\x5 Providers: [:africa_is_talking]
|
23
|
+
\x5 Providers: [:africa_is_talking, :appsnmobile]
|
23
24
|
\x5 Example: `bianchi setup`
|
24
25
|
\x5 Example: `bianchi setup -p :africa_is_talking`
|
25
26
|
|
@@ -27,7 +28,7 @@ module Bianchi
|
|
27
28
|
method_option :provider, aliases: "-p", type: :string, desc: "Set up ussd project for provider"
|
28
29
|
def setup
|
29
30
|
@provider = options[:provider]
|
30
|
-
unless %w[africastalking none].include? @provider
|
31
|
+
unless %w[africastalking none appsnmobile].include? @provider
|
31
32
|
say("Error: provider #{@provider} is not yet configured.", :yellow)
|
32
33
|
exit(1)
|
33
34
|
end
|
@@ -62,3 +63,4 @@ module Bianchi
|
|
62
63
|
end
|
63
64
|
end
|
64
65
|
end
|
66
|
+
# rubocop:enable Metrics/ParameterLists
|
data/lib/bianchi/ussd/engine.rb
CHANGED
@@ -110,10 +110,7 @@ module Bianchi
|
|
110
110
|
"#{constant_name} is supposed to be defined to process #{session.menu.name} menu #{page_number}"
|
111
111
|
end
|
112
112
|
|
113
|
-
page.
|
114
|
-
p.ensure_methods_defined(%i[request response])
|
115
|
-
p.send(action)
|
116
|
-
end
|
113
|
+
page.call(session, action)
|
117
114
|
end
|
118
115
|
end
|
119
116
|
end
|
data/lib/bianchi/ussd/page.rb
CHANGED
@@ -11,6 +11,15 @@ module Bianchi
|
|
11
11
|
@session = session
|
12
12
|
end
|
13
13
|
|
14
|
+
def self.call(session, action)
|
15
|
+
new(session).tap do |p|
|
16
|
+
p.ensure_methods_defined(%i[request response])
|
17
|
+
p.send(action)
|
18
|
+
rescue DispatchRenderException
|
19
|
+
p
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
14
23
|
def render(body, options = {})
|
15
24
|
raise ArgumentError, "render body expected to be a string" unless body.is_a? String
|
16
25
|
|
@@ -22,6 +31,8 @@ module Bianchi
|
|
22
31
|
s.page_number = self.class.name.split("::").last
|
23
32
|
s.store.track_session
|
24
33
|
end
|
34
|
+
|
35
|
+
raise DispatchRenderException
|
25
36
|
end
|
26
37
|
|
27
38
|
def load_page(page_number, menu_name)
|
@@ -4,11 +4,13 @@ module Bianchi
|
|
4
4
|
module USSD
|
5
5
|
module ProviderConfigurations
|
6
6
|
include ProviderParsers::Africastalking
|
7
|
+
include ProviderParsers::Appsnmobile
|
7
8
|
|
8
9
|
def parse_params(params)
|
9
10
|
provider_parsers = {
|
10
11
|
none: proc { params },
|
11
|
-
africastalking: proc { africastalking_params_parser(params) }
|
12
|
+
africastalking: proc { africastalking_params_parser(params) },
|
13
|
+
appsnmobile: proc { appsnmobile_params_parser(params) }
|
12
14
|
}.with_indifferent_access
|
13
15
|
|
14
16
|
parser = provider_parsers[@provider]
|
@@ -21,7 +23,8 @@ module Bianchi
|
|
21
23
|
def parser_prompt_data(prompt_data)
|
22
24
|
provider_parsers = {
|
23
25
|
none: proc { prompt_data },
|
24
|
-
africastalking: proc { africastalking_prompt_data_parser(prompt_data) }
|
26
|
+
africastalking: proc { africastalking_prompt_data_parser(prompt_data) },
|
27
|
+
appsnmobile: proc { appsnmobile_prompt_data_parser(prompt_data) }
|
25
28
|
}.with_indifferent_access
|
26
29
|
|
27
30
|
parser = provider_parsers[@provider]
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bianchi
|
4
|
+
module USSD
|
5
|
+
module ProviderParsers
|
6
|
+
module Appsnmobile
|
7
|
+
def appsnmobile_params_parser(params)
|
8
|
+
required_params = %w[session_id msisdn msg_type ussd_body nw_code service_code]
|
9
|
+
left_required_params = required_params - params.keys.map(&:to_s)
|
10
|
+
|
11
|
+
unless left_required_params.empty?
|
12
|
+
raise ArgumentError, "#{left_required_params} required in params to start engine for provider #{@provider}"
|
13
|
+
end
|
14
|
+
|
15
|
+
{
|
16
|
+
session_id: params["session_id"],
|
17
|
+
mobile_number: params["msisdn"],
|
18
|
+
activity_state: return_activity_state(params["msg_type"]),
|
19
|
+
input_body: params["ussd_body"],
|
20
|
+
nw_code: params["nw_code"],
|
21
|
+
service_code: params["service_code"]
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
def appsnmobile_prompt_data_parser(prompt_data)
|
26
|
+
msg_type = prompt_data["activity_state"] == :await ? "1" : "2"
|
27
|
+
|
28
|
+
{
|
29
|
+
session_id: prompt_data["session_id"],
|
30
|
+
msisdn: prompt_data["mobile_number"],
|
31
|
+
msg_type: msg_type,
|
32
|
+
ussd_body: prompt_data["body"],
|
33
|
+
nw_code: prompt_data["nw_code"],
|
34
|
+
service_code: prompt_data["service_code"]
|
35
|
+
}.to_json
|
36
|
+
end
|
37
|
+
|
38
|
+
def return_activity_state(msg_type)
|
39
|
+
case msg_type
|
40
|
+
when "0"
|
41
|
+
"initial"
|
42
|
+
when "1"
|
43
|
+
"subsequent"
|
44
|
+
else
|
45
|
+
raise ArgumentError, "#{@provider} sent in an unknown message type or msg_type"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/bianchi/ussd/store.rb
CHANGED
@@ -6,7 +6,13 @@ module Bianchi
|
|
6
6
|
attr_reader :session
|
7
7
|
|
8
8
|
def initialize(session)
|
9
|
-
|
9
|
+
redis_url = ENV.fetch("REDIS_URL", nil)
|
10
|
+
unless redis_url.present?
|
11
|
+
raise ArgumentError,
|
12
|
+
"environment variable REDIS_URL required to track engine session."
|
13
|
+
end
|
14
|
+
|
15
|
+
@redis = Redis.new(url: redis_url)
|
10
16
|
@session = session
|
11
17
|
end
|
12
18
|
|
data/lib/bianchi/version.rb
CHANGED
data/lib/bianchi.rb
CHANGED
@@ -7,6 +7,7 @@ require "thor"
|
|
7
7
|
|
8
8
|
require_relative "bianchi/version"
|
9
9
|
require_relative "bianchi/ussd/provider_parsers/africastalking"
|
10
|
+
require_relative "bianchi/ussd/provider_parsers/appsnmobile"
|
10
11
|
require_relative "bianchi/ussd/provider_configurations"
|
11
12
|
require_relative "bianchi/ussd/engine"
|
12
13
|
require_relative "bianchi/ussd/menu"
|
@@ -14,7 +15,7 @@ require_relative "bianchi/ussd/session"
|
|
14
15
|
require_relative "bianchi/ussd/page_delegators"
|
15
16
|
require_relative "bianchi/ussd/page"
|
16
17
|
require_relative "bianchi/ussd/store"
|
17
|
-
require_relative "bianchi/ussd/
|
18
|
+
require_relative "bianchi/ussd/exceptions"
|
18
19
|
|
19
20
|
# cli
|
20
21
|
require "bianchi/cli/main"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bianchi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dapilah Sydney
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -74,9 +74,11 @@ executables:
|
|
74
74
|
extensions: []
|
75
75
|
extra_rdoc_files: []
|
76
76
|
files:
|
77
|
+
- ".github/workflows/ci.yml"
|
77
78
|
- ".gitignore"
|
78
79
|
- ".rspec"
|
79
80
|
- ".rubocop.yml"
|
81
|
+
- ".vscode/settings.json"
|
80
82
|
- CODE_OF_CONDUCT.md
|
81
83
|
- Gemfile
|
82
84
|
- Gemfile.lock
|
@@ -93,12 +95,13 @@ files:
|
|
93
95
|
- lib/bianchi/cli/templates/engine.erb
|
94
96
|
- lib/bianchi/cli/templates/page.erb
|
95
97
|
- lib/bianchi/ussd/engine.rb
|
96
|
-
- lib/bianchi/ussd/
|
98
|
+
- lib/bianchi/ussd/exceptions.rb
|
97
99
|
- lib/bianchi/ussd/menu.rb
|
98
100
|
- lib/bianchi/ussd/page.rb
|
99
101
|
- lib/bianchi/ussd/page_delegators.rb
|
100
102
|
- lib/bianchi/ussd/provider_configurations.rb
|
101
103
|
- lib/bianchi/ussd/provider_parsers/africastalking.rb
|
104
|
+
- lib/bianchi/ussd/provider_parsers/appsnmobile.rb
|
102
105
|
- lib/bianchi/ussd/session.rb
|
103
106
|
- lib/bianchi/ussd/store.rb
|
104
107
|
- lib/bianchi/version.rb
|
@@ -112,6 +115,7 @@ metadata:
|
|
112
115
|
homepage_uri: https://github.com/SydDaps/Bianchi
|
113
116
|
source_code_uri: https://github.com/SydDaps/Bianchi
|
114
117
|
changelog_uri: https://rubygems.org/
|
118
|
+
rubygems_mfa_required: 'true'
|
115
119
|
post_install_message:
|
116
120
|
rdoc_options: []
|
117
121
|
require_paths:
|
@@ -130,5 +134,6 @@ requirements: []
|
|
130
134
|
rubygems_version: 3.2.3
|
131
135
|
signing_key:
|
132
136
|
specification_version: 4
|
133
|
-
summary:
|
137
|
+
summary: A DSL (Domain-Specific Language) and a minimalist framework in Ruby, tailored
|
138
|
+
for USSD development.
|
134
139
|
test_files: []
|