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 the Reminder table of a Reminders database

Defined Under Namespace

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

Constant Summary collapse

ITIME =

Epoch + 31 years

978307200
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 }
NAME =
'icalPal'
VERSION =
'3.1.1'

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.



14
15
16
# File 'lib/icalPal.rb', line 14

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, stores, calendars, events, or tasks

Returns:

  • (Class)

    The subclass of ICalPal



21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/icalPal.rb', line 21

def self.call(klass)
  case klass
  when 'accounts' then Store
  when 'stores' 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) ⇒ Object

Load data



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

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)
    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_with_index { |i, j| rows[j] = i }
    stmt.close

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

  rescue SQLite3::BusyException => e
    $log.error("Non-fatal error closing database #{db.filename}")

  rescue SQLite3::CantOpenException => e
    $log.debug("Can't open #{db_file}")

  rescue SQLite3::SQLException => e
    $log.info("#{db_file}: #{e}")

  rescue SQLite3::Exception => e
    abort("#{db_file}: #{e}")

  end

  return(rows)
end

.nth(n, dow, m) ⇒ RDT

Get the n‘th dow in month m

Parameters:

  • n (Integer)

    Integer between -4 and +4

  • dow (Array)

    Days of the week

  • m (RDT)

    The RDT with the year and month we’re searching

Returns:

  • (RDT)

    The resulting day



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/icalPal.rb', line 150

def self.nth(n, dow, m)
  # Get the number of days in the month
  a = [ ICalPal::RDT.new(m.year, m.month, 1) ] # First of this month
  a[1] = (a[0] >> 1) - 1      # First of next month, minus 1 day

  # 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.any?(i.wday)
    return i if j == n
  end
end

Instance Method Details

#[](k) ⇒ Object



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

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

#[]=(k, v) ⇒ Object



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

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

#initialize(obj) ⇒ Object

Parameters:

  • obj (ICalPal)

    A Store or Calendar



76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/icalPal.rb', line 76

def initialize(obj)
  obj['type'] = EventKit::EKSourceType.find_index { |i| i[:name] == 'Subscribed' } if obj['subcal_url']
  type = EventKit::EKSourceType[obj['type']]

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

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

  @self = obj
end

#keysObject



177
# File 'lib/icalPal.rb', line 177

def keys() @self.keys end

#to_csv(headers) ⇒ CSV::Row

Create a new CSV::Row with values from self. Newlines are replaced with ‘n’ to ensure each Row is a single line of text.

Parameters:

  • headers (Array)

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

Returns:

  • (CSV::Row)

    The Store, Calendar, or CalendarItem as a CSV::Row



94
95
96
97
98
99
# File 'lib/icalPal.rb', line 94

def to_csv(headers)
  values = []
  headers.each { |h| values.push(@self[h].respond_to?(:gsub)? @self[h].gsub(/\n/, '\n') : @self[h]) }

  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>.



105
106
107
108
109
110
# File 'lib/icalPal.rb', line 105

def to_xml
  retval = ""
  @self.keys.each { |k| retval += xmlify(k, @self[k]) }

  retval
end

#valuesObject



178
# File 'lib/icalPal.rb', line 178

def values() @self.values end

#xmlify(key, value) ⇒ String

Convert a key/value pair to XML. The value should be nil, String, Integer, Array, or ICalPal::RDT

Parameters:

  • key

    The key

  • value

    The value

Returns:

  • (String)

    The key/value pair in a simple XML format



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/icalPal.rb', line 118

def xmlify(key, value)
  case value
  # Nil
  when NilClass then return("<#{key}/>")

  # String, Integer
  when String then return("<#{key}>#{value}</#{key}>")
  when Integer then return("<#{key}>#{value}</#{key}>")

  # Array
  when Array then
    # Treat empty arrays as nil values
    return(xmlify(key, nil)) if value[0] == nil 

    retval = ""
    value.each { |x| retval += xmlify("#{key}0", x) }
    return("<#{key}>#{retval}</#{key}>")

  # RDT
  when ICalPal::RDT then return("<#{key}>#{value.to_s}</#{key}>")

  # Unknown
  else return("<#{key}>#{value.to_s}</#{key}>")
  end
end