rodbot 0.4.1 → 0.4.3

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: cfce379a5c8a1fa2b8ba390b25c5a3db58406aa2442edc9bb4c5b022bfabe40a
4
- data.tar.gz: 4b5ca31f1697ae81d9374b5ab9e0173ea37c391d4cd9e936c7a733b91b14439b
3
+ metadata.gz: 63507ad988e8bc39e627cfe154e6713be7e64026e50d222bafc828cb3063825b
4
+ data.tar.gz: cbb4dd2628412ea4b2672e4dfe1f313ff758124a07dfd41082f38e655d5a4ee7
5
5
  SHA512:
6
- metadata.gz: 7d8c5faff81fd9fc2f2552155fe1f29909d444c4b8321bbb8faf4b3889ab363a56991d68de88fc418b9418d3dbc587851cb0bd9134009ad0a9ee8321927ef668
7
- data.tar.gz: b668cbe4c688399f2d4f8bedd355268b4c24d05bfd74dfe50643c3ec93970ebc42c0e87a882135c580587e8badda7f5b9bb0d3a6fe51b478a9e40fa73c0f2124
6
+ metadata.gz: 0cb3f6d314ffedd6e8e25f33abb967a03837512f3ba35b0cc4d14746fa19ac8b491e53bb6653fa3d4f2a6158764fb377eaa7c94b625fa86b5294fc23f921f1e7
7
+ data.tar.gz: cd5d8bc13b3d52f40231b5bb57a0872b340e962caf062e5dab80167d2a5cc35afc57619d36359ebdf5bda133296a608ce603039759bd99e3d4a8ccb0bc6be6ed
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  Nothing so far
4
4
 
5
+ ## 0.4.3
6
+
7
+ #### Changes
8
+ * Add more languages to the word of the day demo plugin
9
+
10
+ ## 0.4.2
11
+
12
+ #### Fixes
13
+ * Pass the time zone down to Clockwork
14
+
5
15
  ## 0.4.1
6
16
 
7
17
  #### 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
  ----|--------------
@@ -211,7 +211,11 @@ The **schedule service** is a [Clockwork process](https://github.com/Rykian/cloc
211
211
 
212
212
  It's a good idea to have the **app service** do the heavy lifting while the schedule simply fires the corresponding HTTP request.
213
213
 
214
- A word on time zones since they are particularly important for schedules: Automatic discovery of the local time zone and DST status is rather unreliable. Therefore, Rodbot expects you to set the time zone in `config/rodbot.rb` using `time_zone`. See `ls /usr/share/zoneinfo` for valid values. To correctly handle DST, you should use geographical zones like `Europe/Paris` rather than technical zones like `CET`. If `time_zone` is not defined, the environment variable `TZ` is read instead. And if `TZ` isn't set neither, Rodbot falls back to `Etc/UTC`.
214
+ A word or two on time zones since they are particularly important for schedules:
215
+
216
+ Automatic discovery of the local time zone and DST status is rather unreliable. Therefore, Rodbot expects you to set the time zone in `config/rodbot.rb` using `time_zone`. See `ls /usr/share/zoneinfo` for valid values. To correctly handle DST, you should use geographical zones like `Europe/Paris` rather than technical zones like `CET`. If `time_zone` is not defined, the environment variable `TZ` is read instead. And if `TZ` isn't set neither, Rodbot falls back to `Etc/UTC`.
217
+
218
+ Also, make sure the [time zone data is available](https://tzinfo.github.io) where you deploy your bot to. The [official Alpine-based Ruby images](https://hub.docker.com/_/ruby) for instance doesn't come with it preinstalled, so you either have to `RUN apk add --no-cache tzdata` in the Dockerfile or add the [tzinfo-data gem](https://rubygems.org/gems/tzinfo-data) to the bundle for `TZ` to have any effect at all.
215
219
 
216
220
  ## CLI
217
221
 
@@ -478,10 +482,10 @@ Name | Dependencies | Description
478
482
  -----|--------------|------------
479
483
  [: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)
480
484
  [:otp](https://rubydoc.info/github/svoop/rodbot/file/lib/rodbot/plugins/otp/README.otp.md) | yes | guard commands with one-time passwords
481
- [: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)
482
- [: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)
485
+ [: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)
486
+ [: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)
483
487
  [:hal](https://rubydoc.info/github/svoop/rodbot/file/lib/rodbot/plugins/hal/README.hal.md) | no | feel like Dave (demo)
484
- [: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)
488
+ [: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)
485
489
 
486
490
  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:
487
491
 
@@ -597,7 +601,7 @@ end
597
601
 
598
602
  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.
599
603
 
600
- 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]`.
604
+ 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]`.
601
605
 
602
606
  For an example, take a look at the [:matrix plugin](https://github.com/svoop/rodbot/tree/main/lib/rodbot/plugins/matrix).
603
607
 
@@ -633,7 +637,7 @@ For an example, take a look at the [:word_of_the_day plugin](https://github.com/
633
637
 
634
638
  #### Toolbox
635
639
 
636
- Before you write a plugin, familiarize yourself with the following bundled helpers:
640
+ Before you write a plugin, familiarise yourself with the following bundled helpers:
637
641
 
638
642
  * [Rodbot::Refinements](https://www.rubydoc.info/gems/rodbot/Rodbot/Refinements.html) – just a few handy extensions to Ruby core classes
639
643
  * [Rodbot::Memoize](https://www.rubydoc.info/gems/rodbot/Rodbot/Memoize.html) – environment-aware memoization for method return values
@@ -0,0 +1 @@
1
+ f6c9c9fd62c5b0c22400fc958198c6d34b8d9b01242b8f7d028fe8622c8c2e8ba955fce7071e05ef0ea3a49e1559954856e21113b1a623c0efd7ed884400a4cc
@@ -0,0 +1 @@
1
+ 909cbacb1a78772d5da56bfb4f1ed391fd43e5c9d2abfb347332e7d5933b3cf1afc4ee11cb6fdc1cc5cb61e2f187d3e700f7a66648f8c1facd78201c68e553e2
@@ -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,22 @@
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 Rodbot
8
+ class Plugins
9
+ class WordOfTheDay
10
+ class Adapter
11
+ extend Forwardable
12
+
13
+ def_delegator :@adapter, :message, :message
14
+
15
+ def initialize(language)
16
+ @language = language
17
+ @adapter = (language == 'English' ? MerriamWebster : Transparent).new(language)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'httpx'
4
+
5
+ module Rodbot
6
+ class Plugins
7
+ class WordOfTheDay
8
+ class Adapter
9
+ class Base
10
+ attr_reader :language
11
+
12
+ def initialize(language)
13
+ @language = language.downcase
14
+ end
15
+
16
+ def message
17
+ if word
18
+ "[#{word}](#{url}) (#{language.capitalize})"
19
+ else
20
+ "~~#{language.capitalize}~~"
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rodbot
4
+ class Plugins
5
+ class WordOfTheDay
6
+ class Adapter
7
+ class MerriamWebster < Base
8
+ private
9
+
10
+ def word
11
+ html.match(/<h2 class="word-header-txt">(.+?)</)&.captures&.first
12
+ end
13
+
14
+ def url
15
+ "https://www.merriam-webster.com/word-of-the-day/#{today}"
16
+ end
17
+
18
+ private
19
+
20
+ def today
21
+ Time.now.strftime('%F')
22
+ end
23
+
24
+ def html
25
+ case (response = HTTPX.get(url))
26
+ in { status: 200 } then response.body.to_s
27
+ else ''
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rodbot
4
+ class Plugins
5
+ class WordOfTheDay
6
+ class Adapter
7
+ class Transparent < Base
8
+ LANGUAGE_CODES = {
9
+ 'arabic' => 'ar',
10
+ 'chinese' => 'zh',
11
+ 'dutch' => 'nl',
12
+ 'esperanto' => 'esp',
13
+ 'french' => 'fr',
14
+ 'german' => 'de',
15
+ 'irish' => 'ga',
16
+ 'italian' => 'it',
17
+ 'japanese' => 'ja',
18
+ 'latin' => 'la',
19
+ 'polish' => 'pl',
20
+ 'portuguese' => 'pt',
21
+ 'russian' => 'ru',
22
+ 'spanish' => 'es'
23
+ }.freeze
24
+
25
+ def word
26
+ xml.match(/<word>(.+?)</)&.captures&.first
27
+ end
28
+
29
+ def url
30
+ "https://wotd.transparent.com/widget/?lang=#{language}&date=#{today}"
31
+ end
32
+
33
+ private
34
+
35
+ def today
36
+ Time.now.strftime('%m-%d-%Y')
37
+ end
38
+
39
+ def language_code
40
+ LANGUAGE_CODES.fetch(language, language)
41
+ end
42
+
43
+ def xml
44
+ xml_url = "https://wotd.transparent.com/rss/#{today}-#{language_code}-widget.xml"
45
+ case (response = HTTPX.get(xml_url))
46
+ in { status: 200 } then response.body.to_s
47
+ else ''
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -2,12 +2,14 @@
2
2
 
3
3
  require 'httpx'
4
4
 
5
+ require_relative '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 { Adapter.new(_1).message }.compact.join(' / ')
46
27
  end
47
28
  end
48
-
49
29
  end
50
30
  end
51
31
  end
32
+
@@ -16,7 +16,10 @@ module Rodbot
16
16
 
17
17
  def run
18
18
  Clockwork.instance_eval do
19
- configure { _1[:logger] = Rodbot::Log.logger('schedule') }
19
+ configure do |config|
20
+ config[:tz] = Rodbot.config[:time_zone]
21
+ config[:logger] = Rodbot::Log.logger('schedule')
22
+ end
20
23
  handler { Rodbot::Async.perform(&_1) }
21
24
  end
22
25
  Rodbot.plugins.extend_schedule
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
- VERSION = "0.4.1"
4
+ VERSION = "0.4.3"
5
5
  end
data.tar.gz.sig CHANGED
@@ -1 +1,3 @@
1
- n�D��J?]T����H`�ƭ���{H��6h��ߊZ]k&��]�������Y �B]gB׍l7+��NJ׫�F��TvO �M���C�=i��
1
+ Q{<��scB�stV?�=��@�f�����d3)���9]�2����U�Z���;Q ܄�q
2
+ ^���=�Ҹ��kDB��uC�WvL�<���O�6)]q/Q� {q`�Ry�T��&�g�&u?�,'�6%��.�r� _��YԊ�F�\����H���$�I�����1bd̸�w�o��G��h%��
3
+ ����8 �-�?�no)+������*ۤ�]`7:Z��=� �V9Ohð�o�ڱ�xpb�
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.1
4
+ version: 0.4.3
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-12 00:00:00.000000000 Z
30
+ date: 2023-12-13 00:00:00.000000000 Z
31
31
  dependencies:
32
32
  - !ruby/object:Gem::Dependency
33
33
  name: zeitwerk
@@ -454,6 +454,8 @@ files:
454
454
  - checksums/rodbot-0.3.4.gem.sha512
455
455
  - checksums/rodbot-0.4.0.gem.sha512
456
456
  - checksums/rodbot-0.4.1.gem.sha512
457
+ - checksums/rodbot-0.4.2.gem.sha512
458
+ - checksums/rodbot-0.4.3.gem.sha512
457
459
  - doc/rodbot.afphoto
458
460
  - doc/rodbot.avif
459
461
  - exe/rodbot
@@ -499,6 +501,10 @@ files:
499
501
  - lib/rodbot/plugins/slack/README.slack.md
500
502
  - lib/rodbot/plugins/slack/relay.rb
501
503
  - lib/rodbot/plugins/word_of_the_day/README.word_of_the_day.md
504
+ - lib/rodbot/plugins/word_of_the_day/adapter.rb
505
+ - lib/rodbot/plugins/word_of_the_day/adapters/base.rb
506
+ - lib/rodbot/plugins/word_of_the_day/adapters/merriam_webster.rb
507
+ - lib/rodbot/plugins/word_of_the_day/adapters/transparent.rb
502
508
  - lib/rodbot/plugins/word_of_the_day/schedule.rb
503
509
  - lib/rodbot/rack.rb
504
510
  - lib/rodbot/refinements.rb
metadata.gz.sig CHANGED
@@ -1,3 +1 @@
1
- ���Jv�|��X��lC�^c1u�I��J�4��i�b��/��D�g}���n�u�*�'�Z"qZ�U;*�/���<�>�0�!�NɆL�p��$
2
- …7Ou
3
- N��Z��J��B�ߤ�D `|�즚k%�r�hq�
1
+ Qy^!6 ��e�[���@�)l�)l��]#��h��y�b��qu�����ɍ^�('���^:��εFWwQj�dK!�o۸A˺t$3>i���㦼_ƺ