Module: EasyAnki

Defined in:
lib/easy-anki.rb,
lib/easy_anki/version.rb

Defined Under Namespace

Classes: Configuration, Error

Constant Summary collapse

VERSION =
"0.1.0"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.configurationObject



28
29
30
# File 'lib/easy-anki.rb', line 28

def self.configuration
  @configuration ||= EasyAnki::Configuration.new
end

.openai_clientObject



32
33
34
# File 'lib/easy-anki.rb', line 32

def self.openai_client
  @openai_client ||= OpenAI::Client.new
end

Class Method Details

.chat(message) ⇒ Object



40
41
42
43
44
45
46
47
48
49
# File 'lib/easy-anki.rb', line 40

def self.chat(message)
  response = openai_client.chat(
    parameters: {
      model: "gpt-3.5-turbo",
      messages: [{ role: "user", content: message }],
      temperature: 0.7
    }
  )
  response.dig("choices", 0, "message", "content")
end

.configure {|configuration| ... } ⇒ Object

Yields:



36
37
38
# File 'lib/easy-anki.rb', line 36

def self.configure
  yield(configuration)
end

.create_anki_cards(words) ⇒ Object



89
90
91
92
93
94
95
96
97
# File 'lib/easy-anki.rb', line 89

def self.create_anki_cards(words)
  words.map do |note|
    definitions = note[:definitions].map do |d|
      "<li>#{d[:text]}. <em>#{d[:example]}</em></li>"
    end
    back = "#{note[:translations].join(", ")}\n<ul>#{definitions.join}</ul>"
    { front: note[:text], back: back }
  end
end

.generate_flashcards(words) ⇒ Object



73
74
75
76
77
78
79
80
81
# File 'lib/easy-anki.rb', line 73

def self.generate_flashcards(words)
  batch_size = 30
  batches = (words.count.to_f / batch_size).ceil
  words.each_slice(batch_size).with_index do |words_batch, index|
    words_batch = words_batch.map { |w| w[:text] }
    puts "Processing batch #{index + 1}/#{batches} ..."
    process_batch(words_batch)
  end
end

.parse_input_file(filename) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/easy-anki.rb', line 60

def self.parse_input_file(filename)
  file = File.read(filename)
  anki_file = filename.match?(/.txt$/)
  if anki_file
    puts "Parsing Anki file..."
    arr = CSV.parse(file, col_sep: "\t")
    puts "#{arr.count} words"
    arr.map { |a| { text: a.first } }
  else
    CSV.parse(file, headers: true, header_converters: :symbol).map(&:to_hash)
  end
end

.process_batch(words_batch) ⇒ Object



83
84
85
86
87
# File 'lib/easy-anki.rb', line 83

def self.process_batch(words_batch)
  ai_results = translate(words_batch)
  cards = create_anki_cards(ai_results)
  write_cards_to_file(cards)
end

.translate(words) ⇒ Object



51
52
53
54
55
56
57
58
# File 'lib/easy-anki.rb', line 51

def self.translate(words)
  message = "For each word, return the translations to #{configuration.translation_language} and also definitions" \
            " (with examples). The response should ONLY contain a JSON (root key data) with an array containing the" \
            " keys text, translations (array), definitions (array of objects with text and example). Words array:" \
            " #{words.to_json}"
  ai_message = chat(message)
  JSON.parse(ai_message, symbolize_names: true)[:data]
end

.write_cards_to_file(cards) ⇒ Object



99
100
101
102
103
104
105
# File 'lib/easy-anki.rb', line 99

def self.write_cards_to_file(cards)
  CSV.open("output.csv", "ab") do |csv|
    cards.each do |hash|
      csv << hash.values
    end
  end
end