riboseinc/ruby-vobject

View on GitHub
lib/vobject/vcalendar/propertyvalue.rb

Summary

Maintainability
D
2 days
Test Coverage
require "vobject"
require "vobject/propertyvalue"

module Vobject
  module Vcalendar
    module PropertyValue
      class Text < Vobject::PropertyValue
        class << self
          def escape(x)
            # temporarily escape \\ as \u007f, which is banned from text
            x.tr("\\", "\u007f").gsub(/\n/, "\\n").gsub(/,/, "\\,").
              gsub(/;/, "\\;").gsub(/\u007f/, "\\\\\\\\")
          end
        end

        def initialize(val)
          self.value = val
          self.type = "text"
        end

        def to_s
          Text.escape value
        end

        def to_hash
          value
        end
      end

      class ClassValue < Text
        def initialize(val)
          self.value = val
          self.type = "classvalue"
        end

        def to_hash
          value
        end
      end

      class TranspValue < Text
        def initialize(val)
          self.value = val
          self.type = "transpvalue"
        end

        def to_hash
          value
        end
      end

      class ActionValue < Text
        def initialize(val)
          self.value = val
          self.type = "actionvalue"
        end

        def to_hash
          value
        end
      end

      class MethodValue < Text
        def initialize(val)
          self.value = val
          self.type = "methodvalue"
        end

        def to_hash
          value
        end
      end

      class Busytype < Text
        def initialize(val)
          self.value = val
          self.type = "busytype"
        end

        def to_hash
          value
        end
      end

      class Color < Text
        def initialize(val)
          self.value = val
          self.type = "color"
        end

        def to_hash
          value
        end
      end

      class EventStatus < Text
        def initialize(val)
          self.value = val
          self.type = "eventstatus"
        end

        def to_hash
          value
        end
      end

      class Todostatus < Text
        def initialize(val)
          self.value = val
          self.type = "todostatus"
        end

        def to_hash
          value
        end
      end

      class Journalstatus < Text
        def initialize(val)
          self.value = val
          self.type = "journalstatus"
        end

        def to_hash
          value
        end
      end

      class Ianatoken < Text
        def initialize(val)
          self.value = val
          self.type = "ianatoken"
        end

        def to_hash
          value
        end
      end

      class Binary < Text
        def initialize(val)
          self.value = val
          self.type = "binary"
        end

        def to_hash
          value
        end
      end

      class Uri < Text
        def initialize(val)
          self.value = val
          self.type = "uri"
        end

        def to_hash
          value
        end
      end

      class Calscale < Vobject::PropertyValue
        def initialize(val)
          self.value = val
          self.type = "calscale"
        end

        def to_s
          value
        end

        def to_hash
          value
        end
      end

      class Float < Vobject::PropertyValue
        include Comparable
        def <=>(another)
          value <=> another.value
        end

        def initialize(val)
          self.value = val
          self.type = "float"
        end

        def to_s
          value.to_s
        end

        def to_hash
          value
        end
      end

      class Integer < Vobject::PropertyValue
        include Comparable
        def <=>(another)
          value <=> another.value
        end

        def initialize(val)
          self.value = val
          self.type = "integer"
        end

        def to_s
          value.to_s
        end

        def to_hash
          value
        end
      end

      class PercentComplete < Integer
        def initialize(val)
          self.value = val
          self.type = "percentcomplete"
        end

        def to_hash
          value
        end
      end

      class Priority < Integer
        def initialize(val)
          self.value = val
          self.type = "priority"
        end

        def to_hash
          value
        end
      end

      class Date < Vobject::PropertyValue
        include Comparable
        def <=>(another)
          value <=> another.value
        end

        def initialize(val)
          self.value = val
          self.type = "date"
        end

        def to_s
          sprintf("%04d%02d%02d", value.year, value.month, value.day)
        end

        def to_hash
          value
        end
      end

      class DateTimeLocal < Vobject::PropertyValue
        include Comparable
        def <=>(another)
          value[:time] <=> another.value[:time]
        end

        def initialize(val)
          self.value = val.clone
          # val consists of :time && :zone values. If :zone is empty, floating local time (i.e. system local time) is assumed
          self.type = "datetimeLocal"
          value[:time] = if val[:zone].nil? || val[:zone].empty?
                           ::Time.local(val[:year], val[:month], val[:day], val[:hour], val[:min], val[:sec])
                         else
                           ::Time.utc(val[:year], val[:month], val[:day], val[:hour], val[:min], val[:sec])
                         end
          value[:origtime] = value[:time]
        end

        def to_s
          # ret = sprintf("%04d%02d%02dT%02d%02d%02d", value[:year], value[:month], value[:day], value[:hour], value[:min], value[:sec])
          ret = sprintf("%s%s%sT%s%s%s", value[:year], value[:month], value[:day], value[:hour], value[:min], value[:sec])
          zone = "Z" if value[:zone] && value[:zone] == "Z"
          ret = ret + zone if !zone.nil?
          ret
        end


        def to_hash
          ret = {
            year: value[:year],
            month: value[:month],
            day: value[:day],
            hour: value[:hour],
            min: value[:min],
            sec: value[:sec],
          }
          ret[:zone] = value[:zone] if value[:zone]
          ret
        end
      end

      class DateTimeUTC < Vobject::PropertyValue
        include Comparable
        def <=>(another)
          value[:time] <=> another.value[:time]
        end

        def initialize(val)
          self.value = val.clone
          value[:time] =  ::Time.utc(val[:year], val[:month], val[:day], val[:hour], val[:min], val[:sec])
          value[:origtime] = value[:time]
        end

        def to_s
          localtime = value[:origtime]
          ret = sprintf("%04d%02d%02dT%02d%02d%02dZ", localtime.year, localtime.month, localtime.day,
                        localtime.hour, localtime.min, localtime.sec)
          ret
        end

        def to_hash
          ret = {
            year: value[:year],
            month: value[:month],
            day: value[:day],
            hour: value[:hour],
            min: value[:min],
            sec: value[:sec],
          }
          ret
        end
      end

      class Boolean < Vobject::PropertyValue
        def initialize(val)
          self.value = val
          self.type = "boolean"
        end

        def to_s
          value.to_s
        end

        def to_hash
          value
        end

        def to_norm
          value.to_s.upcase
        end
      end

      class Duration < Vobject::PropertyValue
        def initialize(val)
          self.value = val
          self.type = "duration"
        end

        def to_s
          ret = "P"
          ret = value[:sign] + ret if value[:sign]
          ret = ret + "#{value[:weeks]}W" if value[:weeks]
          ret = ret + "#{value[:days]}D" if value[:days]
          ret = ret + "T" if value[:hours] || value[:minutes] || value[:seconds]
          ret = ret + "#{value[:hours]}H" if value[:hours]
          ret = ret + "#{value[:minutes]}M" if value[:minutes]
          ret = ret + "#{value[:seconds]}S" if value[:seconds]
          ret
        end

        def to_hash
          value
        end
      end

      class Time < Vobject::PropertyValue
        def initialize(val)
          self.value = val
          self.type = "time"
        end

        def to_s
          ret = "#{value[:hour]}#{value[:min]}#{value[:sec]}"
          ret = ret + "Z" if value[:utc]
          ret
        end

        def to_hash
          value
        end
      end

      class Utcoffset < Vobject::PropertyValue
        def initialize(val)
          self.value = val
          self.type = "utcoffset"
        end

        def to_s
          ret = "#{value[:sign]}#{value[:hr]}#{value[:min]}"
          ret += value[:sec] if value[:sec]
          ret
        end

        def to_hash
          value
        end
      end

      class Geovalue < Vobject::PropertyValue
        def initialize(val)
          self.value = val
          self.type = "geovalue"
        end

        def to_s
          ret = "#{value[:lat]};#{value[:long]}"
          ret
        end

        def to_hash
          value
        end
      end

      class Version < Vobject::PropertyValue
        def initialize(val)
          self.value = val
          self.type = "version"
        end

        def to_s
          value.join(";")
        end

        def to_hash
          if value.length == 1
            value[0]
          else
            value
          end
        end
      end

      class Textlist < Vobject::PropertyValue
        def initialize(val)
          self.value = val
          self.type = "textlist"
        end

        def to_s
          value.map { |m| Text.escape m }.join(",")
        end

        def to_hash
          value
        end
      end

      class Periodlist < Vobject::PropertyValue
        def initialize(val)
          self.value = val
          self.type = "periodlist"
        end

        def to_s
          value.map do |m|
            ret = m[:start].to_s + "/"
            ret += m[:end].to_s if m.has_key? :end
            ret += m[:duration].to_s if m.has_key? :duration
            ret
          end.join(",")
        end

        def to_hash
          value.map { |m| m.each { |k, v| m[k] = v.to_hash } }
        end
      end

      class Datelist < Vobject::PropertyValue
        def initialize(val)
          self.value = val
          self.type = "datelist"
        end

        def to_s
          value.map(&:to_s).join(",")
        end

        def to_hash
          value.map(&:to_hash)
        end
      end

      class Datetimelist < Vobject::PropertyValue
        def initialize(val)
          self.value = val
          self.type = "datetimelist"
        end

        def to_s
          value.map(&:to_s).join(",")
        end

        def to_hash
          value.map(&:to_hash)
        end
      end

      class Datetimeutclist < Vobject::PropertyValue
        def initialize(val)
          self.value = val
          self.type = "datetimeutclist"
        end

        def to_s
          value.map(&:to_s).join(",")
        end

        def to_hash
          value.map(&:to_hash)
        end
      end

      class Requeststatusvalue < Vobject::PropertyValue
        def initialize(val)
          self.value = val
          self.type = "requeststatusvalue"
        end

        def to_s
          ret = "#{value[:statcode]};#{value[:statdesc]}"
          ret += ";#{value[:extdata]}" if value[:extdata]
          ret
        end

        def to_hash
          value
        end
      end

      class Recur < Vobject::PropertyValue
        def initialize(val)
          self.value = val
          self.type = "recur"
        end

        def to_s
          ret = []
          value.each do |k, v|
            ret << "#{k.to_s.upcase}=#{valencode(k, v)}"
          end
          ret.join(";")
        end

        def to_hash
          ret = {}
          value.each do |k, v|
            ret[k] = if v.respond_to?(:to_hash)
                       v.to_hash
                     else
                       v
                     end
          end
          ret
        end

        private

        def valencode(k, v)
          case k
          when :bysetpos, :byyearday
            v.map do |x|
              ret = x[:ordyrday]
              ret = x[:sign] + ret if x[:sign]
              ret
            end.join(",")
          when :byweekno
            v.map do |x|
              ret = x[:ordwk]
              ret = x[:sign] + ret if x[:sign]
              ret
            end.join(",")
          when :bymonthday
            v.map do |x|
              ret = x[:ordmoday]
              ret = x[:sign] + ret if x[:sign]
              ret
            end.join(",")
          when :byday
            v.map do |x|
              ret = x[:weekday]
              ret = x[:ordwk] + ret if x[:ordwk]
              ret = x[:sign] + ret if x[:sign]
              ret
            end.join(",")
          when :bymonth, :byhour, :byminute, :bysecond
            v.join(",")
          when :enddate
            v.to_s
          else
            v
          end
        end
      end
    end
  end
end