Class: When::V::Event

Inherits:
Root show all
Extended by:
Parts::Resource::Pool
Defined in:
lib/when_exe/icalendar.rb,
lib/when_exe/icalendar.rb,
lib/when_exe/google_api.rb,
lib/when_exe/obsolete/googlecalendar.rb

Overview

Eventを定義する

BEGIN:VEVENT...END:VEVENT のブロックに対応

Direct Known Subclasses

Alarm, Freebusy, Journal, TimezoneProperty, Todo

Defined Under Namespace

Classes: Enumerator

Constant Summary collapse

Properties =
[['dtstamp', 'uid', 'dtstart'], [],
                 ['class', 'created', 'description', 'geo',
'last_modified', 'location', 'organizer', 'priority',
'seq', 'status', 'summary', 'transp',
'url', 'recurid', 'dtend', 'duration'], [],
                 ['rrule',
'attach', 'attendee', 'categories', 'comment', 'contact',
'exdate', 'exevent', 'rstatus', 'related',
'resources', 'rdate']]
RegisteredNotes =

Classes = [V::Root, V::Alarm]

{
  'term'      => 'SolarTerms',
  'phase'     => 'LunarPhases',
  'easter'    => 'Christian',
  'christmas' => 'Christian'
}
RegisteredNoteMethods =
/\A(#{RegisteredNotes.keys.sort.reverse.join('|')})/
DayOfWeek =
%w(SU MO TU WE TH FR SA)
Classes =
[Root, Alarm]

Constants inherited from Root

Root::AwareProperties, Root::DefaultOptional, Root::DefaultUnique

Constants included from Parts::Resource

Parts::Resource::ConstList, Parts::Resource::ConstTypes, Parts::Resource::IRIDecode, Parts::Resource::IRIDecodeTable, Parts::Resource::IRIEncode, Parts::Resource::IRIEncodeTable, Parts::Resource::IRIHeader, Parts::Resource::LabelProperty

Constants included from Namespace

Namespace::DC, Namespace::DCQ, Namespace::DCT, Namespace::FOAF, Namespace::OWL, Namespace::RDF, Namespace::RDFC, Namespace::RDFS, Namespace::RSS, Namespace::XSD

Instance Attribute Summary collapse

Attributes inherited from Root

#calscale, #property

Attributes included from Parts::Resource

#_pool, #child, #keys, #locale, #namespace

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Parts::Resource::Pool

[], []=, _pool, _setup_, pool_keys

Methods included from Parts::Resource::Synchronize

#synchronize

Methods inherited from Root

#_enumerator, #include?

Methods included from Parts::Resource

#[], #^, _abbreviation_to_iri, _decode, _encode, _extract_prefix, _instance, _instantiate, _parse, _path_with_prefix, _replace_tags, _simplify_path, base_uri, #enum_for, #hierarchy, #include?, #included?, #iri, #leaf?, #m17n, #map, #parent, #registered?, root_dir

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class When::Parts::Resource

Instance Attribute Details

#dtendWhen::TM::TemporalPosition, When::Parts::GeometricComplex (readonly)

DTEND Property



703
704
705
# File 'lib/when_exe/icalendar.rb', line 703

def dtend
  @dtend
end

#dtstartWhen::TM::TemporalPosition, When::Parts::GeometricComplex (readonly)

DTSTART Property



697
698
699
# File 'lib/when_exe/icalendar.rb', line 697

def dtstart
  @dtstart
end

#durationWhen::TM::Duration (readonly)

Note:

DTSTART Property が保持する When::TM::TemporalPosition の分解能で識別できない 時間差はイベント継続中とみなすので、例えば分解能が DAY の場合、DURATION Porperty に When.Duration(‘P1D’)と指定する必要はない。 DTEND Property が指定された場合、DURATION Property に変換して保持する。

DURATION Property

Returns:



715
716
717
# File 'lib/when_exe/icalendar.rb', line 715

def duration
  @duration
end

#exdateWhen::Parts::GeometricComplex (readonly)

EXDATE Property



721
722
723
# File 'lib/when_exe/icalendar.rb', line 721

def exdate
  @exdate
end

#first_occurrenceString (readonly)

Note:

RFC 5545 では ‘Include’ となっているが、それ以外の振る舞いが可能なように拡張。

DTSTART Property を first occurrence とするか

Returns:

  • (String)
    ‘Include’ - first occurrence とする
    ‘Exclude’ - first occurrence しない
    それ以外 - RRULE により該当する場合に first occurrence とする


745
746
747
# File 'lib/when_exe/icalendar.rb', line 745

def first_occurrence
  @first_occurrence
end

#google_api_propsHash (readonly)

イベントのプロパティ

Returns:

  • (Hash)


93
94
95
# File 'lib/when_exe/google_api.rb', line 93

def google_api_props
  @google_api_props
end

#rdateArray<When::TM::TemporalPosition, When::Parts::GeometricComplex> (readonly)

Note:

RRULE の COUNT が指定されている場合、後で途中の系列を抜き出すような指定をされても よいように、Enumerator 生成時にCOUNT分の計算をして RDATE Property に登録する。 このため、COUNTに大きな値を指定すると、Enumerator 生成に予想外の時間がかかることが ある。

RDATE Property



733
734
735
# File 'lib/when_exe/icalendar.rb', line 733

def rdate
  @rdate
end

#rruleHash (readonly)

Note:

iCalendar の RRULE を Hash に展開したものを保持している。 RRULE は、年のサイクルや7日以外の日のサイクルおよび夏時間の切り替えを 扱えるように RFC 5545 から拡張されている。

RRULE Property

Returns:

  • (Hash)


691
692
693
# File 'lib/when_exe/icalendar.rb', line 691

def rrule
  @rrule
end

#summaryString, When::BasicTypes::M17n (readonly)

SUMMARY Property



680
681
682
# File 'lib/when_exe/icalendar.rb', line 680

def summary
  @summary
end

Class Method Details

._setup_(default_until = nil) ⇒ Object

Note:

RRULE の条件が成立しない場合に無限ループにおちいることを避けるため 他に指定がなくとも、計算を打ち切るようにしている。その打ち切り時間 (When.now + default_until)を本メソッドで指定している。 default_until の指定がない場合、default_until は 1000年と解釈する。

Note:

本メソッドでマルチスレッド対応の管理変数の初期化を行っている。 このため、本メソッド自体はスレッドセーフでない。

When::V::Event Class のグローバルな設定を行う

Parameters:



559
560
561
562
563
# File 'lib/when_exe/icalendar.rb', line 559

def _setup_(default_until=nil)
  @_lock_ = Mutex.new if When.multi_thread
  @_pool = {}
  @default_until = default_until
end

._setup_infoHash

設定情報を取得する

Returns:

  • (Hash)

    設定情報



569
570
571
# File 'lib/when_exe/icalendar.rb', line 569

def _setup_info
  {:until => default_until}
end

.default_untilWhen::TM::IntervalLength

最大打ち切り時間



576
577
578
# File 'lib/when_exe/icalendar.rb', line 576

def default_until
  @default_until ||= 1000*(When::TM::Duration::YEAR / When::TM::Duration::DAY)
end

.gcal2ical(gprops) ⇒ Hash

GoogleCalendar のプロパティを iCalendar のプロパティに変換する

Parameters:

  • gprops (Hash)

    GoogleCalendar のプロパティ

Returns:

  • (Hash)

    iCalendar のプロパティ



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/when_exe/google_api.rb', line 103

def gcal2ical(gprops)
  iprops = {}
  gprops.each_pair do |key, value|
    case key
    when :start, :end
      date  = 'VALUE=DATE'
      if value.key?(:date)
        date += ':' + value[:date].strftime('%Y%m%d')
      else
        date += '-TIME'
        date += ':' + value[:date_time].strftime('%Y%m%dT%H%M%S')
        date += value[:date_time].strftime('%z') unless value[:time_zone]
      end
      date.sub!(':', ";TZID=#{value[:time_zone]}:") if value.key?(:time_zone)
      iprops['dt' + key.to_s] = date
    when :recurrence
      value.map do |line|
        tag, rule = line.split(':', 2)
        tag.downcase!
        if iprops.key?(tag)
          iprops[tag] = Array(iprops[tag]) + [rule]
        else
          iprops[tag] = rule
        end
      end
    when :i_cal_uid
      iprops['uid'] = value
    when Symbol
      iprops[key.to_s] = value
    end
  end
  iprops
end

.iterator_for_ISO8601(base, duration, delayed_options) ⇒ When::Parts::Enumerator

ISO8601へ埋め込まれた指定に対応する iterator を生成する

Parameters:

Returns:



588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
# File 'lib/when_exe/icalendar.rb', line 588

def iterator_for_ISO8601(base, duration, delayed_options)
  duration.to_s =~ /\A-?P(\d+)([YM])\z/
  event_options = {'rrule'=>
    case $2
    when 'Y' ; {'FREQ'=>'YEARLY',  'INTERVAL'=>$1.to_i}
    when 'M' ; {'FREQ'=>'MONTHLY', 'INTERVAL'=>$1.to_i}
    else     ; duration ? {'FREQ'=>duration.set_repeat(false).abs} : {'FREQ'=>'YEARLY'}
    end
  }
  residue_options = delayed_options[:residue]
  frame_len       = base.frame.indices.length
  if residue_options
    event_options['rrule'].update(_byyear(residue_options.delete(frame_len-2))) if residue_options[frame_len-2]
    event_options['rrule'].update(_byday(residue_options.delete(frame_len) )) if residue_options[frame_len]
    delayed_options.delete(:residue)
  end
  if base.precision == When::MONTH && event_options['rrule']['FREQ'] == 'YEARLY'
    event_options['rrule'].update({'BYMONTH'=>base[When::MONTH]})
    base = base.floor if event_options['rrule']['BYMONTHDAY']
  end
  case base
  when When::TM::TemporalPosition ; event_options.update({'dtstart'  =>base})
  else                            ; event_options.update({'dtstart'  =>base.first,
                                                          'duration' =>base.last-base.first})
  end
  event_options['duration']  = delayed_options.delete(:duration) if delayed_options[:duration]
  behavior_options           = {'1st'=>delayed_options.delete(:first) || "don't care"}
  behavior_options[:delayed] = delayed_options unless delayed_options.empty?
  behavior_options[:direction] = :reverse if duration && duration.sign < 0
  return new(event_options).enum_for(event_options['dtstart'], behavior_options)
end

Instance Method Details

#_enumerator_list(args) ⇒ Object



805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
# File 'lib/when_exe/icalendar.rb', line 805

def _enumerator_list(args)
  options = args[-1]
  rdate = @rdate.dup
  options[:exdate]  = @exdate.dup if @exdate
  options[:exevent] = @exevent.map {|v| self[v]} if @exevent
  case (options['1st'] || @first_occurrence).capitalize
  when 'Include' ; rdate.unshift(@duration ? When::Parts::GeometricComplex.new(@dtstart, @duration) : @dtstart)
  when 'Exclude' ; options[:exdate] |= @dtstart
  end

  # 配下の Enumerator の初期化
  enumerators = []
  @rrule.each do |rrule|
    if @due && !(rrule['UNTIL'] && rrule['UNTIL'] <= @due)
      rrule = rrule.dup
      rrule['UNTIL'] = @due
    end
    if rrule['COUNT']
      Event::Enumerator.new(self, rrule, @dtstart, @duration, @dtstart, options).each {|date| rdate << date }
    else
      enumerators << Event::Enumerator.new(self, rrule, @dtstart, @duration, *args)
    end
  end

  enumerators.unshift(When::Parts::Enumerator::Array.new(self, rdate, *args[1..-1])) if (rdate.length > 0)

  return enumerators
end

#dtstopWhen::TM::TemporalPosition, When::Parts::GeometricComplex

Note:

無限に続く可能性がある場合、When::TimeValue::Max(+Infinity)

最後のイベント



762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
# File 'lib/when_exe/icalendar.rb', line 762

def dtstop
  return @dtstop if (@dtstop)

  @dtstop = @dtstart
  @rdate.each do |date|
    @dtstop = date if (date > @dtstop)
  end
  @rrule.each do |rrule|
    unless (rrule['UNTIL'])
      @dtstop = When::TimeValue::Max
      break
    end
    @dtstop = rrule['UNTIL'] if (rrule['UNTIL'] > @dtstop)
  end
  return @dtstop
end

#eachEnumerator #each(range, count_limit = nil) ⇒ Enumerator #each(first, direction, count_limit) ⇒ Enumerator

Note:

block が与えられている場合、yield する。

順次実行

Overloads:

  • #each(range, count_limit = nil) ⇒ Enumerator

    Parameters:

    • range (Range, When::Parts::GeometricComplex)

      始点-range.first, 終点-range.last

    • count_limit (Integer) (defaults to: nil)

      繰り返し回数(デフォルトは指定なし)

  • #each(first, direction, count_limit) ⇒ Enumerator

    Parameters:

    • first (When::TM::TemporalPosition)

      始点

    • direction (Symbol)

      :forward - 昇順, :reverse - 降順 (optionsで渡してもよい)

    • count_limit (Integer)

      繰り返し回数(デフォルトは指定なし, optionsで渡してもよい)

Returns:



796
797
798
799
800
801
802
# File 'lib/when_exe/icalendar.rb', line 796

def each(*args, &block)
  if args.length > 0
    super
  else
    super(@dtstart, &block)
  end
end

#labelString

ユニーク識別名 - UID Property をユニーク識別名とする。

Returns:



751
752
753
# File 'lib/when_exe/icalendar.rb', line 751

def label
  @label ||= @property['uid'].object
end

#to_gcalevent(cal) ⇒ GoogleCalendar::Event Also known as: gcalevent

GoogleCalendar::Event オブジェクトへの変換

Parameters:

Returns:



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/when_exe/obsolete/googlecalendar.rb', line 124

def to_gcalevent(cal)
  event = cal.create_event
  event.title = summary     if respond_to?(:summary)
  event.desc  = description if respond_to?(:description)
  event.where = location    if respond_to?(:location)
  if rrule.size == 0
    event.st  = dtstart.to_time
    event.en  = dtend.to_time
  else
    event.recurrence =
      (['RRULE:' + property['rrule'][0].object] +
       ['dtstart', 'dtend'].map {|key|
         value = property[key].attribute['.']
         key.upcase + (value =~ /=/ ? ';' : ':') + value
       }).join("\n") + "\n"
  end
  event
end