From c2309dd2ef7810ea5e4a212b71180ef1112c7cd1 Mon Sep 17 00:00:00 2001
From: Luke Barratt
Date: Wed, 2 Apr 2014 00:07:21 +0100
Subject: [PATCH] Added timezone based google calendar widget Updated unicorn
and capistrano deployment configuration for the staging environment HTML
formatting Fixes errors when posting new issues Added Google Calendar client
code CSS tweaks to layout Added new .env vars Layout tweaks Updated
contributors
---
.env.example | 3 +
Gemfile | 2 +
Gemfile.lock | 6 +
README.md | 7 +-
app/assets/stylesheets/sass/articles.sass | 6 +-
app/assets/stylesheets/sass/general.sass | 2 +-
app/assets/stylesheets/sass/index.sass | 25 +-
app/assets/stylesheets/sass/special.sass | 2 +-
app/helpers/application_helper.rb | 14 +
app/models/issue.rb | 2 +
app/services/google_calendar.rb | 120 +++
app/views/layouts/application.html.erb | 6 +-
app/views/users/edit.html.erb | 4 +-
app/views/widgets/_calendar.html.erb | 16 +
app/views/widgets/_matches.html.erb | 22 +-
config/deploy.rb | 2 -
config/deploy/production.rb | 3 +-
config/deploy/staging.rb | 9 +-
config/environments/development.rb | 2 +-
config/environments/production.rb | 2 +-
config/environments/staging.rb | 6 +-
config/locales/en.yml | 3 +
config/unicorn.rb | 4 +-
spec/factories/profile.rb | 5 +
spec/factories/user.rb | 4 +
.../calendar/google_calendar_widget_spec.rb | 53 ++
spec/fixtures/google_calendar.json | 763 ++++++++++++++++++
spec/services/api/v1/users_collection_spec.rb | 2 +
spec/support/features/session_helpers.rb | 11 +-
29 files changed, 1065 insertions(+), 41 deletions(-)
create mode 100644 app/services/google_calendar.rb
create mode 100644 app/views/widgets/_calendar.html.erb
create mode 100644 spec/factories/profile.rb
create mode 100644 spec/features/calendar/google_calendar_widget_spec.rb
create mode 100644 spec/fixtures/google_calendar.json
diff --git a/.env.example b/.env.example
index d390356..2d588bb 100644
--- a/.env.example
+++ b/.env.example
@@ -2,6 +2,8 @@ RACK_ENV=
RAILS_ENV=
APP_SECRET=
+DEPLOY_PATH=
+
UNICORN_USER=deploy
UNICORN_GROUP=deploy
UNICORN_WORKERS=4
@@ -18,4 +20,5 @@ NEW_RELIC_LICENSE_KEY=
EXCEPTIONAL_API_KEY=
+GOOGLE_API_KEY=
GOOGLE_CALENDAR_ID=
diff --git a/Gemfile b/Gemfile
index 427b01f..f7d254c 100644
--- a/Gemfile
+++ b/Gemfile
@@ -9,6 +9,7 @@ gem 'dalli', '~> 2.7.0'
gem 'exceptional', '~> 2.0.33'
gem 'oj', '~> 2.5.5'
+gem 'faraday', '~> 0.9.0'
gem 'gruff', '~> 0.3.6'
gem 'nokogiri', '~> 1.6.1'
gem 'bbcoder', '~> 1.0.1'
@@ -50,6 +51,7 @@ group :test do
gem 'poltergeist', '~> 1.5.0'
gem 'selenium-webdriver', '~> 2.41.0'
gem 'factory_girl_rails', '~> 4.4.1'
+ gem 'timecop', '~> 0.7.1'
end
group :development, :test do
diff --git a/Gemfile.lock b/Gemfile.lock
index 898d21d..0474942 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -100,6 +100,8 @@ GEM
factory_girl_rails (4.4.1)
factory_girl (~> 4.4.0)
railties (>= 3.0.0)
+ faraday (0.9.0)
+ multipart-post (>= 1.2, < 3)
ffi (1.9.3)
ffi (1.9.3-x86-mingw32)
gruff (0.3.6)
@@ -119,6 +121,7 @@ GEM
mime-types (1.25.1)
mini_portile (0.5.3)
multi_json (1.8.4)
+ multipart-post (2.0.0)
mysql2 (0.3.15)
net-scp (1.1.2)
net-ssh (>= 2.6.5)
@@ -223,6 +226,7 @@ GEM
ref
thor (0.18.1)
tilt (1.4.1)
+ timecop (0.7.1)
tins (1.0.1)
tinymce-rails (3.5.9)
railties (>= 3.1.1)
@@ -268,6 +272,7 @@ DEPENDENCIES
dynamic_form (~> 1.1.4)
exceptional (~> 2.0.33)
factory_girl_rails (~> 4.4.1)
+ faraday (~> 0.9.0)
gruff (~> 0.3.6)
jquery-rails (~> 2.0.2)
kgio (~> 2.9.2)
@@ -286,6 +291,7 @@ DEPENDENCIES
selenium-webdriver (~> 2.41.0)
simplecov (~> 0.7.1)
therubyracer (~> 0.12.1)
+ timecop (~> 0.7.1)
tinymce-rails (~> 3.5.9)
uglifier (~> 2.5.0)
unicorn (~> 4.8.2)
diff --git a/README.md b/README.md
index 414f630..2b7e08c 100644
--- a/README.md
+++ b/README.md
@@ -32,6 +32,7 @@ Features:
## Contributors
-- [Ari Timonen](https://github.com/jirikivaari) - Original author
-- [Florent Latombe](https://github.com/flatombe) - Improvements
-- [Luke Barratt](https://github.com/lbarratt) - Improvements
+- [Ari Timonen](https://github.com/jirikivaari) (Original Author)
+- [Florent Latombe](https://github.com/flatombe)
+- [Luke Barratt](https://github.com/lbarratt)
+- [Callum Barratt](https://github.com/cbarratt)
\ No newline at end of file
diff --git a/app/assets/stylesheets/sass/articles.sass b/app/assets/stylesheets/sass/articles.sass
index e654610..cf93039 100644
--- a/app/assets/stylesheets/sass/articles.sass
+++ b/app/assets/stylesheets/sass/articles.sass
@@ -6,8 +6,9 @@ div
&.article
@include rounded-corners
@include shadow
- width: 650px
+ width: 100%
padding: 0px
+ margin-right: 0
margin-bottom: 20px
border: 1px solid #d7d7d7
background-color: $bg_box
@@ -16,8 +17,9 @@ div
&.article
> h1
@include shaded-top
+ box-sizing: border-box
margin: 0
- width: 630px
+ width: 100%
font-size: 140%
h1 a
color: #ffffff
diff --git a/app/assets/stylesheets/sass/general.sass b/app/assets/stylesheets/sass/general.sass
index a63ecd4..423af2c 100644
--- a/app/assets/stylesheets/sass/general.sass
+++ b/app/assets/stylesheets/sass/general.sass
@@ -164,7 +164,7 @@ input
float: right
.big
- width: 65%
+ width: 70%
.big2
width: 62%
diff --git a/app/assets/stylesheets/sass/index.sass b/app/assets/stylesheets/sass/index.sass
index 1759f55..4d83815 100644
--- a/app/assets/stylesheets/sass/index.sass
+++ b/app/assets/stylesheets/sass/index.sass
@@ -137,12 +137,13 @@ div
color: #d6d5d5
indexMainarea
- padding: 10px 100px 10px 150px
+ padding: 10px 100px 10px 100px
indexContent
- width: 650px
+ width: 700px
+ margin-top: 15px
margin-left: 15px
- margin-right: 15px
+ margin-right: 20px
float: left
padding: 0
@@ -152,7 +153,7 @@ div
&.indexBox
@include rounded-corners
@include shadow
- width: 220px
+ width: 250px
padding-bottom: 10px
margin-bottom: 15px
background-color: $bg_box
@@ -164,6 +165,14 @@ div
height: 25px
font-size: 14px
font-weight: bold
+ &.separator
+ @include shaded-top
+ border-radius: 0px
+ margin: 0
+ padding-top: 5px
+ height: 20px
+ font-size: 12px
+ font-weight: normal
&.body
width: 100%
text-align: left
@@ -183,6 +192,14 @@ div
width: 110px
text-align: center
+ index-calendar
+ padding-bottom: 0
+ .widget-content-wrapper
+ padding-bottom: 10px
+ max-height: 400px
+ overflow-x: hidden
+ overflow-y: scroll
+
indexPosts
padding: 5px
diff --git a/app/assets/stylesheets/sass/special.sass b/app/assets/stylesheets/sass/special.sass
index a64425a..9ad393a 100644
--- a/app/assets/stylesheets/sass/special.sass
+++ b/app/assets/stylesheets/sass/special.sass
@@ -23,7 +23,7 @@ td
padding-left: 15px
padding-top: 20px
vertical-align: top
- width: 450px
+ width: 550px
div
&.userFields
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 3e5d726..c701f1d 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -130,4 +130,18 @@ module ApplicationHelper
end
link_to_function(name, ("add_fields(this, '#{association}', '#{escape_javascript(fields)}')"))
end
+
+ def timezone_offset
+ if @cuser
+ @cuser.time_zone
+ else
+ Time.zone.name
+ end
+ end
+
+ def upcoming_matches
+ GoogleCalendar.new(ENV['GOOGLE_CALENDAR_ID'], timezone_offset).upcoming.sort_by do |event|
+ event.start
+ end
+ end
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 04116cf..4fd6c07 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -18,6 +18,8 @@
require File.join(Rails.root, 'vendor', 'plugins', 'acts-as-readable', 'init.rb')
class Issue < ActiveRecord::Base
+ include Extra
+
STATUS_OPEN = 0
STATUS_SOLVED = 1
STATUS_REJECTED = 2
diff --git a/app/services/google_calendar.rb b/app/services/google_calendar.rb
new file mode 100644
index 0000000..f259389
--- /dev/null
+++ b/app/services/google_calendar.rb
@@ -0,0 +1,120 @@
+class GoogleCalendar
+ attr_accessor :timezone
+
+ def initialize(id, timezone_offset = Time.zone.name)
+ @id = id
+ @timezone_offset = timezone_offset
+ end
+
+ def summary
+ list.summary
+ end
+
+ def timezone
+ list.timezone
+ end
+
+ def events
+ list.events
+ end
+
+ def upcoming
+ events.select do |event|
+ event.start >= Time.zone.now
+ end
+ end
+
+ def list
+ @list ||= GoogleCalendar::Request.events_list(@id, @timezone_offset)
+ end
+end
+
+class GoogleCalendar
+ class Request
+ BASE_URL = "https://www.googleapis.com/calendar/v3/calendars"
+ 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
+ Faraday.get(request_url)
+ end
+ end
+
+ def cache_key
+ "/google_calendar/#{@id}/#{@endpoint}"
+ end
+
+ def request_url
+ "#{BASE_URL}/#{@id}/#{@endpoint}/?key=#{ENV['GOOGLE_API_KEY']}"
+ end
+ end
+
+ class EventList
+ attr_reader :summary, :events, :timezone
+
+ 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
+
+ class Event
+ def initialize(entry, timezone_offset)
+ @entry = entry
+ @timezone_offset = timezone_offset
+ end
+
+ def start
+ Time.use_zone(@timezone_offset) { Time.zone.parse(@entry["start"]["dateTime"]) }
+ end
+
+ def end
+ Time.use_zone(@timezone_offset) { Time.zone.parse(@entry["end"]["dateTime"]) }
+ end
+
+ def formatted_summary
+ summary.gsub(/(http\:\/\/)(.*[^)])/i, '\2').html_safe
+ end
+
+ def [](key)
+ @entry[key]
+ end
+
+ def method_missing(method)
+ self[method.to_s]
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index a37dbd0..f153bbf 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -34,6 +34,10 @@
+
+ <%= render :partial => "widgets/calendar" %>
+
+
- <%# if @current_controller == "contests" %>
<%= render :partial => "widgets/highlights" %>
- <%# end %>
<%= render :partial => "widgets/posts" %>
diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb
index 9686098..118a43b 100644
--- a/app/views/users/edit.html.erb
+++ b/app/views/users/edit.html.erb
@@ -6,7 +6,7 @@
- <%= f.submit "Save" %>
+ <%= f.submit %>
<% end %>
diff --git a/app/views/widgets/_calendar.html.erb b/app/views/widgets/_calendar.html.erb
new file mode 100644
index 0000000..9589de8
--- /dev/null
+++ b/app/views/widgets/_calendar.html.erb
@@ -0,0 +1,16 @@
+
+
+
+ <% upcoming_matches.group_by{ |e| e.start.month }.each do |month, events| %>
+ <% events.group_by { |e| e.start.day }.each do |day, day_events| %>
+
<%= day_events.first.start.strftime("%A, %e %B") %>
+ <% day_events.each do |event| %>
+
+
<%= event.formatted_summary %>
+
<%= event.start.strftime("%H:%M %Z") %>
+
+ <% end %>
+ <% end %>
+ <% end %>
+
+
\ No newline at end of file
diff --git a/app/views/widgets/_matches.html.erb b/app/views/widgets/_matches.html.erb
index 77ce7b2..82a6376 100644
--- a/app/views/widgets/_matches.html.erb
+++ b/app/views/widgets/_matches.html.erb
@@ -19,14 +19,14 @@
<% link_to match do %>
<%= match.contester1 %>
<% if match.score1 > match.score2; c1 = 'green'; c2 = 'red' end %>
- <% if match.score1 < match.score2; c1 = 'red'; c2 = 'green' end %>
- <% if match.score1 == match.score2; c1 = 'yellow'; c2 = 'yellow' end %>
- <%= h match.score1 %>
- -
- <%= h match.score2 %>
-
- <%= match.contester2 %>
- <% end %>
-
- <% end %>
-
+ <% if match.score1 < match.score2; c1 = 'red'; c2 = 'green' end %>
+ <% if match.score1 == match.score2; c1 = 'yellow'; c2 = 'yellow' end %>
+ <%= h match.score1 %>
+ -
+ <%= h match.score2 %>
+
+ <%= match.contester2 %>
+ <% end %>
+
+ <% end %>
+
diff --git a/config/deploy.rb b/config/deploy.rb
index 398a58a..7bc1a43 100644
--- a/config/deploy.rb
+++ b/config/deploy.rb
@@ -1,8 +1,6 @@
lock '3.1.0'
set :application, 'ensl'
-set :deploy_user, 'deploy'
-set :deploy_to, '/var/www/virtual/ensl.org/deploy'
set :deploy_via, :remote_cache
set :pty, true
diff --git a/config/deploy/production.rb b/config/deploy/production.rb
index 7e4b4e0..a78403c 100644
--- a/config/deploy/production.rb
+++ b/config/deploy/production.rb
@@ -1,9 +1,10 @@
set :branch, 'master'
+set :deploy_to, '/var/www/virtual/ensl.org/deploy'
+
set :rails_env, 'production'
set :unicorn_rack_env, fetch(:rails_env)
role :app, %w{vu2009@ensl.org}
role :web, %w{vu2009@ensl.org}
-role :db, %w{vu2009@ensl.org}
server 'ensl.org', user: 'vu2009', roles: %w{web app}
diff --git a/config/deploy/staging.rb b/config/deploy/staging.rb
index 80edfcd..58c65d4 100644
--- a/config/deploy/staging.rb
+++ b/config/deploy/staging.rb
@@ -1,9 +1,10 @@
set :branch, 'develop'
+set :deploy_to, '/var/www/virtual/ensl.org/staging/rails'
+
set :rails_env, 'staging'
set :unicorn_rack_env, fetch(:rails_env)
-role :app, %w{deploy@staging.ensl.org}
-role :web, %w{deploy@staging.ensl.org}
-role :db, %w{deploy@staging.ensl.org}
+role :app, %w{vu2009@staging.ensl.org}
+role :web, %w{vu2009@staging.ensl.org}
-server 'staging.ensl.org', user: 'deploy', roles: %w{web app}
+server 'staging.ensl.org', user: 'vu2009', roles: %w{web app}
diff --git a/config/environments/development.rb b/config/environments/development.rb
index b0c0176..6fc7019 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -10,7 +10,7 @@ Ensl::Application.configure do
config.whiny_nils = true
# Show full error reports and disable caching
- config.consider_all_requests_local = true
+ config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Don't care if the mailer can't send
diff --git a/config/environments/production.rb b/config/environments/production.rb
index 5d7ece9..980ff81 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -5,7 +5,7 @@ Ensl::Application.configure do
config.cache_classes = true
# Full error reports are disabled and caching is turned on
- config.consider_all_requests_local = false
+ config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Disable Rails's static asset server (Apache or nginx will already do this)
diff --git a/config/environments/staging.rb b/config/environments/staging.rb
index 01e18ea..1bf7d89 100644
--- a/config/environments/staging.rb
+++ b/config/environments/staging.rb
@@ -24,8 +24,8 @@ Ensl::Application.configure do
# config.assets.manifest = YOUR_PATH
# Specifies the header that your server uses for sending files
- # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
- config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
+ config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
+ # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
@@ -61,4 +61,4 @@ Ensl::Application.configure do
# Send deprecation notices to registered listeners
config.active_support.deprecation = :notify
-end
\ No newline at end of file
+end
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 0407863..25e2129 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -81,6 +81,8 @@ en:
votes_success: "Voted successfully."
error: "error"
prohibited: "prohibited"
+ profile:
+ locals: "Locals"
sessions:
form:
forgot_password: "Forgot password?"
@@ -92,6 +94,7 @@ en:
user:
login: "Login"
create: "Register"
+ update: "Update Profile"
post:
create: "Create Article"
activerecord:
diff --git a/config/unicorn.rb b/config/unicorn.rb
index 75ccd3f..75793d3 100644
--- a/config/unicorn.rb
+++ b/config/unicorn.rb
@@ -1,7 +1,7 @@
require "dotenv"
Dotenv.load
-base_path = "/var/www/virtual/ensl.org/deploy"
+base_path = (ENV['DEPLOY_PATH'] || Dir.pwd)
current_path = "#{base_path}/current"
shared_path = "#{base_path}/shared"
@@ -11,7 +11,7 @@ timeout 30
preload_app true
user ENV['UNICORN_USER'], ENV['UNICORN_GROUP']
-listen Integer(ENV['UNICORN_PORT'] || 4000), :tcp_nopush => true
+listen Integer(ENV['UNICORN_PORT']), :tcp_nopush => true
listen ENV['UNICORN_SOCKET'], :backlog => 64
stderr_path "#{shared_path}/log/unicorn.stderr.log"
diff --git a/spec/factories/profile.rb b/spec/factories/profile.rb
new file mode 100644
index 0000000..af03b4a
--- /dev/null
+++ b/spec/factories/profile.rb
@@ -0,0 +1,5 @@
+FactoryGirl.define do
+ factory :profile do
+ web "ensl.org"
+ end
+end
diff --git a/spec/factories/user.rb b/spec/factories/user.rb
index 2f87bc2..fc5f7aa 100644
--- a/spec/factories/user.rb
+++ b/spec/factories/user.rb
@@ -9,6 +9,10 @@ FactoryGirl.define do
country "EU"
raw_password "PasswordABC123"
+ after(:create) do |user|
+ create(:profile, user: user)
+ end
+
factory :user_with_team do
after(:create) do |user|
create(:team, founder: user)
diff --git a/spec/features/calendar/google_calendar_widget_spec.rb b/spec/features/calendar/google_calendar_widget_spec.rb
new file mode 100644
index 0000000..6cdb3b7
--- /dev/null
+++ b/spec/features/calendar/google_calendar_widget_spec.rb
@@ -0,0 +1,53 @@
+require 'spec_helper'
+
+feature 'Google Calendar widget' do
+ let(:time) { Time.zone.local(2014, 4, 1, 12, 0, 0) }
+ let(:events_list_json) { JSON.parse(File.read(Rails.root.join('spec/fixtures/google_calendar.json'))) }
+ let!(:user) { create(:user) }
+
+ before do
+ Timecop.travel(time)
+
+ GoogleCalendar::Request.stub(:events_list) do
+ GoogleCalendar::EventList.new(events_list_json, Time.zone.name)
+ end
+
+ visit root_path
+ end
+
+ scenario 'the most recent upcoming event should appear correctly' do
+ expect(first_event).to have_content("Div 2B: el'pheer vs. RadicaL")
+ end
+
+ feature 'Timezones offsets' do
+ scenario 'when a user is logged out, CEST is default' do
+ expect(first_event).to have_content("20:30 CEST")
+ end
+
+ scenario 'when a user is logged in, their local timezone is used' do
+ sign_in_as(user)
+ change_timezone_for(user, timezone_us_east)
+ visit root_path
+
+ expect(first_event).to have_content(timezone_adjusted)
+ end
+ end
+
+ private
+
+ def first_event
+ page.find(:xpath, "//div[@id = 'index-calendar']/div/div[@class = 'content'][1]")
+ end
+
+ def timezone_adjusted
+ if Time.now.dst?
+ "14:30 EDT"
+ else
+ "15:30 EST"
+ end
+ end
+
+ def timezone_us_east
+ "Eastern Time (US & Canada)"
+ end
+end
\ No newline at end of file
diff --git a/spec/fixtures/google_calendar.json b/spec/fixtures/google_calendar.json
new file mode 100644
index 0000000..1db765f
--- /dev/null
+++ b/spec/fixtures/google_calendar.json
@@ -0,0 +1,763 @@
+{
+ "kind": "calendar#events",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/uXUVU6PbSJC9e6cCh7-EC4OsKu0\"",
+ "summary": "NSL Season 4 Confirmed Match Schedule",
+ "description": "",
+ "updated": "2014-04-01T20:18:31.372Z",
+ "timeZone": "America/New_York",
+ "accessRole": "reader",
+ "items": [
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NTM1ODMwOTgxMjAwMA\"",
+ "id": "gsq5f4k3mhg4keuqu1hqom1h18",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=Z3NxNWY0azNtaGc0a2V1cXUxaHFvbTFoMTggdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-19T21:40:28.000Z",
+ "updated": "2014-03-20T23:31:49.812Z",
+ "summary": "Div 3A: Silvermoon vs. Frequency (http://twitch.tv/feathermonster)",
+ "description": "http://www.ensl.org/matches/5488\n\nWeek 1 matchup. \n\nReferee: NeXuS\nCaster: Feathermonster\nStream: http://twitch.tv/feathermonster",
+ "creator": {
+ "email": "joeyh89@vt.edu",
+ "displayName": "Joey Hutchins"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Matches",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-20T22:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-21T00:00:00-04:00"
+ },
+ "iCalUID": "gsq5f4k3mhg4keuqu1hqom1h18@google.com",
+ "sequence": 1
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NTM1ODM4NTQyMDAwMA\"",
+ "id": "7g1k46eq471fsrsub1hqiqa4do",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=N2cxazQ2ZXE0NzFmc3JzdWIxaHFpcWE0ZG8gdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-19T21:37:32.000Z",
+ "updated": "2014-03-20T23:33:05.420Z",
+ "summary": "Div 2B: WongaNS vs. 2hrsLater (http://hitbox.tv/danjio)",
+ "description": "http://www.ensl.org/matches/5509\n\nWeek 1 matchup. \n\nReferee: Sohma\nCaster: Danjio\nStream: http://hitbox.tv/danjio",
+ "creator": {
+ "email": "joeyh89@vt.edu",
+ "displayName": "Joey Hutchins"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Matches",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-26T15:45:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-26T17:45:00-04:00"
+ },
+ "transparency": "transparent",
+ "iCalUID": "7g1k46eq471fsrsub1hqiqa4do@google.com",
+ "sequence": 4
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NTQyMTI1MzAzMDAwMA\"",
+ "id": "4bkilrunk0b0n2bl49v2n2tfok",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=NGJraWxydW5rMGIwbjJibDQ5djJuMnRmb2sgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-19T17:39:23.000Z",
+ "updated": "2014-03-21T17:00:53.030Z",
+ "summary": "Div 1: Gnarcolepsy vs. Singularity (http://www.twitch.tv/gold_n)",
+ "description": "http://www.ensl.org/matches/5545\n\nWeek 1 matchup. \n\nReferee: Jehuty\nCaster: Golden & joshhhy\nStream: http://www.twitch.tv/gold_n",
+ "creator": {
+ "email": "joeyh89@vt.edu",
+ "displayName": "Joey Hutchins"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Matches",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-23T20:00:00-04:00",
+ "timeZone": "America/Los_Angeles"
+ },
+ "end": {
+ "dateTime": "2014-03-23T22:00:00-04:00",
+ "timeZone": "America/Los_Angeles"
+ },
+ "transparency": "transparent",
+ "iCalUID": "4bkilrunk0b0n2bl49v2n2tfok@google.com",
+ "sequence": 1
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NTQyOTg3NjIwMTAwMA\"",
+ "id": "i8vir19jo5vgsf57qb1gjuldak",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=aTh2aXIxOWpvNXZnc2Y1N3FiMWdqdWxkYWsgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-21T19:23:38.000Z",
+ "updated": "2014-03-21T19:24:36.201Z",
+ "summary": "Div 4B: PinkFluffyGorges vs. FrenchCompany (http://www.twitch.tv/nittai_nev)",
+ "description": "http://www.ensl.org/matches/5582\n\nWeek 1 matchup. \n\nReferee: Yaluzan\nCaster: Nittai\nStream: http://www.twitch.tv/nittai_nev",
+ "creator": {
+ "email": "joeyh89@vt.edu",
+ "displayName": "Joey Hutchins"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-22T16:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-22T18:00:00-04:00"
+ },
+ "iCalUID": "i8vir19jo5vgsf57qb1gjuldak@google.com",
+ "sequence": 0
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NTQzODc1MTM2MTAwMA\"",
+ "id": "2m5v78g88hqq02evfhg5vn9ka8",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=Mm01djc4Zzg4aHFxMDJldmZoZzV2bjlrYTggdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-21T21:51:27.000Z",
+ "updated": "2014-03-21T21:52:31.361Z",
+ "summary": "Div 2A: Perfect Peckers vs. Intent (http://www.twitch.tv/vindalo0)",
+ "description": "http://www.ensl.org/matches/5532\n\nWeek 1 matchup. \n\nReferee: Unique\nCaster: Vindaloo\nStream: http://www.twitch.tv/vindalo0",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-22T07:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-22T09:00:00-04:00"
+ },
+ "iCalUID": "2m5v78g88hqq02evfhg5vn9ka8@google.com",
+ "sequence": 0
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NTUzNDU1MTgxMTAwMA\"",
+ "id": "i7fh8brdlj7im5c7thivp6hc9g",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=aTdmaDhicmRsajdpbTVjN3RoaXZwNmhjOWcgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-20T19:21:50.000Z",
+ "updated": "2014-03-23T00:29:11.811Z",
+ "summary": "Div 3A: Gorge Busters vs. >>ACV<< ( http://www.hitbox.tv/danjio)",
+ "description": "http://www.ensl.org/matches/5489\n\nWeek 1 matchup. \n\nReferee: \nCaster: Danjio\nStream: http://hitbox.tv/danjio",
+ "creator": {
+ "email": "joeyh89@vt.edu",
+ "displayName": "Joey Hutchins"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Matches",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-23T14:30:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-23T16:30:00-04:00"
+ },
+ "iCalUID": "i7fh8brdlj7im5c7thivp6hc9g@google.com",
+ "sequence": 3
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NTU4NDU3Mjc1MjAwMA\"",
+ "id": "jt9upnr744ooit6rhijqs248gc",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=anQ5dXBucjc0NG9vaXQ2cmhpanFzMjQ4Z2MgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-23T14:22:52.000Z",
+ "updated": "2014-03-23T14:22:52.752Z",
+ "summary": "Div 4A: UKTeamplay vs. LuckyFkers (http://www.twitch.tv/ISEGaming)",
+ "description": "http://www.ensl.org/matches/5596\n\nWeek 1 matchup.\n\nReferee: Argosh \nCaster: ItsSuperEffective \nStream: http://www.twitch.tv/ISEGaming",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-23T15:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-23T17:00:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "jt9upnr744ooit6rhijqs248gc@google.com",
+ "sequence": 0
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NTYwMDkwNzc4OTAwMA\"",
+ "id": "mvt93vu72idnqo2p16oklqe5i8",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=bXZ0OTN2dTcyaWRucW8ycDE2b2tscWU1aTggdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-23T00:33:02.000Z",
+ "updated": "2014-03-23T18:55:07.789Z",
+ "summary": "Div 3B: 3hrsLater vs. PowerUP! (http://www.twitch.tv/RIdeOnSkulks)",
+ "description": "http://www.ensl.org/matches/5475\n\nWeek 1 matchup.\n\nReferee: Pelargir\nCaster: RioS \nStream: http://www.twitch.tv/RIdeOnSkulks",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-23T15:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-23T17:00:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "mvt93vu72idnqo2p16oklqe5i8@google.com",
+ "sequence": 0
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NTc0MzY4ODE0NDAwMA\"",
+ "id": "ps74a0vskblsi52i24dkicvklg",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=cHM3NGEwdnNrYmxzaTUyaTI0ZGtpY3ZrbGcgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-25T10:34:48.000Z",
+ "updated": "2014-03-25T10:34:48.144Z",
+ "summary": "Div 1: Joan of Arc™ vs. Virtual Dejection (http://www.hitbox.tv/danjio)",
+ "description": "http://www.ensl.org/matches/5547\n\nWeek 1 Matchup.\n\nReferee: Pelargir\nCaster: Danjio\nStream: http://www.hitbox.tv/danjio",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-29T10:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-29T12:00:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "ps74a0vskblsi52i24dkicvklg@google.com",
+ "sequence": 0
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NTc2NTM5ODQwNzAwMA\"",
+ "id": "aafemih6n92b5v5o70k5imd348",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=YWFmZW1paDZuOTJiNXY1bzcwazVpbWQzNDggdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-25T10:31:01.000Z",
+ "updated": "2014-03-25T16:36:38.407Z",
+ "summary": "Div 4B: [karvalakki] vs. TAWsome (http://www.twitch.tv/ggKaneh)",
+ "description": "http://www.ensl.org/matches/5581\n\nWeek 1 Matchup.\n\nReferee: Pelargir\nCaster: Kaneh\nStream: http://www.twitch.tv/ggKaneh",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-25T15:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-25T17:00:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "aafemih6n92b5v5o70k5imd348@google.com",
+ "sequence": 0
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NTkxODQ5MDc2ODAwMA\"",
+ "id": "mjipkmgdia834bp7f2ksmnf0rk",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=bWppcGttZ2RpYTgzNGJwN2Yya3NtbmYwcmsgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-27T11:08:10.000Z",
+ "updated": "2014-03-27T11:08:10.768Z",
+ "summary": "Div 3B: TAW ♥ vs. HBZ (http://www.twitch.tv/feathermonster)",
+ "description": "http://www.ensl.org/matches/5474\n\nWeek 1 Matchup.\n\nReferee: Pelargir\nCaster: Feathermonster\nStream: http://www.twitch.tv/feathermonster",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-27T15:30:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-27T17:30:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "mjipkmgdia834bp7f2ksmnf0rk@google.com",
+ "sequence": 0
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NTkxODUyNjAxMjAwMA\"",
+ "id": "49jnm0eh22lrjgg6738jr85d3k",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=NDlqbm0wZWgyMmxyamdnNjczOGpyODVkM2sgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-25T10:36:45.000Z",
+ "updated": "2014-03-27T11:08:46.012Z",
+ "summary": "Div 2B: Table For Six vs. -/AUS/- (http://www.twitch.tv/schwaschwa)",
+ "description": "http://www.ensl.org/matches/5511\n\nWeek 1 Matchup.\n\nReferee: Tico\nCaster: Schwa\nStream: http://www.twitch.tv/schwaschwa",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-29T22:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-30T00:00:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "49jnm0eh22lrjgg6738jr85d3k@google.com",
+ "sequence": 0
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NTkxODk5MzEwMjAwMA\"",
+ "id": "h7k7efkmoorimfolqkcn3833l0",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=aDdrN2Vma21vb3JpbWZvbHFrY24zODMzbDAgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-24T15:12:39.000Z",
+ "updated": "2014-03-27T11:16:33.102Z",
+ "summary": "Div 4A: She-Wolves vs. Diamond Gamers (http://www.twitch.tv/ISEGaming)",
+ "description": "http://www.ensl.org/matches/5597\n\nWeek 1 matchup.\n\nReferee: Tico\nCaster: ItsSuperEffective\nStream: http://www.twitch.tv/ISEGaming",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-31T21:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-31T23:00:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "h7k7efkmoorimfolqkcn3833l0@google.com",
+ "sequence": 3
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NjAxNTI1MDczNTAwMA\"",
+ "id": "gq026ueot20a8hfv8leu66r7g0",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=Z3EwMjZ1ZW90MjBhOGhmdjhsZXU2NnI3ZzAgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-28T14:00:44.000Z",
+ "updated": "2014-03-28T14:00:50.735Z",
+ "summary": "Div 3A: TkMaster vs. Neuromancers (http://www.twitch.tv/sadenki)",
+ "description": "http://www.ensl.org/matches/5493\n\nWeek 2 Matchup.\n\nSTREAM IN FRENCH\n\nReferee:\nCaster: Sadenki\nStream: http://www.twitch.tv/sadenki",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-30T14:30:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-30T16:30:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "gq026ueot20a8hfv8leu66r7g0@google.com",
+ "sequence": 0
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NjA0NDg1OTEyMDAwMA\"",
+ "id": "5kp8kjnmhf0dipvc322quf2f6g",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=NWtwOGtqbm1oZjBkaXB2YzMyMnF1ZjJmNmcgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-27T22:26:55.000Z",
+ "updated": "2014-03-28T22:14:19.120Z",
+ "summary": "Div 3A: TkMaster vs. Vexta Ω (http://www.twitch.tv/sadenki)",
+ "description": "http://www.ensl.org/matches/5490\n\nWeek 1 Matchup.\n\nSTREAM IN FRENCH\n\nReferee: Sohma\nCaster: Sadenki & Mirmouz\nStream: http://www.twitch.tv/sadenki",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-31T14:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-31T16:00:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "5kp8kjnmhf0dipvc322quf2f6g@google.com",
+ "sequence": 1
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NjA4OTY3NjMyMzAwMA\"",
+ "id": "8u7mrqlspe78mia6tu21pbst1k",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=OHU3bXJxbHNwZTc4bWlhNnR1MjFwYnN0MWsgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-29T10:39:01.000Z",
+ "updated": "2014-03-29T10:41:16.323Z",
+ "summary": "Div 1: onFire vs. RaZe (http://www.twitch.tv/ren26)",
+ "description": "http://www.ensl.org/matches/5548\n\nWeek 1 Matchup.\n\nReferee:\nCaster: Ren26\nStream: http://www.twitch.tv/ren26",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-29T19:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-29T21:00:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "8u7mrqlspe78mia6tu21pbst1k@google.com",
+ "sequence": 0
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NjExNTY2Mjc0NDAwMA\"",
+ "id": "c46jqcbqt1kb95roo0gedskhd0",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=YzQ2anFjYnF0MWtiOTVyb28wZ2Vkc2toZDAgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-29T17:54:22.000Z",
+ "updated": "2014-03-29T17:54:22.744Z",
+ "summary": "Div 2A: Vexta vs. Aphex (http://www.twitch.tv/ren26)",
+ "description": "http://www.ensl.org/matches/5531\n\nWeek 1 Matchup.\n\nReferees: Tico & Zebroe\nCaster: Ren26\nStream: http://www.twitch.tv/ren26",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-29T16:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-29T18:00:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "c46jqcbqt1kb95roo0gedskhd0@google.com",
+ "sequence": 0
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NjEyNTcxMzQ1MzAwMA\"",
+ "id": "eeduo3nnj33hci76hff49ii8ts",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=ZWVkdW8zbm5qMzNoY2k3NmhmZjQ5aWk4dHMgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-29T20:41:53.000Z",
+ "updated": "2014-03-29T20:41:53.453Z",
+ "summary": "Premiere: Saunamen vs. iMAGINE (http://www.twitch.tv/ren26)",
+ "description": "http://www.ensl.org/matches/5429\n\nWeek 1 Matchup.\n\nReferee: Pelargir\nCaster: Ren26\nStream: http://www.twitch.tv/ren26",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-30T14:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-30T16:00:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "eeduo3nnj33hci76hff49ii8ts@google.com",
+ "sequence": 0
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NjE4MDAzODU3ODAwMA\"",
+ "id": "7rdlnhgllqii9582cdtfhki3lc",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=N3JkbG5oZ2xscWlpOTU4MmNkdGZoa2kzbGMgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-27T11:10:53.000Z",
+ "updated": "2014-03-30T11:47:18.578Z",
+ "summary": "Premiere: Legendary Snails vs. Titus Gaming (http://www.twitch.tv/naturalselection2)",
+ "description": "http://www.ensl.org/matches/5428\n\nWeek 1 Matchup.\n\nReferee: Yaluzan\nCaster: WasabiOne & Ren26\nStream: http://www.twitch.tv/naturalselection2",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-30T12:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-30T14:00:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "7rdlnhgllqii9582cdtfhki3lc@google.com",
+ "sequence": 0
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NjE4MDE0NzAwMzAwMA\"",
+ "id": "aflokq41l64msqdq1q1pmuedqs",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=YWZsb2txNDFsNjRtc3FkcTFxMXBtdWVkcXMgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-28T10:11:46.000Z",
+ "updated": "2014-03-30T11:49:07.003Z",
+ "summary": "Div 4B: TAWsome vs. FrenchCompany (http://www.twitch.tv/feathermonster )",
+ "description": "http://www.ensl.org/matches/5585\n\nWeek 2 Matchup.\n\nReferee:\nCaster: Feathermonster\nStream: http://www.twitch.tv/feathermonster",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-30T15:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-30T17:00:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "aflokq41l64msqdq1q1pmuedqs@google.com",
+ "sequence": 4
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NjE4MDQ3NDIzMTAwMA\"",
+ "id": "274hn9kkkff6hme7k6de1aun9s",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=Mjc0aG45a2trZmY2aG1lN2s2ZGUxYXVuOXMgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-24T15:28:41.000Z",
+ "updated": "2014-03-30T11:54:34.231Z",
+ "summary": "Div 2B: el'pheer vs. RadicaL (http://www.twitch.tv/feathermonster)",
+ "description": "http://www.ensl.org/matches/5510\n\nWeek 1 matchup.\n\nReferee:\nCaster: Feathermonster\nStream: http://www.twitch.tv/feathermonster",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-04-03T14:30:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-04-03T16:30:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "274hn9kkkff6hme7k6de1aun9s@google.com",
+ "sequence": 2
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NjE5MjY3Nzg0MTAwMA\"",
+ "id": "ucrpfl5eeoldr1g29cq35s56o0",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=dWNycGZsNWVlb2xkcjFnMjljcTM1czU2bzAgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-27T22:22:21.000Z",
+ "updated": "2014-03-30T15:17:57.841Z",
+ "summary": "Div 2A: Cheesecake vs. Gorge Casting Couch (http://www.twitch.tv/ggKaneh)",
+ "description": "http://www.ensl.org/matches/5530\n\nWeek 1 Matchup.\n\nReferee: Danjio\nCaster: Kaneh\nStream: http://www.twitch.tv/ggKaneh",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-03-30T15:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-03-30T17:00:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "ucrpfl5eeoldr1g29cq35s56o0@google.com",
+ "sequence": 2
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NjI3Mzk4OTc0MzAwMA\"",
+ "id": "4dtgq7c1mk583gjglomk60tn80",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=NGR0Z3E3YzFtazU4M2dqZ2xvbWs2MHRuODAgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-31T13:53:09.000Z",
+ "updated": "2014-03-31T13:53:09.743Z",
+ "summary": "Div 3B: OMNOM vs. Mister (twitch.tv/LoopyCaster)",
+ "description": "http://www.ensl.org/matches/5473\n\nWeek 1 Matchup.\n\nReferee: \nCasters! Schwa & Loopy\nStream: http://www.twitch.tv/LoopyCaster",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-04-05T14:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-04-05T16:00:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "4dtgq7c1mk583gjglomk60tn80@google.com",
+ "sequence": 0
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NjI3NDA3NTQzMTAwMA\"",
+ "id": "do011hdp17c36c8rkoobi6lksk",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=ZG8wMTFoZHAxN2MzNmM4cmtvb2JpNmxrc2sgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-24T15:26:11.000Z",
+ "updated": "2014-03-31T13:54:35.431Z",
+ "summary": "Div 1: Gnarcolepsy vs. Ant (http://www.twitch.tv/schwaschwa)",
+ "description": "http://www.ensl.org/matches/5549\n\nWeek 2 matchup.\n\nReferee: \nCaster: Schwa\nStream: http://www.twitch.tv/schwaschwa",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-04-05T15:30:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-04-05T17:30:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "do011hdp17c36c8rkoobi6lksk@google.com",
+ "sequence": 3
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NjI3NDE2NTMxMzAwMA\"",
+ "id": "eo46nhg92f1t3domncc0qiejlo",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=ZW80Nm5oZzkyZjF0M2RvbW5jYzBxaWVqbG8gdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-31T13:56:05.000Z",
+ "updated": "2014-03-31T13:56:05.313Z",
+ "summary": "Div 4B: [karvalakki] vs. PinkFluffyGorges (twitch.tv/LoopyCaster)",
+ "description": "http://www.ensl.org/matches/5584\n\nWeek 2 Matchup.\n\nReferee: \nCaster: Loopy\nStream: http://www.ensl.org/matches/5584",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-04-06T14:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-04-06T16:00:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "eo46nhg92f1t3domncc0qiejlo@google.com",
+ "sequence": 0
+ },
+ {
+ "kind": "calendar#event",
+ "etag": "\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTM5NjI3NDMwNDE1MzAwMA\"",
+ "id": "1lb8cg9d6m2nl0bs0ude42nplc",
+ "status": "confirmed",
+ "htmlLink": "https://www.google.com/calendar/event?eid=MWxiOGNnOWQ2bTJubDBiczB1ZGU0Mm5wbGMgdnQuZWR1X281dHVnc3NqZTRoNnBqbnZ2aHNuNmw3bG9jQGc",
+ "created": "2014-03-31T13:58:24.000Z",
+ "updated": "2014-03-31T13:58:24.153Z",
+ "summary": "Div 3B: Mister vs. HBZ (twitch.tv/vindalo0)",
+ "description": "http://www.ensl.org/matches/5477\n\nWeek 2 Matchup.\n\nReferee:\nCaster: Vindaloo\nStream: http://www.twitch.tv/vindalo0",
+ "creator": {
+ "email": "pelargir.lsa@gmail.com",
+ "displayName": "Pelargir Chazalet"
+ },
+ "organizer": {
+ "email": "vt.edu_o5tugssje4h6pjnvvhsn6l7loc@group.calendar.google.com",
+ "displayName": "NSL Season 4 Confirmed Match Schedule",
+ "self": true
+ },
+ "start": {
+ "dateTime": "2014-04-04T16:00:00-04:00"
+ },
+ "end": {
+ "dateTime": "2014-04-04T18:00:00-04:00"
+ },
+ "visibility": "public",
+ "iCalUID": "1lb8cg9d6m2nl0bs0ude42nplc@google.com",
+ "sequence": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/spec/services/api/v1/users_collection_spec.rb b/spec/services/api/v1/users_collection_spec.rb
index a4844cc..9d29c02 100644
--- a/spec/services/api/v1/users_collection_spec.rb
+++ b/spec/services/api/v1/users_collection_spec.rb
@@ -1,3 +1,5 @@
+require 'spec_helper'
+
describe Api::V1::UsersCollection do
let(:collection) { Api::V1::UsersCollection.new }
diff --git a/spec/support/features/session_helpers.rb b/spec/support/features/session_helpers.rb
index b22d459..7a888c5 100644
--- a/spec/support/features/session_helpers.rb
+++ b/spec/support/features/session_helpers.rb
@@ -6,7 +6,16 @@ module Features
fill_in "login_username", with: user.username
fill_in "login_password", with: user.raw_password
- click_button 'Login'
+ click_button I18n.t('helpers.submit.user.login')
+ end
+
+ def change_timezone_for(user, timezone)
+ visit edit_user_path(user.id)
+
+ click_link I18n.t('profile.locals')
+ find("option[value='#{timezone}']").select_option
+
+ click_button I18n.t('helpers.submit.user.update')
end
end
end
\ No newline at end of file