rodbot 0.4.2 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 731572aaf37dd47b3ca8bdd234e9db1dca540f735fc6031af62a8794d45fd470
4
- data.tar.gz: e98a94ef370bd0845749b3182df742cf1870059c75b5abd60800c9643c8e3862
3
+ metadata.gz: 47f769ca6ea9ef12065fddf0efaf8a0269009654aef1a21fe156a92c07199844
4
+ data.tar.gz: 6c6fec74a830838687e797dabe1076ec800fddd7f1efb1ea8248a455b80a5819
5
5
  SHA512:
6
- metadata.gz: c36906cb429ac14617f8e3a80c28cd83620d4ede1d8b3f307f7e8b3f97915c60e8248aa72b1791f58fd32380473976b3286736b8a09fa321311925676cbe4f83
7
- data.tar.gz: ef71720cbd4852cc4198b43002757a73e4fcb15b11b5e64b6893477791c608b2e5cccd77a35db95fd4ab72bd1986fbf8c548e2c9ea5a65fa1f87a913e3402c6a
6
+ metadata.gz: 64dcb382753c7493bad70e24d4fe4e13c12b0388066f16dfc9c491a7d8869254f03d7b2000f910827f477a1a7eaf07e3b1088c46db13db91389bacc11316b25c
7
+ data.tar.gz: cce4048655798b61cfa1a3724b264ce4d739673771f4f957f5e7878fe469be871de0d28a7b1ab502abf9aefe57f2d8a08e1fcd0d0eb61438b9ca638db8eac3d7
checksums.yaml.gz.sig CHANGED
Binary file
@@ -6,7 +6,7 @@ jobs:
6
6
  fail-fast: false
7
7
  matrix:
8
8
  os: [ubuntu-latest]
9
- ruby: ['3.0', '3.1', '3.2']
9
+ ruby: ['3.0', '3.1', '3.2', '3.3']
10
10
  name: test (Ruby ${{ matrix.ruby }} on ${{ matrix.os }})
11
11
  runs-on: ${{ matrix.os }}
12
12
  steps:
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.2
1
+ 3.3
data/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  Nothing so far
4
4
 
5
+ ## 0.4.4
6
+
7
+ #### Changes
8
+ * Adhere to plugin file layout suggestions
9
+ * Support Ruby 3.3
10
+ * Honor `APP_ENV` as an alternative to `RODBOT_ENV`
11
+
12
+ ## 0.4.3
13
+
14
+ #### Changes
15
+ * Add more languages to the word of the day demo plugin
16
+
5
17
  ## 0.4.2
6
18
 
7
19
  #### Fixes
data/README.md CHANGED
@@ -17,21 +17,21 @@ Minimalistic yet polyglot framework to build chat bots on top of a Roda backend
17
17
 
18
18
  ## Table of Contents
19
19
 
20
- [Install](#label-Install) <br>
21
- [Anatomy](#label-Anatomy) <br>
22
- &emsp;&emsp;&emsp;[App Service](#label-App-Service) <br>
23
- &emsp;&emsp;&emsp;[Relay Services](#label-Relay-Services) <br>
24
- &emsp;&emsp;&emsp;[Schedule Service](#label-Schedule-Service) <br>
25
- [CLI](#label-CLI) <br>
20
+ [Install](#install) <br>
21
+ [Anatomy](#anatomy) <br>
22
+ &emsp;&emsp;&emsp;[App Service](#app-service) <br>
23
+ &emsp;&emsp;&emsp;[Relay Services](#relay-services) <br>
24
+ &emsp;&emsp;&emsp;[Schedule Service](#schedule-service) <br>
25
+ [CLI](#CLI) <br>
26
26
  [Request](#request)<br>
27
27
  [Say](#say)<br>
28
- [Routes and Commands](#label-Routes-and-Commands) <br>
29
- [Database](#label-Database) <br>
28
+ [Routes and Commands](#routes-and-commands) <br>
29
+ [Database](#database) <br>
30
30
  [Environments](#environments) <br>
31
31
  [Credentials](#credentials) <br>
32
- [Plugins](#label-Plugins) <br>
33
- [Environment Variables](#label-Environment-Variables) <br>
34
- [Development](#label-Development) <br>
32
+ [Plugins](#plugins) <br>
33
+ [Environment Variables](#environment-variables) <br>
34
+ [Development](#development) <br>
35
35
 
36
36
  ## Install
37
37
 
@@ -53,7 +53,7 @@ rodbot new my_bot
53
53
  cd my_bot
54
54
  ```
55
55
 
56
- For the bot to be useful at all, you should choose one of the supported [relay service plugins](#label-Plugins). Say, you'd like to interact via Matrix:
56
+ For the bot to be useful at all, you should choose one of the supported [relay service plugins](#plugins). Say, you'd like to interact via Matrix:
57
57
 
58
58
  ```
59
59
  bundle config set --local with matrix
@@ -137,7 +137,7 @@ It loads the following Roda plugins:
137
137
  * [unescape_path](http://roda.jeremyevans.net/rdoc/classes/Roda/RodaPlugins/UnescapePath.html)
138
138
  * [render](http://roda.jeremyevans.net/rdoc/classes/Roda/RodaPlugins/Render.html)
139
139
 
140
- It loads the following Roda extensions provided by Rodbot:
140
+ It also loads the following Roda extension provided by Rodbot:
141
141
 
142
142
  * Shortcut `r.arguments` for `r.params['arguments']`
143
143
 
@@ -159,7 +159,7 @@ port 12345
159
159
 
160
160
  #### Commands
161
161
 
162
- All top level GET requests such as `GET /foobar` are commands and therefore are accessible by relays, for instance using `!foobar` on Matrix.
162
+ All top level GET requests such as `GET /foobar` are commands and therefore accessible by relays, for instance using `!foobar` on Matrix.
163
163
 
164
164
  Responses have to be either of the following content types:
165
165
 
@@ -168,7 +168,7 @@ Responses have to be either of the following content types:
168
168
 
169
169
  Please note that the Markdown might get stripped on communication networks which feature only limited or no support for Markdown.
170
170
 
171
- The response may contain special tags which have to be replace appropriately by the corresponding **relay service**:
171
+ The response may contain special tags which have to be replaced appropriately by the corresponding **relay service**:
172
172
 
173
173
  Tag | Replaced with
174
174
  ----|--------------
@@ -468,6 +468,8 @@ Rodbot.env.production? # => true
468
468
  Rodbot.env.development? # => false
469
469
  ```
470
470
 
471
+ You can use the more generic alternative `APP_ENV` as well, however, if `RODBOT_ENV` is defined, it takes precedence over `APP_ENV`.
472
+
471
473
  ## Credentials
472
474
 
473
475
  In order not to commit secrets to repositories or environment variables, Rodbot bundles the [dry-credentials](https://rubygems.org/gems/dry-credentials) gem and exposes it via the `rodbot credentials` CLI command. The secrets are then available in your code like `Rodbot.credentials.my_secret` and the encrypted files are written to `config/credentials`.
@@ -481,11 +483,12 @@ Rodbot aims to keep its core small and add features via plugins, either built-in
481
483
  Name | Dependencies | Description
482
484
  -----|--------------|------------
483
485
  [:matrix](https://rubydoc.info/github/svoop/rodbot/file/lib/rodbot/plugins/matrix/README.matrix.md) | yes | relay service for the [Matrix communication network](https://matrix.org)
486
+ [:slack](https://rubydoc.info/github/svoop/rodbot/file/lib/rodbot/plugins/slack/README.slack.md) | yes | relay service for the [Slack communication network](https://slack.com)
484
487
  [:otp](https://rubydoc.info/github/svoop/rodbot/file/lib/rodbot/plugins/otp/README.otp.md) | yes | guard commands with one-time passwords
485
- [:gitlab_webhook](ttps://rubydoc.info/github/svoop/rodbot/file/lib/rodbot/plugins/gitlab_webhook/README.gitlab_webhook.md) | no | event announcements from [GitLab](https://gitlab.com)
486
- [:github_webhook](ttps://rubydoc.info/github/svoop/rodbot/file/lib/rodbot/plugins/github_webhook/README.github_webhook.md) | no | event announcements from [GitHub](https://github.com)
488
+ [:gitlab_webhook](https://rubydoc.info/github/svoop/rodbot/file/lib/rodbot/plugins/gitlab_webhook/README.gitlab_webhook.md) | no | event announcements from [GitLab](https://gitlab.com)
489
+ [:github_webhook](https://rubydoc.info/github/svoop/rodbot/file/lib/rodbot/plugins/github_webhook/README.github_webhook.md) | no | event announcements from [GitHub](https://github.com)
487
490
  [:hal](https://rubydoc.info/github/svoop/rodbot/file/lib/rodbot/plugins/hal/README.hal.md) | no | feel like Dave (demo)
488
- [:word_of_the_day](ttps://rubydoc.info/github/svoop/rodbot/file/lib/rodbot/plugins/word_of_the_day/README.word_of_the_day.md) | no | word of the day announcements (demo)
491
+ [:word_of_the_day](https://rubydoc.info/github/svoop/rodbot/file/lib/rodbot/plugins/word_of_the_day/README.word_of_the_day.md) | no | word of the day announcements (demo)
489
492
 
490
493
  You have to install the corresponding Bundler group in case the plugin depends on extra gems. Here's an example for the `:otp` plugin listed above:
491
494
 
@@ -601,7 +604,7 @@ end
601
604
 
602
605
  The `loops` method must returns an array of callables (e.g. a Proc or Method) which will be called when this relay service is started. The loops must trap the `INT` signal.
603
606
 
604
- Proactive messsages require other parts of Rodbot to forward a message directly. To do so, the relay has to implement a TCP socket. This socket must bind to the IP and port you get from the `bind` method which returns an array like `["localhost", 7201]`.
607
+ Proactive messages require other parts of Rodbot to forward a message directly. To do so, the relay has to implement a TCP socket. This socket must bind to the IP and port you get from the `bind` method which returns an array like `["localhost", 7201]`.
605
608
 
606
609
  For an example, take a look at the [:matrix plugin](https://github.com/svoop/rodbot/tree/main/lib/rodbot/plugins/matrix).
607
610
 
@@ -637,7 +640,7 @@ For an example, take a look at the [:word_of_the_day plugin](https://github.com/
637
640
 
638
641
  #### Toolbox
639
642
 
640
- Before you write a plugin, familiarize yourself with the following bundled helpers:
643
+ Before you write a plugin, familiarise yourself with the following bundled helpers:
641
644
 
642
645
  * [Rodbot::Refinements](https://www.rubydoc.info/gems/rodbot/Rodbot/Refinements.html) – just a few handy extensions to Ruby core classes
643
646
  * [Rodbot::Memoize](https://www.rubydoc.info/gems/rodbot/Rodbot/Memoize.html) – environment-aware memoization for method return values
@@ -0,0 +1 @@
1
+ 909cbacb1a78772d5da56bfb4f1ed391fd43e5c9d2abfb347332e7d5933b3cf1afc4ee11cb6fdc1cc5cb61e2f187d3e700f7a66648f8c1facd78201c68e553e2
@@ -0,0 +1 @@
1
+ 263a706d44c8776c413d3800b455249a7c75ed323dc27932ca57d589e13e7da68bc5eb6351beff4efc3cc0dec32d03d7d9c64ee68bfe739426a0f54eccac1229
data/lib/rodbot/env.rb CHANGED
@@ -27,7 +27,7 @@ module Rodbot
27
27
  @root = root ? Pathname(root).realpath : Pathname.pwd
28
28
  @tmp = @root.join('tmp')
29
29
  @gem = Pathname(__dir__).join('..', '..').realpath
30
- @current = ENV['RODBOT_ENV']
30
+ @current = ENV['RODBOT_ENV'] || ENV['APP_ENV']
31
31
  @current = 'development' unless ENVS.include? @current
32
32
  end
33
33
 
@@ -11,3 +11,30 @@ plugin :word_of_the_day do
11
11
  time '10:00'
12
12
  end
13
13
  ```
14
+
15
+ By default, the English word of the day from Merriam-Webster is used, but you can [select another language from Transparent](https://www.transparent.com/word-of-the-day/):
16
+
17
+ ```ruby
18
+ plugin :word_of_the_day do
19
+ time '10:00'
20
+ languages %w(French)
21
+ end
22
+ ```
23
+
24
+ You can also select more than one language:
25
+
26
+ ```ruby
27
+ plugin :word_of_the_day do
28
+ time '10:00'
29
+ languages %w(English French Swedish)
30
+ end
31
+ ```
32
+
33
+ Given the above, the word of the day for any given day might look something like this:
34
+
35
+ ```
36
+ Word of the day: foobar (English) / foobâr (French) / foobår (Swedish)
37
+ ```
38
+
39
+ In case the word of the day is not available, the message will contain the missing language struck through.
40
+
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'adapters/base'
4
+ require_relative 'adapters/merriam_webster'
5
+ require_relative 'adapters/transparent'
6
+
7
+ module WordOfTheDay
8
+ class Adapter
9
+ extend Forwardable
10
+
11
+ def_delegator :@adapter, :message, :message
12
+
13
+ def initialize(language)
14
+ @language = language
15
+ @adapter = (language == 'English' ? MerriamWebster : Transparent).new(language)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'httpx'
4
+
5
+ module WordOfTheDay
6
+ class Adapter
7
+ class Base
8
+ attr_reader :language
9
+
10
+ def initialize(language)
11
+ @language = language.downcase
12
+ end
13
+
14
+ def message
15
+ if word
16
+ "[#{word}](#{url}) (#{language.capitalize})"
17
+ else
18
+ "~~#{language.capitalize}~~"
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WordOfTheDay
4
+ class Adapter
5
+ class MerriamWebster < Base
6
+ private
7
+
8
+ def word
9
+ html.match(/<h2 class="word-header-txt">(.+?)</)&.captures&.first
10
+ end
11
+
12
+ def url
13
+ "https://www.merriam-webster.com/word-of-the-day/#{today}"
14
+ end
15
+
16
+ private
17
+
18
+ def today
19
+ Time.now.strftime('%F')
20
+ end
21
+
22
+ def html
23
+ case (response = HTTPX.get(url))
24
+ in { status: 200 } then response.body.to_s
25
+ else ''
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WordOfTheDay
4
+ class Adapter
5
+ class Transparent < Base
6
+ LANGUAGE_CODES = {
7
+ 'arabic' => 'ar',
8
+ 'chinese' => 'zh',
9
+ 'dutch' => 'nl',
10
+ 'esperanto' => 'esp',
11
+ 'french' => 'fr',
12
+ 'german' => 'de',
13
+ 'irish' => 'ga',
14
+ 'italian' => 'it',
15
+ 'japanese' => 'ja',
16
+ 'latin' => 'la',
17
+ 'polish' => 'pl',
18
+ 'portuguese' => 'pt',
19
+ 'russian' => 'ru',
20
+ 'spanish' => 'es'
21
+ }.freeze
22
+
23
+ def word
24
+ xml.match(/<word>(.+?)</)&.captures&.first
25
+ end
26
+
27
+ def url
28
+ "https://wotd.transparent.com/widget/?lang=#{language}&date=#{today}"
29
+ end
30
+
31
+ private
32
+
33
+ def today
34
+ Time.now.strftime('%m-%d-%Y')
35
+ end
36
+
37
+ def language_code
38
+ LANGUAGE_CODES.fetch(language, language)
39
+ end
40
+
41
+ def xml
42
+ xml_url = "https://wotd.transparent.com/rss/#{today}-#{language_code}-widget.xml"
43
+ case (response = HTTPX.get(xml_url))
44
+ in { status: 200 } then response.body.to_s
45
+ else ''
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -2,12 +2,14 @@
2
2
 
3
3
  require 'httpx'
4
4
 
5
+ require_relative 'lib/adapter'
6
+
5
7
  module Rodbot
6
8
  class Plugins
7
9
  class WordOfTheDay
8
10
  class Schedule
9
11
  def initialize
10
- Clockwork.every(1.day, -> { Rodbot.say message }, at: time)
12
+ Clockwork.every(1.day, -> { Rodbot.say "Word of the day: #{message}" }, at: time)
11
13
  end
12
14
 
13
15
  private
@@ -16,36 +18,15 @@ module Rodbot
16
18
  Rodbot.config(:plugin, :word_of_the_day, :time) || '12:00'
17
19
  end
18
20
 
19
- def message
20
- Rodbot::Plugins::WordOfTheDay::Today.new.message
21
- end
22
-
23
- end
24
-
25
- class Today
26
- def initialize
27
- @response = HTTPX.with(timeout: { request_timeout: 60 }).get('https://www.merriam-webster.com/word-of-the-day')
21
+ def languages
22
+ Rodbot.config(:plugin, :word_of_the_day, :languages) || %w(english)
28
23
  end
29
24
 
30
25
  def message
31
- if @response.status == 200
32
- "Word of the day: [#{word}](#{url})"
33
- else
34
- "Sorry, there was a problem fetching the word of the day."
35
- end
36
- end
37
-
38
- private
39
-
40
- def word
41
- @response.body.to_s.match(/<h2 class="word-header-txt">(.+?)</).captures.first
42
- end
43
-
44
- def url
45
- @response.body.to_s.match(/<meta property="og:url" content="(.+?)"/).captures.first
26
+ languages.map { ::WordOfTheDay::Adapter.new(_1).message }.compact.join(' / ')
46
27
  end
47
28
  end
48
-
49
29
  end
50
30
  end
51
31
  end
32
+
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
- VERSION = "0.4.2"
4
+ VERSION = "0.4.4"
5
5
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rodbot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Schwyn
@@ -27,7 +27,7 @@ cert_chain:
27
27
  k/QvZU05f6HMYBrPogJgIzHC/C5N/yeE4BVEuBDn+10Zb1iu3aDk8sd0uMgukCY8
28
28
  TUmlP5A6NeGdeDJIoLgromAKs+nvI7TWzhQq9ODs51XhxgUFRCvBqUTpjTQigw==
29
29
  -----END CERTIFICATE-----
30
- date: 2023-11-24 00:00:00.000000000 Z
30
+ date: 2024-02-12 00:00:00.000000000 Z
31
31
  dependencies:
32
32
  - !ruby/object:Gem::Dependency
33
33
  name: zeitwerk
@@ -455,6 +455,8 @@ files:
455
455
  - checksums/rodbot-0.4.0.gem.sha512
456
456
  - checksums/rodbot-0.4.1.gem.sha512
457
457
  - checksums/rodbot-0.4.2.gem.sha512
458
+ - checksums/rodbot-0.4.3.gem.sha512
459
+ - checksums/rodbot-0.4.4.gem.sha512
458
460
  - doc/rodbot.afphoto
459
461
  - doc/rodbot.avif
460
462
  - exe/rodbot
@@ -500,6 +502,10 @@ files:
500
502
  - lib/rodbot/plugins/slack/README.slack.md
501
503
  - lib/rodbot/plugins/slack/relay.rb
502
504
  - lib/rodbot/plugins/word_of_the_day/README.word_of_the_day.md
505
+ - lib/rodbot/plugins/word_of_the_day/lib/adapter.rb
506
+ - lib/rodbot/plugins/word_of_the_day/lib/adapters/base.rb
507
+ - lib/rodbot/plugins/word_of_the_day/lib/adapters/merriam_webster.rb
508
+ - lib/rodbot/plugins/word_of_the_day/lib/adapters/transparent.rb
503
509
  - lib/rodbot/plugins/word_of_the_day/schedule.rb
504
510
  - lib/rodbot/rack.rb
505
511
  - lib/rodbot/refinements.rb
@@ -574,7 +580,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
574
580
  - !ruby/object:Gem::Version
575
581
  version: '0'
576
582
  requirements: []
577
- rubygems_version: 3.4.22
583
+ rubygems_version: 3.5.6
578
584
  signing_key:
579
585
  specification_version: 4
580
586
  summary: Minimalistic framework to build chat bots on top of a Roda backend
metadata.gz.sig CHANGED
Binary file