matheus 0.3.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0f58d7287ef588ecd9a19da562f85a0c94cecb1911b07c1b3e079b620c37d7de
4
- data.tar.gz: f45c9ed2d4d192ead57a91562eecc52153c0dd35b6241fab31afcafa73050add
3
+ metadata.gz: 1aae1525835c65b5020012db937256f508f67fbb67662cd2ccf8ff73057ba6a0
4
+ data.tar.gz: 4d16cc4bebdbf0044a8a68455487580fc80c391fee5571de08d8ac33c6df7133
5
5
  SHA512:
6
- metadata.gz: c2ab16abdc86aedba2c0ef30f1614091e17165d11bad1d8c95d3170619104e7e6a62c33785cc34abe516e3d3929434a5eac7f77550f17b2c639174c1d23aba03
7
- data.tar.gz: 0a241ef204280b9a5e08f379d82823bd670a9fd352e20fe633055e0a788ee1adaa15af5c7f8956c5c2bc1e032089eff502973e21839d6b318f166d7a455a0eba
6
+ metadata.gz: 389ca6376f66e3a04ca92e9f969469c48f063705b792ab2f7e312a51bfe7b1303a65643de9e39586e394f2fdb9e54030c71191b38beff8b01b94eac77bc01e0d
7
+ data.tar.gz: 8b5d9c3055ee080259e314e785d18e661522bcda62964246cef86642d33ec72bd06a1e64dbc8e568a50999bdd1659ac9dd1dbce4ac5c6a78cc2d39289228dd40
data/.tool-versions CHANGED
@@ -1 +1 @@
1
- ruby 3.3.4
1
+ ruby 3.3.5
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.5.0]
4
+
5
+ _Released 2024-12-27_
6
+
7
+ - Add `convert-currency` command.
8
+
9
+ ## [0.4.0]
10
+
11
+ _Released 2024-10-02_
12
+
13
+ - Save past questions with `q` and retrieve them with the `qs` command.
14
+ - Reuse answers for the same questions.
15
+
3
16
  ## [0.3.0]
4
17
 
5
18
  _Released 2024-08-27_
data/README.md CHANGED
@@ -11,11 +11,18 @@ A bunch of CLI tools I made for my own use.
11
11
  ### `alert-me`
12
12
 
13
13
  ```sh
14
- $ alert-me sleep 1 && echo "Done!"
14
+ $ alert-me 'sleep 1 && echo "Done!"'
15
15
  Done!
16
16
  # plays a sound after the command finishes
17
17
  ```
18
18
 
19
+ ### [`convert-currency`](./lib/matheus/convert_currency.rb)
20
+
21
+ ```sh
22
+ $ convert-currency usd eur
23
+ 1 USD = 0.92 EUR
24
+ ```
25
+
19
26
  ### `date-of-last`
20
27
 
21
28
  Prints the date of the last week day.
data/Rakefile CHANGED
@@ -45,3 +45,5 @@ end
45
45
 
46
46
  # Ensure the generate_executables task runs before the build task
47
47
  task build: :generate_executables
48
+ # Ensure tests are run before releasing the gem
49
+ task release: :spec
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift("#{__dir__}/../lib")
4
+
5
+ require "matheus"
6
+
7
+ Matheus::ConvertCurrency.call ARGV
data/exe/qs ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift("#{__dir__}/../lib")
4
+
5
+ require "matheus"
6
+
7
+ Matheus::Qs.call ARGV
@@ -1,11 +1,14 @@
1
+ require 'net/http'
2
+ require 'json'
3
+ require 'date'
4
+
1
5
  module Matheus
2
6
  class AlertMe < Command
3
7
  # Usage:
4
- # $ alert-me sleep 1 && echo 'Done!'
8
+ # $ alert-me "sleep 1 && echo 'Done!'"
5
9
  # Runs the command and plays a sound based on its success or failure after it finishes.
6
10
  def call(*args)
7
- command = args.join(" ")
8
- if system(command)
11
+ if system(args.join(" "))
9
12
  system("afplay /System/Library/Sounds/Glass.aiff")
10
13
  else
11
14
  system("afplay /System/Library/Sounds/Sosumi.aiff")
@@ -0,0 +1,29 @@
1
+ require 'net/http'
2
+ require 'json'
3
+ require 'date'
4
+
5
+ module Matheus
6
+ # Usage:
7
+ # $ convert-currency usd eur
8
+ # $ convert-currency usd eur 2024-03-06
9
+ class ConvertCurrency < Command
10
+ def call(args)
11
+ source = args.fetch(0) { raise "Missing source currency" }
12
+ target = args.fetch(1) { raise "Missing target currency" }
13
+ date = args.fetch(2, Date.today)
14
+
15
+ api_url = "https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@#{date}/v1/currencies/#{source}.json"
16
+
17
+ data = JSON.parse(Net::HTTP.get(URI(api_url)))
18
+ rate = data.dig(source.downcase, target.downcase)
19
+
20
+ if rate
21
+ puts "1 #{source.upcase} = #{ActiveSupport::NumberHelper.number_to_currency(rate, unit: "")} #{target.upcase}"
22
+ else
23
+ Failure("Conversion rate from #{source.upcase} to #{target.upcase} not found")
24
+ end
25
+ rescue => e
26
+ Failure(e.message)
27
+ end
28
+ end
29
+ end
data/lib/matheus/q.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require "openai"
2
2
  require "tty-markdown"
3
+ require "tty-prompt"
4
+ require "json"
3
5
 
4
6
  module Matheus
5
7
  # Usage:
@@ -9,7 +11,17 @@ module Matheus
9
11
  BASE_PROMPT = "Answer this question in a short and concise way. You can use markdown in the response: "
10
12
 
11
13
  def call(question)
12
- ask_llm(question).then { print_markdown _1 }
14
+ question = question.join(" ")
15
+ existing_entry = search_question_in_history(question)
16
+
17
+ if existing_entry && use_existing_answer?
18
+ answer = existing_entry['answer']
19
+ else
20
+ answer = ask_llm(question)
21
+ save_qa(question, answer)
22
+ end
23
+
24
+ print_markdown(answer)
13
25
  rescue => e
14
26
  Failure(e.message)
15
27
  end
@@ -40,5 +52,26 @@ module Matheus
40
52
  def client
41
53
  OpenAI::Client.new(access_token: ENV.fetch("OPENAI_API_KEY"))
42
54
  end
55
+
56
+ def save_qa(question, answer)
57
+ history = load_history
58
+ history << { question:, answer:, timestamp: Time.now.to_s }
59
+ File.write(QUESTION_HISTORY_FILE, JSON.pretty_generate(history))
60
+ end
61
+
62
+ def load_history
63
+ File.exist?(QUESTION_HISTORY_FILE) ? JSON.parse(File.read(QUESTION_HISTORY_FILE)) : []
64
+ end
65
+
66
+ def search_question_in_history(question)
67
+ load_history.reverse.find { |entry| entry['question'].downcase.strip == question.downcase.strip }
68
+ end
69
+
70
+ def use_existing_answer?
71
+ prompt = TTY::Prompt.new
72
+ prompt.yes?("An existing answer was found. Do you want to use it?") do |q|
73
+ q.default true
74
+ end
75
+ end
43
76
  end
44
77
  end
data/lib/matheus/qs.rb ADDED
@@ -0,0 +1,40 @@
1
+ require "json"
2
+ require "tty-prompt"
3
+ require "tty-markdown"
4
+
5
+ module Matheus
6
+ # Usage:
7
+ # $ qs
8
+ # Lists the questions asked and their answers.
9
+ class Qs < Command
10
+ def call(_)
11
+ return puts "No questions found in history." if history.empty?
12
+
13
+ answer = prompt.select("Question:", choices, per_page: 10)
14
+ print_markdown(answer)
15
+ rescue => e
16
+ Failure(e.message)
17
+ end
18
+
19
+ private
20
+ def choices
21
+ history.map do |entry|
22
+ {entry['question'] => entry['answer'] }
23
+ end
24
+ end
25
+
26
+
27
+ def history
28
+ @history ||= File.exist?(QUESTION_HISTORY_FILE) ? JSON.parse(File.read(QUESTION_HISTORY_FILE)) : []
29
+ end
30
+
31
+ def prompt
32
+ @prompt ||= TTY::Prompt.new(interrupt: :exit)
33
+ end
34
+
35
+ def print_markdown(answer)
36
+ puts
37
+ puts TTY::Markdown.parse(answer)
38
+ end
39
+ end
40
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Matheus
4
- VERSION = "0.3.0"
4
+ VERSION = "0.5.0"
5
5
  end
data/lib/matheus.rb CHANGED
@@ -9,4 +9,5 @@ Dotenv.load("~/.env")
9
9
  Zeitwerk::Loader.for_gem.setup
10
10
 
11
11
  module Matheus
12
+ QUESTION_HISTORY_FILE = File.expand_path("~/.qa_history.json")
12
13
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: matheus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matheus Richard
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-08-27 00:00:00.000000000 Z
11
+ date: 2024-12-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zeitwerk
@@ -66,6 +66,34 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: 0.7.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: tty-table
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.12.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.12.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: tty-prompt
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.23.1
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.23.1
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: dotenv
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -85,9 +113,11 @@ email:
85
113
  - matheusrichardt@gmail.com
86
114
  executables:
87
115
  - alert-me
116
+ - convert-currency
88
117
  - date-of-last
89
118
  - puts
90
119
  - q
120
+ - qs
91
121
  extensions: []
92
122
  extra_rdoc_files: []
93
123
  files:
@@ -98,15 +128,19 @@ files:
98
128
  - README.md
99
129
  - Rakefile
100
130
  - exe/alert-me
131
+ - exe/convert-currency
101
132
  - exe/date-of-last
102
133
  - exe/puts
103
134
  - exe/q
135
+ - exe/qs
104
136
  - lib/matheus.rb
105
137
  - lib/matheus/alert_me.rb
106
138
  - lib/matheus/command.rb
139
+ - lib/matheus/convert_currency.rb
107
140
  - lib/matheus/date_of_last.rb
108
141
  - lib/matheus/puts.rb
109
142
  - lib/matheus/q.rb
143
+ - lib/matheus/qs.rb
110
144
  - lib/matheus/result.rb
111
145
  - lib/matheus/string_format.rb
112
146
  - lib/matheus/version.rb
@@ -132,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
132
166
  - !ruby/object:Gem::Version
133
167
  version: '0'
134
168
  requirements: []
135
- rubygems_version: 3.5.11
169
+ rubygems_version: 3.5.16
136
170
  signing_key:
137
171
  specification_version: 4
138
172
  summary: A bunch of CLI tools I made for my own use.