Class: Treat::Workers::Extractors::Time::Nickel

Inherits:
Object
  • Object
show all
Defined in:
lib/treat/workers/extractors/time/nickel.rb

Overview

Time extraction using a pure Ruby natural language time parser.

Class Method Summary collapse

Class Method Details

.remove_time_from_ancestors(entity, time) ⇒ Object

Keeps the lowest-level time annotations that do not conflict with a higher time annotation. Returns true if the entity conflicts with a higher-level time annotation.



84
85
86
87
88
89
90
91
92
# File 'lib/treat/workers/extractors/time/nickel.rb', line 84

def self.remove_time_from_ancestors(entity, time)
  entity.ancestors_with_type(:phrase).each do |a|
    next if !a.has?(:time)
    return false unless a.get(:time).to_s == time.to_s
    a.unset(:time, :time_recurrence, 
    :time_recurrence_interval, :end_time)
  end
  true
end

.time(entity, options = {}) ⇒ Object

Extract time information from a bit of text.

In addition to the :time annotation, this class will provided:

  • time_recurrence: frequency of recurrence in words*.

  • time_recurrence_interval: frequency of recurrence in days.

  • start_time: a DateTime object representing the beginning of an event.

  • end_time: a DateTime object representing the end of an event.

Examples of values for time_recurrence are:

  • single: “lunch with megan tomorrow at noon”

  • daily: “Art exhibit until March 1st”

  • weekly: “math class every wed from 8-11am”

  • daymonthly: “open bar at joes the first friday of every month”

  • datemonthly: “pay credit card bill on the 22nd of each month”



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/treat/workers/extractors/time/nickel.rb', line 27

def self.time(entity, options = {})
  
  s = entity.to_s
  return if s =~ /^[0-9]+$/
  
  n = nil
  
  begin
    silence_warnings { n = ::Nickel.parse(s.to_s.strip) }
  rescue
    return
  end
  
  occ = n.occurrences[0]
  
  return unless occ

  rec = occ.type.to_s.gsub('single', 'once').intern
  time_recurrence = rec
  interval = occ.interval ?
  occ.interval : :none
  time_recurrence_interval = interval


  s = [occ.start_date, occ.start_time]
  ds = [s[0].year, s[0].month, s[0].day] if s[0]
  ts = [s[1].hour, s[1].minute, s[1].second] if s[1]

  e = [occ.end_date, occ.end_time]
  de = [e[0].year, e[0].month, e[0].day] if e[0]
  te = [e[1].hour, e[1].minute, e[1].second] if e[1]

  start_time = ::DateTime.civil(*ds) if ds && !ts
  start_time = ::DateTime.civil(*ds, *ts) if ds && ts
  end_time = ::DateTime.civil(*de) if de && !te
  end_time = ::DateTime.civil(*de, *te) if de && te
  
  return unless start_time

  if entity.has_parent? && 
    remove_time_from_ancestors(entity, start_time)
    nil
  else
    entity.set :time_recurrence,
    time_recurrence
    entity.set :time_recurrence_interval,
    time_recurrence_interval
    entity.set :end_time, end_time if end_time
    start_time
  end
  
end