anki_record 0.3.2 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +0 -1
  3. data/.rubocop.yml +2 -7
  4. data/CHANGELOG.md +15 -1
  5. data/Gemfile +4 -0
  6. data/Gemfile.lock +9 -2
  7. data/README.md +89 -132
  8. data/anki_record.gemspec +2 -2
  9. data/lib/anki_record/anki21_database/anki21_database.rb +172 -0
  10. data/lib/anki_record/anki21_database/anki21_database_attributes.rb +31 -0
  11. data/lib/anki_record/anki21_database/anki21_database_constructors.rb +52 -0
  12. data/lib/anki_record/anki2_database/anki2_database.rb +44 -0
  13. data/lib/anki_record/anki_package/anki_package.rb +115 -174
  14. data/lib/anki_record/card/card.rb +17 -33
  15. data/lib/anki_record/card/card_attributes.rb +3 -34
  16. data/lib/anki_record/card_template/card_template.rb +2 -2
  17. data/lib/anki_record/card_template/card_template_attributes.rb +11 -11
  18. data/lib/anki_record/collection/collection.rb +20 -154
  19. data/lib/anki_record/collection/collection_attributes.rb +2 -30
  20. data/lib/anki_record/deck/deck.rb +11 -10
  21. data/lib/anki_record/deck/deck_attributes.rb +6 -8
  22. data/lib/anki_record/deck/deck_defaults.rb +1 -1
  23. data/lib/anki_record/deck_options_group/deck_options_group.rb +8 -6
  24. data/lib/anki_record/deck_options_group/deck_options_group_attributes.rb +5 -7
  25. data/lib/anki_record/helpers/anki_guid_helper.rb +20 -0
  26. data/lib/anki_record/media/media.rb +36 -0
  27. data/lib/anki_record/note/note.rb +72 -93
  28. data/lib/anki_record/note/note_attributes.rb +18 -17
  29. data/lib/anki_record/note_field/note_field.rb +3 -3
  30. data/lib/anki_record/note_field/note_field_attributes.rb +9 -9
  31. data/lib/anki_record/note_type/note_type.rb +13 -14
  32. data/lib/anki_record/note_type/note_type_attributes.rb +17 -21
  33. data/lib/anki_record/version.rb +1 -1
  34. metadata +11 -7
  35. data/lib/anki_record/helpers/data_query_helper.rb +0 -15
  36. data/lib/anki_record/note/note_guid_helper.rb +0 -10
@@ -2,78 +2,113 @@
2
2
 
3
3
  require "securerandom"
4
4
 
5
+ require_relative "../helpers/anki_guid_helper"
5
6
  require_relative "../helpers/checksum_helper"
6
7
  require_relative "../helpers/time_helper"
7
8
  require_relative "note_attributes"
8
- require_relative "note_guid_helper"
9
9
 
10
- # rubocop:disable Metrics/ClassLength
11
10
  module AnkiRecord
12
11
  ##
13
- # Represents an Anki note.
12
+ # Note represents Anki notes, which are the main thing that Anki Record is intended to create or update.
14
13
  class Note
15
14
  include Helpers::ChecksumHelper
16
15
  include NoteAttributes
17
- include NoteGuidHelper
18
16
  include Helpers::TimeHelper
19
17
  include Helpers::SharedConstantsHelper
20
18
 
21
19
  ##
22
- # Instantiates a note of type +note_type+ and belonging to deck +deck+.
23
- def initialize(note_type: nil, deck: nil, collection: nil, data: nil)
20
+ # Instantiates a note of type +note_type+ and belonging to deck +deck+
21
+ def initialize(note_type: nil, deck: nil, anki21_database: nil, data: nil)
24
22
  if note_type && deck
25
- setup_instance_variables_for_new_note(note_type: note_type, deck: deck)
26
- elsif collection && data
27
- setup_instance_variables_from_existing(collection: collection,
28
- note_data: data[:note_data], cards_data: data[:cards_data])
23
+ setup_new_note(note_type:, deck:)
24
+ elsif anki21_database && data
25
+ setup_existing_note(anki21_database:,
26
+ note_data: data[:note_data], cards_data: data[:cards_data])
29
27
  else
30
28
  raise ArgumentError
31
29
  end
32
30
  end
33
31
 
34
- private
32
+ ##
33
+ # Saves the note and its cards
34
+ def save
35
+ anki21_database.find_note_by(id: @id) ? update_note_in_collection_anki21 : insert_new_note_in_collection_anki21
36
+ true
37
+ end
35
38
 
36
- def setup_instance_variables_for_new_note(note_type:, deck:)
37
- raise ArgumentError unless note_type.collection == deck.collection
39
+ ##
40
+ # Overrides BasicObject#method_missing and creates "ghost methods"
41
+ #
42
+ # The ghost methods are the setters and getters for the note field values.
43
+ #
44
+ # For example, if the note type has a field called "front" then there will be two ghost methods: front and front=.
45
+ def method_missing(method_name, field_content = nil)
46
+ raise NoMethodError, "##{method_name} is not defined or a ghost method" unless respond_to_missing? method_name
38
47
 
39
- setup_collaborator_object_instance_variables_for_new_note(note_type: note_type, deck: deck)
40
- setup_simple_instance_variables_for_new_note
48
+ method_name = method_name.to_s
49
+ return @field_contents[method_name] unless method_name.end_with?("=")
50
+
51
+ @field_contents[method_name.chomp("=")] = field_content
52
+ end
53
+
54
+ ##
55
+ # This allows #respond_to? to be accurate for the ghost methods created by #method_missing.
56
+ def respond_to_missing?(method_name, *)
57
+ method_name = method_name.to_s
58
+ if method_name.end_with?("=")
59
+ note_type.snake_case_field_names.include?(method_name.chomp("="))
60
+ else
61
+ note_type.snake_case_field_names.include?(method_name)
41
62
  end
63
+ end
64
+
65
+ ##
66
+ # Returns the text value of the note's sfld (sort field) which is determined by
67
+ # the note's note type
68
+ def sort_field_value
69
+ @field_contents[note_type.snake_case_sort_field_name]
70
+ end
71
+
72
+ private
73
+
74
+ # rubocop:disable Metrics/AbcSize
75
+ # rubocop:disable Metrics/MethodLength
76
+ def setup_new_note(note_type:, deck:)
77
+ raise ArgumentError unless note_type.anki21_database == deck.anki21_database
42
78
 
43
- def setup_collaborator_object_instance_variables_for_new_note(note_type:, deck:)
44
79
  @note_type = note_type
45
80
  @deck = deck
46
- @collection = deck.collection
81
+ @anki21_database = note_type.anki21_database
47
82
  @field_contents = setup_empty_field_contents_hash
48
83
  @cards = @note_type.card_templates.map do |card_template|
49
- Card.new(note: self, card_template: card_template)
84
+ Card.new(note: self, card_template:)
50
85
  end
51
- end
52
-
53
- def setup_simple_instance_variables_for_new_note
54
86
  @id = milliseconds_since_epoch
55
- @guid = globally_unique_id
56
- @last_modified_timestamp = seconds_since_epoch
87
+ @guid = Helpers::AnkiGuidHelper.globally_unique_id
88
+ @last_modified_timestamp = nil
57
89
  @usn = NEW_OBJECT_USN
58
90
  @tags = []
59
91
  @flags = 0
60
92
  @data = ""
61
93
  end
62
94
 
63
- def setup_instance_variables_from_existing(collection:, note_data:, cards_data:)
64
- setup_collaborator_object_instance_variables_from_existing(collection: collection, note_data: note_data,
65
- cards_data: cards_data)
66
- setup_simple_instance_variables_from_existing(note_data: note_data)
67
- end
68
-
69
- def setup_collaborator_object_instance_variables_from_existing(collection:, note_data:, cards_data:)
70
- @collection = collection
71
- @note_type = collection.find_note_type_by id: note_data["mid"]
72
- @field_contents = setup_field_contents_hash_from_existing(note_data: note_data)
95
+ def setup_existing_note(anki21_database:, note_data:, cards_data:)
96
+ @anki21_database = anki21_database
97
+ @note_type = anki21_database.find_note_type_by id: note_data["mid"]
98
+ @field_contents = setup_field_contents_hash_from_existing(note_data:)
73
99
  @cards = @note_type.card_templates.map.with_index do |_card_template, index|
74
100
  Card.new(note: self, card_data: cards_data[index])
75
101
  end
102
+ @id = note_data["id"]
103
+ @guid = note_data["guid"]
104
+ @last_modified_timestamp = note_data["mod"]
105
+ @usn = note_data["usn"]
106
+ @tags = note_data["tags"].split
107
+ @flags = note_data["flags"]
108
+ @data = note_data["data"]
76
109
  end
110
+ # rubocop:enable Metrics/AbcSize
111
+ # rubocop:enable Metrics/MethodLength
77
112
 
78
113
  def setup_field_contents_hash_from_existing(note_data:)
79
114
  field_contents = setup_empty_field_contents_hash
@@ -84,93 +119,37 @@ module AnkiRecord
84
119
  field_contents
85
120
  end
86
121
 
87
- def setup_simple_instance_variables_from_existing(note_data:)
88
- @id = note_data["id"]
89
- @guid = note_data["guid"]
90
- @last_modified_timestamp = note_data["mod"]
91
- @usn = note_data["usn"]
92
- @tags = note_data["tags"].split
93
- @flags = note_data["flags"]
94
- @data = note_data["data"]
95
- end
96
-
97
122
  def setup_empty_field_contents_hash
98
123
  field_contents = {}
99
124
  note_type.snake_case_field_names.each { |field_name| field_contents[field_name] = "" }
100
125
  field_contents
101
126
  end
102
127
 
103
- public
104
-
105
- ##
106
- # Saves the note to the collection.anki21 database.
107
- #
108
- # This also saves the note's cards.
109
- def save
110
- collection.find_note_by(id: @id) ? update_note_in_collection_anki21 : insert_new_note_in_collection_anki21
111
- true
112
- end
113
-
114
- private
115
-
116
128
  def update_note_in_collection_anki21
117
- statement = @collection.anki_package.prepare <<~SQL
129
+ statement = anki21_database.prepare <<~SQL
118
130
  update notes set guid = ?, mid = ?, mod = ?, usn = ?, tags = ?,
119
131
  flds = ?, sfld = ?, csum = ?, flags = ?, data = ? where id = ?
120
132
  SQL
121
- statement.execute([@guid, note_type.id, @last_modified_timestamp,
133
+ statement.execute([@guid, note_type.id, seconds_since_epoch,
122
134
  @usn, @tags.join(" "), field_values_separated_by_us, sort_field_value,
123
135
  checksum(sort_field_value), @flags, @data, @id])
124
136
  cards.each { |card| card.save(note_exists_already: true) }
125
137
  end
126
138
 
127
139
  def insert_new_note_in_collection_anki21
128
- statement = @collection.anki_package.prepare <<~SQL
140
+ statement = anki21_database.prepare <<~SQL
129
141
  insert into notes (id, guid, mid, mod, usn, tags, flds, sfld, csum, flags, data)
130
142
  values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
131
143
  SQL
132
- statement.execute([@id, @guid, note_type.id, @last_modified_timestamp,
144
+ statement.execute([@id, @guid, note_type.id, seconds_since_epoch,
133
145
  @usn, @tags.join(" "), field_values_separated_by_us, sort_field_value,
134
146
  checksum(sort_field_value), @flags, @data])
135
147
  cards.each(&:save)
136
148
  end
137
149
 
138
- public
139
-
140
- ##
141
- # Overrides BasicObject#method_missing and creates "ghost methods".
142
- #
143
- # The ghost methods are the setters and getters for the note field values.
144
- def method_missing(method_name, field_content = nil)
145
- raise NoMethodError, "##{method_name} is not defined or a ghost method" unless respond_to_missing? method_name
146
-
147
- method_name = method_name.to_s
148
- return @field_contents[method_name] unless method_name.end_with?("=")
149
-
150
- @field_contents[method_name.chomp("=")] = field_content
151
- end
152
-
153
- ##
154
- # This allows #respond_to? to be accurate for the ghost methods created by #method_missing.
155
- def respond_to_missing?(method_name, *)
156
- method_name = method_name.to_s
157
- if method_name.end_with?("=")
158
- note_type.snake_case_field_names.include?(method_name.chomp("="))
159
- else
160
- note_type.snake_case_field_names.include?(method_name)
161
- end
162
- end
163
-
164
- private
165
-
166
150
  def field_values_separated_by_us
167
151
  # The ASCII control code represented by hexadecimal 1F is the Unit Separator (US)
168
152
  note_type.snake_case_field_names.map { |field_name| @field_contents[field_name] }.join("\x1F")
169
153
  end
170
-
171
- def sort_field_value
172
- @field_contents[note_type.snake_case_sort_field_name]
173
- end
174
154
  end
175
155
  end
176
- # rubocop:enable Metrics/ClassLength
@@ -1,56 +1,57 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AnkiRecord
4
- # Module with the Note class's attribute readers, writers, and accessors.
4
+ # Module with Note's attribute readers, writers, and accessors.
5
5
  module NoteAttributes
6
+ attr_reader :anki21_database # :nodoc:
7
+
6
8
  ##
7
- # The note's id.
9
+ # The note's id
8
10
  attr_reader :id
9
11
 
10
12
  ##
11
- # The note's globally unique id.
13
+ # The note's globally unique id
14
+ #
15
+ # This is used by Anki to match an imported note to an existing note and
16
+ # update it rather than duplicate the note.
12
17
  attr_accessor :guid
13
18
 
14
19
  ##
15
- # The number of seconds since the 1970 epoch at which the note was last modified.
20
+ # The number of seconds since the 1970 epoch when the note was last modified.
16
21
  attr_reader :last_modified_timestamp
17
22
 
18
23
  ##
19
- # The note's update sequence number.
24
+ # The note's update sequence number
20
25
  attr_reader :usn
21
26
 
22
27
  ##
23
- # The note's tags, as an array. The tags are strings.
28
+ # The note's tags, as an array of strings
24
29
  attr_reader :tags
25
30
 
26
31
  ##
27
- # The note's field contents, as a hash.
32
+ # The note's field contents as a hash
28
33
  attr_reader :field_contents
29
34
 
30
35
  ##
31
- # The note's deck object.
36
+ # The note's deck.
32
37
  #
33
- # When the note is saved, the cards will belong to this deck.
38
+ # When the note is saved, the note will belong to this deck
34
39
  attr_reader :deck
35
40
 
36
41
  ##
37
- # The note's note type object.
42
+ # The note's note type
38
43
  attr_reader :note_type
39
44
 
40
45
  ##
41
- # The note's collection object.
42
- attr_reader :collection
43
-
44
- ##
45
- # The note's card objects, as an array.
46
+ # The note's card objects, as an array
46
47
  attr_reader :cards
47
48
 
48
49
  ##
49
- # Corresponds to the flags column in the collection.anki21 notes table.
50
+ # Corresponds to the flags column in the collection.anki21 notes table
50
51
  attr_reader :flags
51
52
 
52
53
  ##
53
- # Corresponds to the data column in the collection.anki21 notes table.
54
+ # Corresponds to the data column in the collection.anki21 notes table
54
55
  attr_reader :data
55
56
  end
56
57
  end
@@ -5,7 +5,7 @@ require_relative "note_field_defaults"
5
5
 
6
6
  module AnkiRecord
7
7
  ##
8
- # NoteField represents a field of an Anki note type.
8
+ # NoteField represents a field of an Anki note type
9
9
  class NoteField
10
10
  include NoteFieldAttributes
11
11
  include NoteFieldDefaults
@@ -17,9 +17,9 @@ module AnkiRecord
17
17
 
18
18
  @note_type = note_type
19
19
  if args
20
- setup_note_field_instance_variables_from_existing(args: args)
20
+ setup_note_field_instance_variables_from_existing(args:)
21
21
  else
22
- setup_note_field_instance_variables_for_new_field(name: name)
22
+ setup_note_field_instance_variables_for_new_field(name:)
23
23
  end
24
24
 
25
25
  @note_type.add_note_field self
@@ -2,38 +2,38 @@
2
2
 
3
3
  module AnkiRecord
4
4
  ##
5
- # Module with the NoteField class's attribute readers, writers, and accessors.
5
+ # Module with NoteField class's attribute readers, writers, and accessors.
6
6
  module NoteFieldAttributes
7
7
  ##
8
- # The field's note type.
8
+ # The field's note type
9
9
  attr_reader :note_type
10
10
 
11
11
  ##
12
- # The field's name.
12
+ # The field's name
13
13
  attr_accessor :name
14
14
 
15
15
  ##
16
- # A boolean that indicates if the field is sticky.
16
+ # A boolean that indicates if the field is sticky
17
17
  attr_accessor :sticky
18
18
 
19
19
  ##
20
- # A boolean that indicates if the field is right to left.
20
+ # A boolean that indicates if the field is right to left
21
21
  attr_accessor :right_to_left
22
22
 
23
23
  ##
24
- # The field's font style used when editing.
24
+ # The field's font style used when editing
25
25
  attr_accessor :font_style
26
26
 
27
27
  ##
28
- # The field's font size used when editing.
28
+ # The field's font size used when editing
29
29
  attr_accessor :font_size
30
30
 
31
31
  ##
32
- # The field's description.
32
+ # The field's description
33
33
  attr_accessor :description
34
34
 
35
35
  ##
36
- # 0 for the first field of the note type, 1 for the second, etc.
36
+ # 0 for the first field of the note type, 1 for the second, etc
37
37
  attr_reader :ordinal_number
38
38
  end
39
39
  end
@@ -10,8 +10,6 @@ require_relative "note_type_defaults"
10
10
  module AnkiRecord
11
11
  ##
12
12
  # NoteType represents an Anki note type (also called a model).
13
- #
14
- # The attributes are documented in the NoteTypeAttributes module.
15
13
  class NoteType
16
14
  include Helpers::SharedConstantsHelper
17
15
  include Helpers::TimeHelper
@@ -21,28 +19,29 @@ module AnkiRecord
21
19
  NOTE_TYPES_WITHOUT_TAGS_AND_VERS_VALUES = ["Basic", "Basic (and reversed card)",
22
20
  "Basic (optional reversed card)", "Basic (type in the answer)"].freeze
23
21
 
24
- def initialize(collection:, name: nil, args: nil)
22
+ ##
23
+ # Instantiates a new note type belonging to +anki21_database+ with name +name+
24
+ def initialize(anki21_database:, name: nil, args: nil)
25
25
  raise ArgumentError unless (name && args.nil?) || (args && args["name"])
26
26
 
27
- @collection = collection
27
+ @anki21_database = anki21_database
28
28
 
29
29
  if args
30
- setup_note_type_instance_variables_from_existing(args: args)
30
+ setup_note_type_instance_variables_from_existing(args:)
31
31
  else
32
- setup_instance_variables_for_new_note_type(name: name)
32
+ setup_instance_variables_for_new_note_type(name:)
33
33
  end
34
34
 
35
- @collection.add_note_type self
36
- save
35
+ @anki21_database.add_note_type self
37
36
  end
38
37
 
39
38
  ##
40
39
  # Saves the note type to the collection.anki21 database
41
40
  def save
42
- collection_models_hash = collection.models_json
41
+ collection_models_hash = anki21_database.models_json
43
42
  collection_models_hash[@id] = to_h
44
43
  sql = "update col set models = ? where id = ?"
45
- collection.anki_package.prepare(sql).execute([JSON.generate(collection_models_hash), collection.id])
44
+ anki21_database.prepare(sql).execute([JSON.generate(collection_models_hash), anki21_database.collection.id])
46
45
  end
47
46
 
48
47
  def to_h # :nodoc:
@@ -68,7 +67,7 @@ module AnkiRecord
68
67
  end
69
68
 
70
69
  def snake_case_field_names # :nodoc:
71
- field_names_in_order.map { |field_name| field_name.downcase.gsub(" ", "_") }
70
+ field_names_in_order.map { |field_name| field_name.downcase.tr(" ", "_") }
72
71
  end
73
72
 
74
73
  ##
@@ -78,7 +77,7 @@ module AnkiRecord
78
77
  end
79
78
 
80
79
  def snake_case_sort_field_name # :nodoc:
81
- sort_field_name.downcase.gsub(" ", "_")
80
+ sort_field_name.downcase.tr(" ", "_")
82
81
  end
83
82
 
84
83
  ##
@@ -109,8 +108,8 @@ module AnkiRecord
109
108
  private
110
109
 
111
110
  def setup_note_type_instance_variables_from_existing(args:)
112
- setup_collaborator_object_instance_variables_from_existing(args: args)
113
- setup_simple_instance_variables_from_existing(args: args)
111
+ setup_collaborator_object_instance_variables_from_existing(args:)
112
+ setup_simple_instance_variables_from_existing(args:)
114
113
  end
115
114
 
116
115
  def setup_collaborator_object_instance_variables_from_existing(args:)
@@ -2,70 +2,68 @@
2
2
 
3
3
  module AnkiRecord
4
4
  ##
5
- # Module with the NoteType class's attribute readers, writers, and accessors.
5
+ # Module with the NoteType class's attribute readers, writers, and accessors
6
6
  module NoteTypeAttributes
7
- ##
8
- # The note type's collection object.
9
- attr_reader :collection
7
+ attr_reader :anki21_database, :latex_svg, :tags, :req, :vers
10
8
 
11
9
  ##
12
- # The note type's id.
10
+ # The note type's id
13
11
  attr_reader :id
14
12
 
15
13
  ##
16
- # The note type's name.
14
+ # The note type's name
17
15
  attr_accessor :name
18
16
 
19
17
  ##
20
- # A boolean that indicates if this note type is a cloze-deletion note type.
18
+ # A boolean that indicates if this note type is a cloze-deletion note type
21
19
  attr_accessor :cloze
22
20
 
23
21
  ##
24
- # The number of seconds since the 1970 epoch at which the note type was last modified.
22
+ # The number of seconds since the 1970 epoch at which the note type was last modified
25
23
  attr_reader :last_modified_timestamp
26
24
 
27
25
  ##
28
- # The note type's update sequence number.
26
+ # The note type's update sequence number
29
27
  attr_reader :usn
30
28
 
31
29
  ##
32
- # The note type's sort field.
30
+ # The note type's sort field
33
31
  attr_reader :sort_field
34
32
 
35
33
  ##
36
- # The note type's CSS.
34
+ # The note type's CSS
37
35
  attr_accessor :css
38
36
 
39
37
  ##
40
- # The note type's LaTeX preamble.
38
+ # The note type's LaTeX preamble
41
39
  attr_reader :latex_preamble
42
40
 
43
41
  ##
44
- # The note type's LaTeX postamble.
42
+ # The note type's LaTeX postamble
45
43
  attr_reader :latex_postamble
46
44
 
47
45
  ##
48
- # The note type's card template objects, as an array.
46
+ # The note type's card template objects, as an array
49
47
  attr_reader :card_templates
50
48
 
51
49
  ##
52
- # The note type's field objects, as an array.
50
+ # The note type's field objects, as an array
53
51
  attr_reader :note_fields
54
52
 
55
53
  ##
56
- # The note type's deck's id.
54
+ # The note type's deck's id
57
55
  attr_reader :deck_id
58
56
 
59
57
  ##
60
- # The note type's deck.
58
+ # The note type's deck
61
59
  def deck
62
60
  return nil unless @deck_id
63
61
 
64
- @collection.find_deck_by id: @deck_id
62
+ anki21_database.find_deck_by id: @deck_id
65
63
  end
66
64
 
67
65
  ##
68
- # Sets the note type's deck object.
66
+ # Sets the note type's deck object
69
67
  def deck=(deck)
70
68
  unless deck.instance_of?(AnkiRecord::Deck)
71
69
  raise ArgumentError,
@@ -74,7 +72,5 @@ module AnkiRecord
74
72
 
75
73
  @deck_id = deck.id
76
74
  end
77
-
78
- attr_reader :latex_svg, :tags, :req, :vers
79
75
  end
80
76
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AnkiRecord
4
- VERSION = "0.3.2" # :nodoc:
4
+ VERSION = "0.4.1" # :nodoc:
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: anki_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kyle Rego
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-20 00:00:00.000000000 Z
11
+ date: 2023-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubyzip
@@ -38,8 +38,8 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.3'
41
- description: " A Ruby library which provides a programmatic interface to Anki flashcard
42
- decks (.apkg files/zipped Anki SQLite databases).\n"
41
+ description: " Anki Record lets you create Anki deck packages or update existing
42
+ ones with the Ruby programming language.\n"
43
43
  email:
44
44
  - regoky@outlook.com
45
45
  executables: []
@@ -57,6 +57,10 @@ files:
57
57
  - Rakefile
58
58
  - anki_record.gemspec
59
59
  - lib/anki_record.rb
60
+ - lib/anki_record/anki21_database/anki21_database.rb
61
+ - lib/anki_record/anki21_database/anki21_database_attributes.rb
62
+ - lib/anki_record/anki21_database/anki21_database_constructors.rb
63
+ - lib/anki_record/anki2_database/anki2_database.rb
60
64
  - lib/anki_record/anki_package/anki_package.rb
61
65
  - lib/anki_record/card/card.rb
62
66
  - lib/anki_record/card/card_attributes.rb
@@ -70,13 +74,13 @@ files:
70
74
  - lib/anki_record/deck/deck_defaults.rb
71
75
  - lib/anki_record/deck_options_group/deck_options_group.rb
72
76
  - lib/anki_record/deck_options_group/deck_options_group_attributes.rb
77
+ - lib/anki_record/helpers/anki_guid_helper.rb
73
78
  - lib/anki_record/helpers/checksum_helper.rb
74
- - lib/anki_record/helpers/data_query_helper.rb
75
79
  - lib/anki_record/helpers/shared_constants_helper.rb
76
80
  - lib/anki_record/helpers/time_helper.rb
81
+ - lib/anki_record/media/media.rb
77
82
  - lib/anki_record/note/note.rb
78
83
  - lib/anki_record/note/note_attributes.rb
79
- - lib/anki_record/note/note_guid_helper.rb
80
84
  - lib/anki_record/note_field/note_field.rb
81
85
  - lib/anki_record/note_field/note_field_attributes.rb
82
86
  - lib/anki_record/note_field/note_field_defaults.rb
@@ -110,5 +114,5 @@ requirements: []
110
114
  rubygems_version: 3.4.6
111
115
  signing_key:
112
116
  specification_version: 4
113
- summary: Automate Anki flashcard editing with the Ruby programming language.
117
+ summary: Create and update Anki deck packages with Ruby.
114
118
  test_files: []
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AnkiRecord
4
- module Helpers
5
- module DataQueryHelper # :nodoc:
6
- def note_cards_data_for_note_id(sql_able:, id:)
7
- note_data = sql_able.prepare("select * from notes where id = ?").execute([id]).first
8
- return nil unless note_data
9
-
10
- cards_data = sql_able.prepare("select * from cards where nid = ?").execute([id]).to_a
11
- { note_data: note_data, cards_data: cards_data }
12
- end
13
- end
14
- end
15
- end
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AnkiRecord
4
- # Module with the helper method to generate the note guid.
5
- module NoteGuidHelper
6
- def globally_unique_id
7
- SecureRandom.uuid.slice(5...15)
8
- end
9
- end
10
- end