Class: Doing::Items
- Defined in:
- lib/doing/items/items.rb,
lib/doing/items/util.rb,
lib/doing/items/filter.rb,
lib/doing/items/modify.rb,
lib/doing/items/sections.rb
Overview
A collection of Item objects
Instance Attribute Summary collapse
-
#sections ⇒ Object
Returns the value of attribute sections.
Instance Method Summary collapse
-
#add_section(section, log: false) ⇒ Object
Add a new section to the sections array.
-
#all_tags ⇒ Array
Get all tags on Items in self.
-
#between_dates(start, finish) ⇒ Items
Filter Items by date.
-
#dedup(match_section: true) ⇒ Items
Remove duplicated entries.
- #dedup!(match_section: true) ⇒ Object
-
#delete(item) ⇒ Object
Create a deep copy of Items def clone Marshal.load(Marshal.dump(self)) end.
-
#delete_item(item, single: false) ⇒ Object
Delete an item from the index.
- #delete_section(section, log: false) ⇒ Object
-
#diff(items) ⇒ Hash
Return Items containing items that don't exist in receiver.
-
#find_id(id) ⇒ Object
Find an item by ID.
-
#guess_section(frag, distance: 2) ⇒ Section
Return the best section match for a search query.
-
#in_section(section) ⇒ Items
Get a new Items object containing only items in a specified section.
-
#include?(item, match_section: true) ⇒ Boolean
Test if self includes Item.
-
#index_for_id(id) ⇒ Object
Return the index for an entry matching ID.
-
#initialize ⇒ Items
constructor
A new instance of Items.
-
#search(query, case_type: :smart) ⇒ Items
Search Items for a string (title and note).
-
#section?(section) ⇒ Boolean
Test if section already exists.
-
#section_titles ⇒ Array
List sections, title only.
-
#tagged(tags, bool: :and) ⇒ Items
Search items by tags.
-
#to_s ⇒ Object
Output sections and items in Doing file format.
-
#update_item(old_item, new_item) ⇒ Object
Update an item in the index with a modified item.
Methods inherited from Array
Methods included from ChronifyArray
#time_string, #to_abbr, #to_natural, #to_years
Constructor Details
#initialize ⇒ Items
Returns a new instance of Items.
13 14 15 16 |
# File 'lib/doing/items/items.rb', line 13 def initialize super @sections = [] end |
Instance Attribute Details
#sections ⇒ Object
Returns the value of attribute sections.
11 12 13 |
# File 'lib/doing/items/items.rb', line 11 def sections @sections end |
Instance Method Details
#add_section(section, log: false) ⇒ Object
Add a new section to the sections array. Accepts either a Section object, or a title string that will be converted into a Section.
59 60 61 62 63 64 65 66 |
# File 'lib/doing/items/sections.rb', line 59 def add_section(section, log: false) section = section.is_a?(Section) ? section : Section.new(section.cap_first) return if section?(section) @sections.push(section) Doing.logger.info('New section:', %("#{section}" added)) if log end |
#all_tags ⇒ Array
Get all tags on Items in self
26 27 28 29 30 |
# File 'lib/doing/items/util.rb', line 26 def each_with_object([]) do |entry, | .concat(entry.).sort!.uniq! end end |
#between_dates(start, finish) ⇒ Items
Filter Items by date. String arguments will be chronified
62 63 64 65 66 |
# File 'lib/doing/items/filter.rb', line 62 def between_dates(start, finish) start = start.chronify(guess: :begin, future: false) if start.is_a?(String) finish = finish.chronify(guess: :end) if finish.is_a?(String) WWID.new.filter_items(self, opt: { date_filter: [start, finish] }) end |
#dedup(match_section: true) ⇒ Items
Remove duplicated entries. Duplicate entries must have matching start date, title, note, and section
60 61 62 63 64 65 66 67 |
# File 'lib/doing/items/util.rb', line 60 def dedup(match_section: true) unique = Items.new each do |item| unique.push(item) unless unique.include?(item, match_section: match_section) end unique end |
#dedup!(match_section: true) ⇒ Object
70 71 72 |
# File 'lib/doing/items/util.rb', line 70 def dedup!(match_section: true) replace dedup(match_section: match_section) end |
#delete(item) ⇒ Object
Create a deep copy of Items
def clone Marshal.load(Marshal.dump(self)) end
10 11 12 13 14 15 16 17 18 19 |
# File 'lib/doing/items/util.rb', line 10 def delete(item) deleted = nil each_with_index do |i, idx| if i.equal?(item, match_section: true) deleted = delete_at(idx) break end end deleted end |
#delete_item(item, single: false) ⇒ Object
Delete an item from the index
10 11 12 13 14 15 |
# File 'lib/doing/items/modify.rb', line 10 def delete_item(item, single: false) deleted = delete(item) Doing.logger.count(:deleted) Doing.logger.info('Entry deleted:', deleted.title) if single deleted end |
#delete_section(section, log: false) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/doing/items/sections.rb', line 68 def delete_section(section, log: false) return unless section?(section) raise DoingRuntimeError, 'Section not empty' if in_section(section).count.positive? @sections.each do |sect| next unless sect.title == section && in_section(sect).count.zero? @sections.delete(sect) Doing.logger.info('Removed section:', %("#{section}" removed)) if log end Doing.logger.error('Not found:', %("#{section}" not found)) end |
#diff(items) ⇒ Hash
Return Items containing items that don't exist in receiver
40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/doing/items/util.rb', line 40 def diff(items) a = clone b = items.clone a.delete_if do |item| if b.include?(item) b.delete(item) true else false end end { added: b, deleted: a } end |
#find_id(id) ⇒ Object
Find an item by ID
42 43 44 |
# File 'lib/doing/items/items.rb', line 42 def find_id(id) select { |item| item.id == id }[0] end |
#guess_section(frag, distance: 2) ⇒ Section
Return the best section match for a search query
32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/doing/items/sections.rb', line 32 def guess_section(frag, distance: 2) section = nil re = frag.to_rx(distance: distance, case_type: :ignore) @sections.each do |sect| next unless sect.title =~ /#{re}/i Doing.logger.debug('Match:', %(Assuming "#{sect.title}" from "#{frag}")) section = sect break end section end |
#in_section(section) ⇒ Items
Get a new Items object containing only items in a specified section
12 13 14 15 16 17 18 19 20 21 |
# File 'lib/doing/items/filter.rb', line 12 def in_section(section) sect = section.is_a?(Section) ? section.title : section if sect =~ /^all$/i dup else items = Items.new.concat(select { |item| !item.nil? && item.section == section }) items.add_section(section, log: false) items end end |
#include?(item, match_section: true) ⇒ Boolean
Test if self includes Item
26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/doing/items/items.rb', line 26 def include?(item, match_section: true) includes = false each do |other_item| if other_item.equal?(item, match_section: match_section) includes = true break end end includes end |
#index_for_id(id) ⇒ Object
Return the index for an entry matching ID
51 52 53 54 55 56 57 58 59 60 |
# File 'lib/doing/items/items.rb', line 51 def index_for_id(id) i = nil each_with_index do |item, idx| if item.id == id i = idx break end end i end |
#search(query, case_type: :smart) ⇒ Items
Search Items for a string (title and note)
32 33 34 |
# File 'lib/doing/items/filter.rb', line 32 def search(query, case_type: :smart) WWID.new.fuzzy_filter_items(self, query, case_type: case_type) end |
#section?(section) ⇒ Boolean
Test if section already exists
19 20 21 22 |
# File 'lib/doing/items/sections.rb', line 19 def section?(section) section = section.is_a?(Section) ? section.title.downcase : section.downcase @sections.map { |i| i.title.downcase }.include?(section) end |
#section_titles ⇒ Array
List sections, title only
9 10 11 |
# File 'lib/doing/items/sections.rb', line 9 def section_titles @sections.map(&:title) end |
#tagged(tags, bool: :and) ⇒ Items
Search items by tags
46 47 48 |
# File 'lib/doing/items/filter.rb', line 46 def tagged(, bool: :and) WWID.new.filter_items(self, opt: { tag: , bool: bool }) end |
#to_s ⇒ Object
Output sections and items in Doing file format
63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/doing/items/items.rb', line 63 def to_s out = [] @sections.each do |section| out.push(section.original) items = in_section(section.title).sort_by { |i| [i.date, i.title] } items.reverse! if Doing.setting('doing_file_sort').normalize_order == :desc items.each { |item| out.push(item.to_s) } end out.join("\n") end |
#update_item(old_item, new_item) ⇒ Object
Update an item in the index with a modified item
23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/doing/items/modify.rb', line 23 def update_item(old_item, new_item) s_idx = index { |item| item.equal?(old_item) } raise ItemNotFound, 'Unable to find item in index, did it mutate?' unless s_idx return if fetch(s_idx).equal?(new_item) self[s_idx] = new_item Doing.logger.count(:updated) Doing.logger.info('Entry updated:', self[s_idx].title.trunc(60)) new_item end |