Class: CoachZed::FeedReader

Inherits:
Object
  • Object
show all
Defined in:
lib/coach_zed/feed_reader.rb,
sig/coach_zed.rbs

Defined Under Namespace

Classes: Event

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(feed_content) ⇒ FeedReader

Returns a new instance of FeedReader.

Parameters:

  • (String)


25
26
27
# File 'lib/coach_zed/feed_reader.rb', line 25

def initialize(feed_content)
  @feed_content = feed_content
end

Instance Attribute Details

#feed_contentString (readonly)

Returns the value of attribute feed_content.

Returns:

  • (String)


29
30
31
# File 'lib/coach_zed/feed_reader.rb', line 29

def feed_content
  @feed_content
end

Class Method Details

.load(path) ⇒ Array[Event]

Parameters:

  • (Pathname, String)

Returns:



17
18
19
# File 'lib/coach_zed/feed_reader.rb', line 17

def self.load(path)
  new(File.read(path.to_s)).events
end

.load_existing(path) ⇒ FeedReader

Parameters:

  • (Pathname, String)

Returns:



21
22
23
# File 'lib/coach_zed/feed_reader.rb', line 21

def self.load_existing(path)
  new(File.read(path.to_s))
end

Instance Method Details

#eventsArray[Event]

Returns:



31
32
33
# File 'lib/coach_zed/feed_reader.rb', line 31

def events
  @events ||= parse_events
end

#last_dateDate?

Returns:

  • (Date, nil)


35
36
37
# File 'lib/coach_zed/feed_reader.rb', line 35

def last_date
  events.map(&:date).compact.max
end

#parse_date(event_text) ⇒ Date?

Parameters:

  • event_text (String)

Returns:

  • (Date, nil)


74
75
76
77
78
79
# File 'lib/coach_zed/feed_reader.rb', line 74

def parse_date(event_text)
  value = parse_line(event_text, /^DTSTART;VALUE=DATE:(\d{8})$/)
  return if value.nil?

  Date.strptime(value, "%Y%m%d")
end

#parse_eventsArray[Event]

Returns:



60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/coach_zed/feed_reader.rb', line 60

def parse_events
  blocks = feed_content.split(/BEGIN:VEVENT\r?\n/).drop(1)
  blocks.filter_map do |block|
    event_text = block.split("END:VEVENT").first
    next if event_text.nil?

    Event.new(
      date: parse_date(event_text),
      summary: parse_line(event_text, /^SUMMARY:(.*)$/),
      description: unescape(parse_line(event_text, /^DESCRIPTION:(.*)$/))
    )
  end
end

#parse_line(event_text, pattern) ⇒ String?

Parameters:

  • event_text (String)
  • pattern (Regexp)

Returns:

  • (String, nil)


81
82
83
84
# File 'lib/coach_zed/feed_reader.rb', line 81

def parse_line(event_text, pattern)
  match = event_text.match(pattern)
  match && match[1]
end

#recent_events(limit_days: 28) ⇒ Array[Event]

Parameters:

  • limit_days: (Integer) (defaults to: 28)

Returns:



39
40
41
42
43
44
45
# File 'lib/coach_zed/feed_reader.rb', line 39

def recent_events(limit_days: 28)
  last = last_date
  cutoff = last ? last - (limit_days - 1) : nil
  return events if cutoff.nil?

  events.select { |event| event.date && event.date >= cutoff }
end

#to_context(limit_days: 28) ⇒ String

Parameters:

  • limit_days: (Integer) (defaults to: 28)

Returns:

  • (String)


47
48
49
50
51
52
53
54
55
56
# File 'lib/coach_zed/feed_reader.rb', line 47

def to_context(limit_days: 28)
  recent_events(limit_days:).map do |event|
    # @type var pieces: Array[String]
    pieces = []
    pieces << event.date.iso8601 if event.date
    pieces << event.summary if event.summary && !event.summary.empty?
    pieces << event.description if event.description && !event.description.empty?
    pieces.join(" | ")
  end.join("\n")
end

#unescape(value) ⇒ String

Parameters:

  • value (String, nil)

Returns:

  • (String)


86
87
88
89
90
91
92
# File 'lib/coach_zed/feed_reader.rb', line 86

def unescape(value)
  value.to_s
    .gsub("\\n", "\n")
    .gsub("\\,", ",")
    .gsub("\\;", ";")
    .gsub("\\\\", "\\")
end