Merge pull request #102 from Absurdon/CalendarIntegrationUpdate

Calendar integration update
This commit is contained in:
Absurdon 2017-04-03 01:06:33 +02:00 committed by GitHub
commit 0358817d91
6 changed files with 103 additions and 147 deletions

View file

@ -4,7 +4,7 @@ ruby '2.2.2'
gem 'dotenv-rails', '~> 0.10.0' gem 'dotenv-rails', '~> 0.10.0'
gem 'rails', '~> 3.2.22' gem 'rails', '~> 3.2.22'
gem 'mysql2', '~> 0.3.15' gem 'mysql2', '~> 0.3.17'
gem 'dalli', '~> 2.7.0' gem 'dalli', '~> 2.7.0'
gem 'puma', '~> 2.11.1' gem 'puma', '~> 2.11.1'
@ -24,6 +24,7 @@ gem 'active_link_to', '~> 1.0.2'
gem 'rmagick', '~> 2.13.4', require: false gem 'rmagick', '~> 2.13.4', require: false
gem 'steam-condenser', github: 'koraktor/steam-condenser-ruby' gem 'steam-condenser', github: 'koraktor/steam-condenser-ruby'
gem 'test-unit', '~> 3.1.3' gem 'test-unit', '~> 3.1.3'
gem 'google-api-client', '~> 0.10.3'
# Please install nodejs locally. # Please install nodejs locally.
gem 'therubyracer', '~> 0.12.1' if RUBY_PLATFORM == 'x86_64-linux' gem 'therubyracer', '~> 0.12.1' if RUBY_PLATFORM == 'x86_64-linux'

View file

@ -38,6 +38,8 @@ GEM
activesupport (3.2.22) activesupport (3.2.22)
i18n (~> 0.6, >= 0.6.4) i18n (~> 0.6, >= 0.6.4)
multi_json (~> 1.0) multi_json (~> 1.0)
addressable (2.5.1)
public_suffix (~> 2.0, >= 2.0.2)
annotate (2.6.3) annotate (2.6.3)
activerecord (>= 2.3.0) activerecord (>= 2.3.0)
rake (>= 0.8.7) rake (>= 0.8.7)
@ -100,6 +102,8 @@ GEM
database_cleaner (1.2.0) database_cleaner (1.2.0)
debug_inspector (0.0.2) debug_inspector (0.0.2)
debugger-linecache (1.2.0) debugger-linecache (1.2.0)
declarative (0.0.9)
declarative-option (0.1.0)
diff-lcs (1.2.5) diff-lcs (1.2.5)
dotenv (0.10.0) dotenv (0.10.0)
dotenv-rails (0.10.0) dotenv-rails (0.10.0)
@ -119,25 +123,51 @@ GEM
ffi (1.9.3) ffi (1.9.3)
font-awesome-sass (4.1.0) font-awesome-sass (4.1.0)
sass (~> 3.2) sass (~> 3.2)
google-api-client (0.10.3)
addressable (~> 2.3)
googleauth (~> 0.5)
httpclient (~> 2.7)
hurley (~> 0.1)
memoist (~> 0.11)
mime-types (>= 1.6)
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
googleauth (0.5.1)
faraday (~> 0.9)
jwt (~> 1.4)
logging (~> 2.0)
memoist (~> 0.12)
multi_json (~> 1.11)
os (~> 0.9)
signet (~> 0.7)
haml (4.0.5) haml (4.0.5)
tilt tilt
hike (1.2.3) hike (1.2.3)
httpclient (2.8.3)
hurley (0.2)
i18n (0.7.0) i18n (0.7.0)
journey (1.0.4) journey (1.0.4)
jquery-rails (2.0.3) jquery-rails (2.0.3)
railties (>= 3.1.0, < 5.0) railties (>= 3.1.0, < 5.0)
thor (~> 0.14) thor (~> 0.14)
json (1.8.3) json (1.8.3)
jwt (1.5.6)
libv8 (3.16.14.19)
little-plugger (1.1.4)
logging (2.2.0)
little-plugger (~> 1.1)
multi_json (~> 1.10)
mail (2.5.4) mail (2.5.4)
mime-types (~> 1.16) mime-types (~> 1.16)
treetop (~> 1.4.8) treetop (~> 1.4.8)
memoist (0.15.0)
method_source (0.8.2) method_source (0.8.2)
mime-types (1.25.1) mime-types (1.25.1)
mini_portile (0.6.2) mini_portile (0.6.2)
multi_json (1.11.2) multi_json (1.11.2)
multi_xml (0.5.5) multi_xml (0.5.5)
multipart-post (2.0.0) multipart-post (2.0.0)
mysql2 (0.3.15) mysql2 (0.3.21)
neat (1.6.0) neat (1.6.0)
bourbon (>= 3.1) bourbon (>= 3.1)
sass (>= 3.3) sass (>= 3.3)
@ -148,6 +178,7 @@ GEM
nokogiri (1.6.6.2) nokogiri (1.6.6.2)
mini_portile (~> 0.6.0) mini_portile (~> 0.6.0)
oj (2.5.5) oj (2.5.5)
os (0.9.6)
poltergeist (1.6.0) poltergeist (1.6.0)
capybara (~> 2.1) capybara (~> 2.1)
cliver (~> 0.3.1) cliver (~> 0.3.1)
@ -162,6 +193,7 @@ GEM
pry-byebug (1.3.2) pry-byebug (1.3.2)
byebug (~> 2.7) byebug (~> 2.7)
pry (~> 0.9.12) pry (~> 0.9.12)
public_suffix (2.0.5)
puma (2.11.1) puma (2.11.1)
rack (>= 1.1, < 2.0) rack (>= 1.1, < 2.0)
quiet_assets (1.0.2) quiet_assets (1.0.2)
@ -193,6 +225,12 @@ GEM
rake (10.4.2) rake (10.4.2)
rdoc (3.12.2) rdoc (3.12.2)
json (~> 1.4) json (~> 1.4)
ref (2.0.0)
representable (3.0.3)
declarative (< 0.1.0)
declarative-option (< 0.2.0)
uber (< 0.2.0)
retriable (3.0.1)
rmagick (2.13.4) rmagick (2.13.4)
rspec-core (3.3.2) rspec-core (3.3.2)
rspec-support (~> 3.3.0) rspec-support (~> 3.3.0)
@ -224,6 +262,11 @@ GEM
multi_json (~> 1.0) multi_json (~> 1.0)
rubyzip (~> 1.0) rubyzip (~> 1.0)
websocket (~> 1.0.4) websocket (~> 1.0.4)
signet (0.7.3)
addressable (~> 2.3)
faraday (~> 0.9)
jwt (~> 1.5)
multi_json (~> 1.10)
simplecov (0.7.1) simplecov (0.7.1)
multi_json (~> 1.0) multi_json (~> 1.0)
simplecov-html (~> 0.7.1) simplecov-html (~> 0.7.1)
@ -242,6 +285,9 @@ GEM
tins (~> 1.0) tins (~> 1.0)
test-unit (3.1.3) test-unit (3.1.3)
power_assert power_assert
therubyracer (0.12.3)
libv8 (~> 3.16.14.15)
ref
thor (0.19.1) thor (0.19.1)
tilt (1.4.1) tilt (1.4.1)
timecop (0.7.1) timecop (0.7.1)
@ -252,6 +298,7 @@ GEM
polyglot polyglot
polyglot (>= 0.3.1) polyglot (>= 0.3.1)
tzinfo (0.3.44) tzinfo (0.3.44)
uber (0.1.0)
uglifier (2.5.0) uglifier (2.5.0)
execjs (>= 0.3.0) execjs (>= 0.3.0)
json (>= 1.8.0) json (>= 1.8.0)
@ -291,9 +338,10 @@ DEPENDENCIES
factory_girl_rails (~> 4.4.1) factory_girl_rails (~> 4.4.1)
faraday (~> 0.9.0) faraday (~> 0.9.0)
font-awesome-sass (~> 4.1.0.0) font-awesome-sass (~> 4.1.0.0)
google-api-client (~> 0.10.3)
haml (~> 4.0.5) haml (~> 4.0.5)
jquery-rails (~> 2.0.2) jquery-rails (~> 2.0.2)
mysql2 (~> 0.3.15) mysql2 (~> 0.3.17)
neat (~> 1.6.0) neat (~> 1.6.0)
newrelic_rpm (~> 3.13.0.299) newrelic_rpm (~> 3.13.0.299)
nokogiri (~> 1.6.1) nokogiri (~> 1.6.1)
@ -314,10 +362,14 @@ DEPENDENCIES
sprockets (~> 2.2.1) sprockets (~> 2.2.1)
steam-condenser! steam-condenser!
test-unit (~> 3.1.3) test-unit (~> 3.1.3)
therubyracer (~> 0.12.1)
timecop (~> 0.7.1) timecop (~> 0.7.1)
tinymce-rails (~> 3.5.9) tinymce-rails (~> 3.5.9)
uglifier (~> 2.5.0) uglifier (~> 2.5.0)
will_paginate (~> 3.0.5) will_paginate (~> 3.0.5)
RUBY VERSION
ruby 2.2.2p95
BUNDLED WITH BUNDLED WITH
1.10.6 1.14.6

View file

@ -171,19 +171,20 @@ module ApplicationHelper
end end
end end
def calendar
@calendar ||= GoogleCalendar.new(ENV['GOOGLE_CALENDAR_ID'], timezone_offset)
end
def event_start_time event
event.start.date_time.to_datetime.in_time_zone(timezone_offset)
end
def upcoming_matches def upcoming_matches
GoogleCalendar.new(ENV['GOOGLE_CALENDAR_ID'], timezone_offset). calendar.upcoming || []
upcoming.sort_by do |event|
event.start
end
end end
def upcoming_nsltv def upcoming_nsltv
GoogleCalendar.new(ENV['GOOGLE_CALENDAR_ID'], timezone_offset). calendar.upcoming_nsltv || []
upcoming_nsltv.sort_by do |event|
event.start
end
end end
def latest_rules def latest_rules

View file

@ -1,144 +1,46 @@
require 'google/apis/calendar_v3'
CALENDAR = Google::Apis::CalendarV3
class GoogleCalendar class GoogleCalendar
attr_accessor :timezone
def initialize(id, timezone_offset = Time.zone.name) def initialize (calendar_id, timezone_offset = Time.zone.name)
@id = id @id = calendar_id
@timezone_offset = timezone_offset @timezone_offset = timezone_offset
@events = nil
@service = CALENDAR::CalendarService.new
#@service.authorization = CALENDAR::AUTH_CALENDAR # change this if write access needed
@service.key = ENV['GOOGLE_API_KEY']
query_events
end end
def summary
list.summary
end
def timezone
list.timezone
end
def events
list.events
end
def upcoming def upcoming
events.select do |event| @events && @events.select do |event|
event.start >= (Time.zone.now - 2.hours) && (not nsltv_regex =~ event.summary)
(not event.nsltv_regex =~ event.summary)
end end
end end
def upcoming_nsltv def upcoming_nsltv
events.select do |event| @events && @events.select do |event|
event.start >= (Time.zone.now - 2.hours) && (nsltv_regex =~ event.summary)
event.nsltv_regex =~ (event.summary)
end end
end end
def list def query_events
@list ||= GoogleCalendar::Request.events_list(@id, @timezone_offset) list = nil
end @events.nil? and @service.list_events(@id, time_zone: ActiveSupport::TimeZone::MAPPING[@timezone_offset], time_min: (2.hours.ago).utc.iso8601 ) {|result, err|
end if err
puts err.inspect
class GoogleCalendar else
class Request list = result
BASE_URL = "https://www.googleapis.com/"
EVENTS_ENDPOINT = "events"
def self.events_list(id, timezone_offset)
request = self.new(id, EVENTS_ENDPOINT)
GoogleCalendar::EventList.new(request.parsed_response, timezone_offset)
end
def initialize(id, endpoint)
@id = id
@endpoint = endpoint
@response = get_data
end
def parsed_response
JSON.parse(@response.body)
end
private
def get_data
Rails.cache.fetch(cache_key, expires_in: 5.minutes) do
if Rails.env.development?
conn = Faraday.new(BASE_URL, ssl: {verify: false})
else
conn = Faraday.new(BASE_URL)
end
conn.get(request_url)
end end
end }
@events = (list) ? list.items : nil
def cache_key
"/google_calendar/#{@id}/#{@endpoint}"
end
def request_url
#The default number of events pulled is 250.
#We reached that number and events didn't show any more.
#So now I filter all events that have a start time
#that is longer ago then 7 days.
#Alternative: maxResults=2500
time_min = (Time.now - 7.days).utc.iso8601
"calendar/v3/calendars/#{@id}/#{@endpoint}/?key=#{ENV['GOOGLE_API_KEY']}&timeMin=#{time_min}"
end
end end
class EventList def nsltv_regex
attr_reader :summary, :events, :timezone /\[NSLTV\]/i
def initialize(list, timezone_offset)
@list = list
@timezone_offset = timezone_offset
parse_list
parse_events
end
private
def parse_list
@summary = @list["summary"]
@timezone = @list["timeZone"]
end
def parse_events
@events = @list["items"].map do |item|
GoogleCalendar::Event.new(item, @timezone_offset)
end
end
end end
class Event
def initialize(entry, timezone_offset)
@entry = entry
@timezone_offset = timezone_offset
end
def start
@entry["start"]["dateTime"].to_datetime.in_time_zone(@timezone_offset)
end
def end
@entry["end"]["dateTime"].to_datetime.in_time_zone(@timezone_offset)
end
def nsltv_regex
/\[NSLTV\]/i
end
def formatted_summary
summary.gsub(/(http\:\/\/)(.*[^)])/i, '<a href="\1\2">\2</a>').
gsub(nsltv_regex, '').html_safe
end
def [](key)
@entry[key]
end
def method_missing(method)
self[method.to_s]
end
end
end end

View file

@ -22,7 +22,7 @@
</div> </div>
<div id="sidebar"> <div id="sidebar">
<%= yield :sidebar %> <%= yield :sidebar %>
<% ['shoutbox', 'posts', 'poll'].each do |widget| %> <% ['calendar','shoutbox', 'posts', 'poll'].each do |widget| %>
<%= render partial: "widgets/#{widget}" %> <%= render partial: "widgets/#{widget}" %>
<% end %> <% end %>
</div> </div>

View file

@ -3,14 +3,14 @@
<h4><%= t('widget.schedule') %></h4> <h4><%= t('widget.schedule') %></h4>
<div class="widget-content-wrapper"> <div class="widget-content-wrapper">
<% upcoming_matches.group_by{ |e| e.start.month }.each do |month, events| %> <% upcoming_matches.group_by{ |e| e.start.date_time.month }.each do |month, events| %>
<% events.group_by { |e| e.start.day }.each do |day, day_events| %> <% events.group_by { |e| e.start.date_time.day }.each do |day, day_events| %>
<div class="separator"><%= day_events.first.start.strftime("%A, %e %B") %></div> <div class="separator"><%= event_start_time(day_events.first).strftime("%A, %e %B") %></div>
<% day_events.each do |event| %> <% day_events.each do |event| %>
<div class="entry"> <div class="entry">
<p class="summary"> <p class="summary">
<span class="time"><%= event.start.strftime("%H:%M %Z") %></span> <span class="time"><%= event_start_time(event).strftime("%H:%M %Z") %></span>
<%= event.formatted_summary %> <%= event.summary %>
</p> </p>
</div> </div>
<% end %> <% end %>
@ -24,14 +24,14 @@
<h4>NSLTV</h4> <h4>NSLTV</h4>
<div class="widget-content-wrapper"> <div class="widget-content-wrapper">
<% upcoming_nsltv.group_by{ |e| e.start.month }.each do |month, events| %> <% upcoming_nsltv.group_by{ |e| e.start.date_time.month }.each do |month, events| %>
<% events.group_by { |e| e.start.day }.each do |day, day_events| %> <% events.group_by { |e| e.start.date_time.day }.each do |day, day_events| %>
<div class="separator"><%= day_events.first.start.strftime("%A, %e %B") %></div> <div class="separator"><%= event_start_time(day_events.first).strftime("%A, %e %B") %></div>
<% day_events.each do |event| %> <% day_events.each do |event| %>
<div class="entry"> <div class="entry">
<p class="summary"> <p class="summary">
<span class="time"><%= event.start.strftime("%H:%M %Z") %></span> <span class="time"><%= event_start_time(event).strftime("%H:%M %Z") %></span>
<%= event.formatted_summary %> <%= event.summary %>
</p> </p>
</div> </div>
<% end %> <% end %>