Class: Doing::Item

Inherits:
Object
  • Object
show all
Defined in:
lib/doing/item.rb

Overview

This class describes a single WWID item

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(date, title, section, note = nil) ⇒ Item

Initialize an item with date, title, section, and optional note

Parameters:

  • date (Time)

    The item's start date

  • title (String)

    The title

  • section (String)

    The section to which the item belongs

  • note (Array or String) (defaults to: nil)

    The note (optional)



23
24
25
26
27
28
# File 'lib/doing/item.rb', line 23

def initialize(date, title, section, note = nil)
  @date = date.is_a?(Time) ? date : Time.parse(date)
  @title = title
  @section = section
  @note = Note.new(note)
end

Instance Attribute Details

#dateObject

include Amatch



10
11
12
# File 'lib/doing/item.rb', line 10

def date
  @date
end

#noteObject

include Amatch



10
11
12
# File 'lib/doing/item.rb', line 10

def note
  @note
end

#sectionObject

include Amatch



10
11
12
# File 'lib/doing/item.rb', line 10

def section
  @section
end

#titleObject

include Amatch



10
11
12
# File 'lib/doing/item.rb', line 10

def title
  @title
end

Instance Method Details

#end_dateTime

Get the value of the item's @done tag

Returns:

  • (Time)

    @done value



49
50
51
# File 'lib/doing/item.rb', line 49

def end_date
  @end_date ||= Time.parse(Regexp.last_match(1)) if @title =~ /@done\((\d{4}-\d\d-\d\d \d\d:\d\d.*?)\)/
end

#equal?(other) ⇒ Boolean

Test for equality between items

Parameters:

  • other (Item)

    The other item

Returns:

  • (Boolean)

    is equal?



64
65
66
67
68
69
70
71
72
# File 'lib/doing/item.rb', line 64

def equal?(other)
  return false if @title.strip != other.title.strip

  return false if @date != other.date

  return false unless @note.equal?(other.note)

  true
end

#hash_idObject



53
54
55
# File 'lib/doing/item.rb', line 53

def hash_id
  (@date.to_s + @title + @section + @note.join(' ')).hash
end

#intervalObject

Get the difference between the item's start date and the value of its @done tag (if present)

Returns:

  • Interval in seconds



40
41
42
# File 'lib/doing/item.rb', line 40

def interval
  @interval ||= calc_interval
end

#overlapping_time?(item_b) ⇒ Boolean

Test if the interval between start date and @done value overlaps with another item's

Parameters:

  • item_b (Item)

    The item to compare

Returns:

  • (Boolean)

    overlaps?



93
94
95
96
97
98
99
100
101
102
103
# File 'lib/doing/item.rb', line 93

def overlapping_time?(item_b)
  return true if same_time?(item_b)

  start_a = date
  interval = interval
  end_a = interval ? start_a + interval.to_i : start_a
  start_b = item_b.date
  interval = item_b.interval
  end_b = interval ? start_b + interval.to_i : start_b
  (start_a >= start_b && start_a <= end_b) || (end_a >= start_b && end_a <= end_b) || (start_a < start_b && end_a > end_b)
end

#same_time?(item_b) ⇒ Boolean

Test if two items occur at the same time (same start date and equal duration)

Parameters:

  • item_b (Item)

    The item to compare

Returns:

  • (Boolean)

    is equal?



81
82
83
# File 'lib/doing/item.rb', line 81

def same_time?(item_b)
  date == item_b.date ? interval == item_b.interval : false
end

#search(search, distance: 3, negate: false, case_type: :smart, fuzzy: false) ⇒ Boolean

Test if item matches search string

Parameters:

  • search (String)

    The search string

  • negate (Boolean) (defaults to: false)

    negate results

  • case_type (Symbol) (defaults to: :smart)

    The case-sensitivity type (:sensitive, :ignore, :smart)

Returns:

  • (Boolean)

    matches search criteria



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/doing/item.rb', line 162

def search(search, distance: 3, negate: false, case_type: :smart, fuzzy: false)
  text = @title + @note.to_s
  matches = text =~ search.to_rx(distance: distance, case_type: case_type)

  # if search.is_rx? || !fuzzy
  #   matches = text =~ search.to_rx(distance: distance, case_type: case_type)
  # else
  #   distance = 0.25 if distance > 1
  #   score = if (case_type == :smart && search !~ /[A-Z]/) || case_type == :ignore
  #             text.downcase.pair_distance_similar(search.downcase)
  #           else
  #             score = text.pair_distance_similar(search)
  #           end

  #   if score >= distance
  #     matches = true
  #     Doing.logger.debug('Fuzzy Match:', %(#{@title}, "#{search}" #{score}))
  #   end
  # end

  negate ? !matches : matches
end

#should_finish?Boolean

Returns:

  • (Boolean)


185
186
187
# File 'lib/doing/item.rb', line 185

def should_finish?
  should?('never_finish')
end

#should_time?Boolean

Returns:

  • (Boolean)


189
190
191
# File 'lib/doing/item.rb', line 189

def should_time?
  should?('never_time')
end

#tag(tag, value: nil, remove: false, rename_to: nil, regex: false) ⇒ Object

Add (or remove) tags from the title of the item

Parameters:

  • tag (String)

    The tag to add

  • value (String) (defaults to: nil)

    A value to include as @tag(value)

  • remove (Boolean) (defaults to: false)

    if true remove instead of adding

  • rename_to (String) (defaults to: nil)

    if not nil, rename target tag to this tag name

  • regex (Boolean) (defaults to: false)

    treat target tag string as regex pattern



114
115
116
# File 'lib/doing/item.rb', line 114

def tag(tag, value: nil, remove: false, rename_to: nil, regex: false)
  @title.tag!(tag, value: value, remove: remove, rename_to: rename_to, regex: regex).strip!
end

#tagsArray

Get a list of tags on the item

Returns:

  • (Array)

    array of tags (no values)



123
124
125
# File 'lib/doing/item.rb', line 123

def tags
  @title.scan(/(?<= |\A)@([^\s(]+)/).map {|tag| tag[0]}.sort.uniq
end

#tags?(tags, bool = :and, negate: false) ⇒ Boolean

Test if item contains tag(s)

Parameters:

  • tags (Array or String)

    The tags to test. Can be an array or a comma-separated string.

  • bool (Symbol) (defaults to: :and)

    The boolean to use for multiple tags (:and, :or, :not)

  • negate (Boolean) (defaults to: false)

    negate the result?

Returns:

  • (Boolean)

    true if tag/bool combination passes



136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/doing/item.rb', line 136

def tags?(tags, bool = :and, negate: false)
  tags = split_tags(tags)
  bool = bool.normalize_bool

  matches = case bool
            when :and
              all_tags?(tags)
            when :not
              no_tags?(tags)
            else
              any_tags?(tags)
            end
  negate ? !matches : matches
end