Module: ICalPal

Included in:
Calendar, Event, Reminder, Store
Defined in:
lib/icalPal.rb,
lib/rdt.rb,
lib/event.rb,
lib/store.rb,
lib/options.rb,
lib/version.rb,
lib/calendar.rb,
lib/reminder.rb

Overview

Encapsulate the Store (accounts), Calendar and CalendarItem tables of a Calendar database, and Reminders (tasks) of a Reminders database

Defined Under Namespace

Classes: Calendar, Event, Options, RDT, Reminder, Store

Constant Summary collapse

ITIME =

Epoch + 31 years (Mon Jan 1 00:00:00 UTC 2001)

978_307_200
DOW =

Days of the week abbreviations used in recurrence rules

SU, MO, TU, WE, TH, FR, SA

{ SU: 0, MO: 1, TU: 2, WE: 3, TH: 4, FR: 5, SA: 6 }.freeze
NAME =
'icalPal'.freeze
VERSION =
'4.2.0'.freeze

Instance Attribute Summary collapse

Accessors collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#selfObject (readonly)

Returns the value of attribute self.



7
8
9
# File 'lib/icalPal.rb', line 7

def self
  @self
end

Class Method Details

.call(klass) ⇒ Class

Dynamic instantiation of our classes based on the command being run

Parameters:

  • klass (String)

    One of accounts, calendars, events, or tasks

Returns:

  • (Class)

    The subclass of ICalPal



14
15
16
17
18
19
20
21
22
23
24
# File 'lib/icalPal.rb', line 14

def self.call(klass)
  case klass
  when 'accounts' then Store
  when 'calendars' then Calendar
  when 'events' then Event
  when 'tasks' then Reminder
  else
    $log.fatal("Unknown class: #{klass}")
    exit
  end
end

.load_data(db_file, q) ⇒ Array<Hash>

Load data from a database

Parameters:

  • db_file (String)

    Path to the database file

  • q (String)

    The query to run

Returns:

  • (Array<Hash>)

    Array of rows returned by the query



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
# File 'lib/icalPal.rb', line 31

def self.load_data(db_file, q)
  $log.debug(q.gsub("\n", ' '))

  rows = []

  begin
    # Open the database
    $log.debug("Opening database: #{db_file}")
    db = SQLite3::Database.new(db_file, { readonly: true, results_as_hash: true })

    # Prepare the query
    stmt = db.prepare(q)

    # Check for "list" and "all" pseudo-properties
    abort(stmt.columns.sort.join(' ')) if $opts[:props].any? 'list'
    $opts[:props] = stmt.columns - $opts[:eep] if $opts[:props].any? 'all'

    # Iterate the SQLite3::ResultSet once
    stmt.execute.each { |i| rows.push(i) }
    stmt.close

    # Close the database
    db.close
    $log.debug("Closed #{db_file}")
  end

  rows
end

.nth(n, dow, m) ⇒ RDT

Get the n‘th dow in month m

Parameters:

  • n (Integer)

    Integer between -4 and +4

  • dow (Integer)

    Day of the week

  • m (RDT)

    The RDT with the year and month we’re searching

Returns:

  • (RDT)

    The resulting day



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/icalPal.rb', line 110

def self.nth(n, dow, m)
  # Get the number of days in the month by advancing to the first of
  # the next month, then going back one day
  a = [ RDT.new(m.year, m.month, 1, m.hour, m.min, m.sec, m.zone) ]
  a[1] = (a[0] >> 1) - 1

  # Reverse it if going backwards
  a.reverse! if n.negative?
  step = a[1] <=> a[0]

  j = 0
  a[0].step(a[1], step) do |i|
    j += step if dow == i.wday
    return i if j == n
  end
end

Instance Method Details

#<=>(other) ⇒ Object

If either self or other is nil, but not both, the nil object is always less than

See Also:

  • Array.<=>


156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/icalPal.rb', line 156

def <=>(other)
  $sort_attrs.each do |s|
    next if self[s] == other[s]

    # nil is always less than
    return -1 if other[s].nil?
    return 1 if self[s].nil?

    return -1 if self[s] < other[s]
    return 1 if self[s] > other[s]
  end

  0
end

#[](k) ⇒ Object



136
137
138
# File 'lib/icalPal.rb', line 136

def [](k)
  @self[k]
end

#[]=(k, v) ⇒ Object



140
141
142
# File 'lib/icalPal.rb', line 140

def []=(k, v)
  @self[k] = v
end

#dumpArray<String>

Like inspect, but easier for humans to read

Returns:

  • (Array<String>)

    @self as a key=value array, sorted by key



174
175
176
# File 'lib/icalPal.rb', line 174

def dump
  @self.keys.sort.map { |k| "#{k}: #{@self[k]}" }
end

#initialize(obj) ⇒ Object

Initialize fields common to all ICalPal classes

Parameters:

  • obj (ICalPal)

    An Store, Calendar, Event, or Reminder



63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/icalPal.rb', line 63

def initialize(obj)
  @self = obj

  obj['store'] = obj['account']

  obj['type'] = EventKit::EKSourceType.find_index { |i| i[:name] == 'Subscribed' } if obj['subcal_url']
  return unless obj['type']

  type = EventKit::EKSourceType[obj['type']]

  obj['type'] = type[:name]
  obj['color'] ||= type[:color]
  obj['symbolic_color_name'] ||= type[:color]
end

#keysObject



144
145
146
# File 'lib/icalPal.rb', line 144

def keys
  @self.keys
end

#to_csv(headers) ⇒ CSV::Row

Create a new CSV::Row with values from self. Control characters are escaped to ensure they are not interpreted by the terminal.

Reminder as a CSV::Row

Parameters:

  • headers (Array)

    Key names used as the header row in a CSV::Table

Returns:

  • (CSV::Row)

    The Store, Calendar, CalendarItem, or



84
85
86
87
88
89
90
91
# File 'lib/icalPal.rb', line 84

def to_csv(headers)
  values = headers.map do |h|
    (@self[h].respond_to?(:gsub))?
      @self[h].gsub(/([[:cntrl:]])/) { |c| c.dump[1..-2] } : @self[h]
  end

  CSV::Row.new(headers, values)
end

#to_xmlString

Convert self to XML

Fields with empty values return <field/>.

Returns:

  • (String)

    All fields in a simple XML format: <field>value</field>.



97
98
99
100
101
102
# File 'lib/icalPal.rb', line 97

def to_xml
  retval = ''
  @self.each_key { |k| retval += xmlify(k, @self[k]) }

  retval
end

#valuesObject



148
149
150
# File 'lib/icalPal.rb', line 148

def values
  @self.values
end