123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- class Calendar < ApplicationModel
- store :business_hours
- store :public_holidays
- before_create :validate_public_holidays, :fetch_ical
- before_update :validate_public_holidays, :fetch_ical
- after_create :sync_default, :min_one_check
- after_update :sync_default, :min_one_check
- after_destroy :min_one_check
- notify_clients_support
- def self.init_setup(ip = nil)
-
- if ip && ip =~ /^(::1|127\.|10\.|172\.1[6-9]\.|172\.2[0-9]\.|172\.3[0-1]\.|192\.168\.)/
- ip = nil
- end
-
- cache = Cache.get('Calendar.init_setup.done')
- return if cache && cache[:ip] == ip
- Cache.write('Calendar.init_setup.done', { ip: ip }, { expires_in: 1.hour })
-
- calendar_details = Service::GeoCalendar.location(ip)
- return if !calendar_details
- calendar_details['name'] = Calendar.genrate_uniq_name(calendar_details['name'])
- calendar_details['default'] = true
- calendar_details['created_by_id'] = 1
- calendar_details['updated_by_id'] = 1
-
- calendar = Calendar.find_by(default: true, updated_by_id: 1, created_by_id: 1)
- if calendar
- calendar.update_attributes(calendar_details)
- return calendar
- end
- create(calendar_details)
- end
- def self.default
- find_by(default: true)
- end
- def self.ical_feeds
- gfeeds = {
- 'Australia' => 'en.australian',
- 'Austria' => 'de.austrian',
- 'Argentina' => 'en.ar',
- 'Bahamas' => 'en.bs',
- 'Belarus' => 'en.by',
- 'Brazil' => 'en.brazilian',
- 'Bulgaria' => 'en.bulgarian',
- 'Canada' => 'en.canadian',
- 'China' => 'en.china',
- 'Chile' => 'en.cl',
- 'Costa Rica' => 'en.cr',
- 'Colombia' => 'en.co',
- 'Croatia' => 'en.croatian',
- 'Cuba' => 'en.cu',
- 'Cyprus' => 'de.cy',
- 'Switzerland' => 'de.ch',
- 'Denmark' => 'da.danish',
- 'Netherlands' => 'nl.dutch',
- 'Egypt' => 'en.eg',
- 'Ethiopia' => 'en.et',
- 'Ecuador' => 'en.ec',
- 'Estonia' => 'en.ee',
- 'Finland' => 'en.finnish',
- 'France' => 'en.french',
- 'Germany' => 'de.german',
- 'Greece' => 'en.greek',
- 'Ghana' => 'en.gh',
- 'Hong Kong' => 'en.hong_kong',
- 'Haiti' => 'en.ht',
- 'Hungary' => 'en.hungarian',
- 'India' => 'en.indian',
- 'Indonesia' => 'en.indonesian',
- 'Iran' => 'en.ir',
- 'Ireland' => 'en.irish',
- 'Italy' => 'it.italian',
- 'Israel' => 'en.jewish',
- 'Japan' => 'en.japanese',
- 'Kuwait' => 'en.kw',
- 'Latvia' => 'en.latvian',
- 'Liechtenstein' => 'en.li',
- 'Lithuania' => 'en.lithuanian',
- 'Luxembourg' => 'en.lu',
- 'Malaysia' => 'en.malaysia',
- 'Mexico' => 'en.mexican',
- 'Morocco' => 'en.ma',
- 'Mauritius' => 'en.mu',
- 'Moldova' => 'en.md',
- 'New Zealand' => 'en.new_zealand',
- 'Norway' => 'en.norwegian',
- 'Philippines' => 'en.philippines',
- 'Poland' => 'en.polish',
- 'Portugal' => 'en.portuguese',
- 'Pakistan' => 'en.pk',
- 'Russia' => 'en.russian',
- 'Senegal' => 'en.sn',
- 'Singapore' => 'en.singapore',
- 'South Africa' => 'en.sa',
- 'South Korean' => 'en.south_korea',
- 'Spain' => 'en.spain',
- 'Slovakia' => 'en.slovak',
- 'Serbia' => 'en.rs',
- 'Slovenia' => 'en.slovenian',
- 'Sweden' => 'en.swedish',
- 'Taiwan' => 'en.taiwan',
- 'Thai' => 'en.th',
- 'Turkey' => 'en.turkish',
- 'UK' => 'en.uk',
- 'US' => 'en.usa',
- 'Ukraine' => 'en.ukrainian',
- 'Uruguay' => 'en.uy',
- 'Vietnam' => 'en.vietnamese',
- 'Venezuela' => 'en.ve',
- }
- all_feeds = {}
- gfeeds.each { |key, name|
- all_feeds["http://www.google.com/calendar/ical/#{name}%23holiday%40group.v.calendar.google.com/public/basic.ics"] = key
- }
- all_feeds
- end
- def self.timezones
- list = {}
- TZInfo::Timezone.all_country_zone_identifiers.each { |timezone|
- t = TZInfo::Timezone.get(timezone)
- diff = t.current_period.utc_total_offset / 60 / 60
- list[ timezone ] = diff
- }
- list
- end
- def self.sync
- Calendar.all.each(&:sync)
- true
- end
- def sync(without_save = nil)
- return if !ical_url
- begin
- events = {}
- if ical_url && !ical_url.empty?
- events = Calendar.parse(ical_url)
- end
-
- if !public_holidays
- self.public_holidays = {}
- end
-
- public_holidays.each { |day, meta|
- next if !public_holidays[day]['feed']
- next if meta['feed'] == Digest::MD5.hexdigest(ical_url)
- public_holidays.delete(day)
- }
-
- events.each { |day, summary|
- if !public_holidays[day]
- public_holidays[day] = {}
- end
-
- next if public_holidays[day].key?('active')
-
- public_holidays[day] = {
- active: true,
- summary: summary,
- feed: Digest::MD5.hexdigest(ical_url)
- }
- }
- self.last_log = nil
- rescue => e
- self.last_log = e.inspect
- end
- self.last_sync = Time.zone.now
- if !without_save
- save
- end
- true
- end
- def self.parse(location)
- if location =~ /^http/i
- result = UserAgent.get(location)
- if !result.success?
- raise result.error
- end
- cal_file = result.body
- else
- cal_file = File.open(location)
- end
- cals = Icalendar::Calendar.parse(cal_file)
- cal = cals.first
- events = {}
- cal.events.each { |event|
- next if event.dtstart < Time.zone.now - 1.year
- next if event.dtstart > Time.zone.now + 3.years
- day = "#{event.dtstart.year}-#{format('%02d', event.dtstart.month)}-#{format('%02d', event.dtstart.day)}"
- comment = event.summary || event.description
- comment = Encode.conv( 'utf8', comment.to_s.force_encoding('utf-8') )
- if !comment.valid_encoding?
- comment = comment.encode('utf-8', 'binary', invalid: :replace, undef: :replace, replace: '?')
- end
-
- next if comment =~ /(daylight saving|sommerzeit|summertime)/i
- events[day] = comment
- }
- events.sort.to_h
- end
- private
-
- def sync_default
- return if !default
- Calendar.all.each { |calendar|
- next if calendar.id == id
- next if !calendar.default
- calendar.default = false
- calendar.save
- }
- end
-
- def min_one_check
- Calendar.all.each { |calendar|
- return true if calendar.default
- }
- first = Calendar.order(:created_at, :id).limit(1).first
- first.default = true
- first.save
-
- Sla.all.each { |sla|
- if !sla.calendar_id
- sla.calendar_id = first.id
- sla.save
- next
- end
- if !Calendar.find_by(id: sla.calendar_id)
- sla.calendar_id = first.id
- sla.save
- end
- }
- end
-
- def fetch_ical
- sync(true)
- end
-
- def validate_public_holidays
-
- public_holidays.each { |day, meta|
- if public_holidays_was && public_holidays_was[day] && public_holidays_was[day]['feed']
- meta['feed'] = public_holidays_was[day]['feed']
- end
- meta['active'] = if meta['active']
- true
- else
- false
- end
- }
- end
- end
|