Skip to content

Commit

Permalink
Users can associate with their Meetup account on the Account page.
Browse files Browse the repository at this point in the history
This does an OAuth request with Meetup to determine the user's meetup ID.
RSVPs from past Meetup events will show up on the user's Profile page.
  • Loading branch information
tjgrathwell committed Mar 3, 2013
1 parent 22931ac commit d457c79
Show file tree
Hide file tree
Showing 18 changed files with 267 additions and 46 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ gem 'select2-rails'
gem 'active_hash'
gem 'sanitize'
gem 'gmaps4rails'
gem 'omniauth-meetup'

group :production do
gem 'pg'
Expand All @@ -25,6 +26,7 @@ group :assets do
end

group :development do
gem 'sextant'
gem 'quiet_assets'
gem 'guard-rspec'
gem 'rb-fsevent'
Expand Down
27 changes: 27 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ GEM
railties (>= 3.0.0)
faker (1.1.2)
i18n (~> 0.5)
faraday (0.8.6)
multipart-post (~> 1.1)
faye-websocket (0.4.6)
eventmachine (>= 0.12.0)
ffi (1.3.1)
Expand All @@ -89,8 +91,10 @@ GEM
guard-rspec (2.3.3)
guard (>= 1.1)
rspec (~> 2.11)
hashie (1.2.0)
hike (1.2.1)
http_parser.rb (0.5.3)
httpauth (0.2.0)
i18n (0.6.1)
journey (1.0.4)
jquery-datatables-rails (1.11.2)
Expand All @@ -102,6 +106,8 @@ GEM
jquery-rails
railties (>= 3.1.0)
json (1.7.6)
jwt (0.1.5)
multi_json (>= 1.0)
launchy (2.1.2)
addressable (~> 2.3)
libwebsocket (0.1.7.1)
Expand All @@ -122,8 +128,24 @@ GEM
railties (~> 3.0)
thor (~> 0.14)
multi_json (1.5.0)
multipart-post (1.2.0)
nested_form (0.3.1)
nokogiri (1.5.6)
oauth2 (0.8.1)
faraday (~> 0.8)
httpauth (~> 0.1)
jwt (~> 0.1.4)
multi_json (~> 1.0)
rack (~> 1.2)
omniauth (1.1.3)
hashie (~> 1.2)
rack
omniauth-meetup (0.0.6)
omniauth (~> 1.0)
omniauth-oauth2 (~> 1.0)
omniauth-oauth2 (1.1.1)
oauth2 (~> 0.8.0)
omniauth (~> 1.0)
orm_adapter (0.4.0)
pg (0.14.1)
poltergeist (1.0.2)
Expand Down Expand Up @@ -195,6 +217,9 @@ GEM
libwebsocket (~> 0.1.3)
multi_json (~> 1.0)
rubyzip
sextant (0.2.3)
activesupport (>= 3.2)
rails (>= 3.2)
shoulda-matchers (1.4.2)
activesupport (>= 3.0.0)
bourne (~> 1.1.2)
Expand Down Expand Up @@ -249,6 +274,7 @@ DEPENDENCIES
launchy
modernizr_rails
nested_form
omniauth-meetup
pg
poltergeist
quiet_assets
Expand All @@ -258,6 +284,7 @@ DEPENDENCIES
sanitize
sass-rails
select2-rails
sextant
shoulda-matchers
sqlite3
terminal-notifier-guard
Expand Down
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: rails server thin -p $PORT -e $RACK_ENV
10 changes: 10 additions & 0 deletions app/assets/stylesheets/application.css.scss
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,14 @@ a {

#map label {
width: auto; display:inline;
}

.meetup-association {
border: 3px solid rgb(80, 80, 97);
background-color: rgb(200, 200, 200);
width: 500px;
margin: 0 auto;
text-align: center;
padding: 15px;
border-radius: 10px;
}
9 changes: 9 additions & 0 deletions app/controllers/omniauths_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class OmniauthsController < ApplicationController
before_filter :authenticate_user!

def callback
auth_hash = request.env['omniauth.auth']
MeetupImporter.new.associate_user(current_user, auth_hash['uid'])
redirect_to edit_user_registration_path
end
end
32 changes: 32 additions & 0 deletions app/services/meetup_importer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,38 @@ def dump_events
ap event_jsons.map { |hsh| hsh.slice('id', 'name', 'description', 'event_url') }, plain: true
end

def associate_user bridgetroll_user, meetup_id
raise "User already associated with #{bridgetroll_user.meetup_id}" if bridgetroll_user.meetup_id.present?

meetup_user = MeetupUser.where(meetup_id: meetup_id).first
raise "No user with ID #{meetup_id}" unless meetup_user.present?

Rsvp.transaction do
Rsvp.where(user_type: 'MeetupUser', user_id: meetup_user.id).find_each do |rsvp|
rsvp.user = bridgetroll_user
rsvp.save!
end

bridgetroll_user.meetup_id = meetup_id
bridgetroll_user.save!
end
end

def disassociate_user bridgetroll_user
raise "User is not associated with a meetup account!" unless bridgetroll_user.meetup_id.present?

meetup_user = MeetupUser.where(meetup_id: bridgetroll_user.meetup_id).first
Rsvp.transaction do
Rsvp.where(user_type: 'User', user_id: bridgetroll_user.id).find_each do |rsvp|
rsvp.user = meetup_user
rsvp.save!
end

bridgetroll_user.meetup_id = nil
bridgetroll_user.save!
end
end

private

def get_api_response_for path, params=nil
Expand Down
12 changes: 12 additions & 0 deletions app/views/devise/registrations/edit.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
<h1>Edit <%= resource_name.to_s.humanize %></h1>

<div class='meetup-association'>

<% if resource.meetup_id.present? %>
<p>This account is associated with <%= link_to "meetup user #{resource.meetup_id}.", "http://www.meetup.com/members/#{resource.meetup_id}/" %></p>
<% else %>
<p>This account is not associated with a SFRuby Meetup account.</p>

<p>If you associate with your meetup account, Bridgetroll can show you information about past workshops you have attended.</p>
<%= link_to 'Associate with Meetup account', "/auth/meetup", class: 'btn' %>
<% end %>
</div>

<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
<%= devise_error_messages! %>

Expand Down
30 changes: 1 addition & 29 deletions app/views/meetup_users/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,34 +1,6 @@
<h1>Events attended by <%= @user.full_name %></h1>

<table class="datatable table table-striped table-bordered table-condensed">
<thead>
<tr>
<th>Title</th>
<th>Date</th>
<th>Location</th>
<th>Role</th>
</tr>
</thead>
<tbody>
<% @rsvps.each do |rsvp| %>
<% event = rsvp.event %>
<tr>
<td>
<%= link_to event.title, event %>
<% if event.meetup_student_event_id %>
<%= link_to "[Student Meetup]", "http://www.sfruby.info/events/#{event.meetup_student_event_id}/", class: 'meetup-link' %>
<% end %>
<% if event.meetup_volunteer_event_id %>
<%= link_to "[Volunteer Meetup]", "http://www.sfruby.info/events/#{event.meetup_volunteer_event_id}/", class: 'meetup-link' %>
<% end %>
</td>
<td><%= formatted_session_date(event.event_sessions.first) %></td>
<td><%= event.location.name rescue nil %></td>
<td><%= rsvp.role.title %></td>
</tr>
<% end %>
</tbody>
</table>
<%= render 'shared/rsvps', rsvps: @rsvps %>

<ul class='actions'>
<li class='btn'><%= link_to 'Meetup User Index', meetup_users_path %></li>
Expand Down
13 changes: 3 additions & 10 deletions app/views/profiles/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,9 @@
<%= @profile.bio %>
</div>

<strong>Workshop History</strong>
<table class='table'>
<thead>
<tr>
<td>Role</td>
<td>Date</td>
<td>Venue</td>
</tr>
</thead>
</table>
<h3>Workshop History</h3>

<%= render 'shared/rsvps', rsvps: @user.rsvps %>

<ul class='actions'>
<% if @user == current_user %>
Expand Down
29 changes: 29 additions & 0 deletions app/views/shared/_rsvps.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<table class="datatable table table-striped table-bordered table-condensed">
<thead>
<tr>
<th>Title</th>
<th>Date</th>
<th>Location</th>
<th>Role</th>
</tr>
</thead>
<tbody>
<% rsvps.each do |rsvp| %>
<% event = rsvp.event %>
<tr>
<td>
<%= link_to event.title, event %>
<% if event.meetup_student_event_id %>
<%= link_to "[Student Meetup]", "http://www.sfruby.info/events/#{event.meetup_student_event_id}/", class: 'meetup-link' %>
<% end %>
<% if event.meetup_volunteer_event_id %>
<%= link_to "[Volunteer Meetup]", "http://www.sfruby.info/events/#{event.meetup_volunteer_event_id}/", class: 'meetup-link' %>
<% end %>
</td>
<td><%= formatted_session_date(event.event_sessions.first) %></td>
<td><%= event.location.name rescue nil %></td>
<td><%= rsvp.role.title %></td>
</tr>
<% end %>
</tbody>
</table>
3 changes: 3 additions & 0 deletions config/initializers/omniauth.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Rails.application.config.middleware.use OmniAuth::Builder do
provider :meetup, ENV['MEETUP_OAUTH_KEY'], ENV['MEETUP_OAUTH_SECRET']
end
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@
resources :checkins, :only => [:index, :create, :destroy]
end
end

get "/auth/:provider/callback" => "omniauths#callback"
end
5 changes: 5 additions & 0 deletions db/migrate/20130303204435_add_meetup_id_to_users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddMeetupIdToUsers < ActiveRecord::Migration
def change
add_column :users, :meetup_id, :integer
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.

ActiveRecord::Schema.define(:version => 20130302211017) do
ActiveRecord::Schema.define(:version => 20130303204435) do

create_table "event_sessions", :force => true do |t|
t.datetime "starts_at"
Expand Down Expand Up @@ -114,6 +114,7 @@
t.boolean "admin", :default => false
t.string "first_name"
t.string "last_name"
t.integer "meetup_id"
end

add_index "users", ["confirmation_token"], :name => "index_users_on_confirmation_token", :unique => true
Expand Down
22 changes: 22 additions & 0 deletions spec/controllers/omniauths_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
require 'spec_helper'
require Rails.root.join('spec', 'services', 'meetup_request_fixtures')

describe OmniauthsController do
context "after meetup hits the callback" do
before do
@user = create(:user)
sign_in @user

OmniAuth.config.test_mode = true
authed_params = MeetupRequestFixtures.oauth_response(7654321)
OmniAuth.config.mock_auth[:meetup] = OmniAuth::AuthHash.new(authed_params)
request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:meetup]
end

it 'informs the meetup importer that this bridgetroll user has claimed this meetup user' do
MeetupImporter.any_instance.should_receive(:associate_user).with(@user, 7654321)

get :callback, provider: :meetup
end
end
end
17 changes: 11 additions & 6 deletions spec/requests/profiles_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,16 @@
page.should have_content("This is my bio...")
end

it "should be able to see workshop history" do
click_link "Profile"
page.should have_content("Workshop History")
page.should have_content("Role")
page.should have_content("Date")
page.should have_content("Venue")
context "when the user has attended some workshops" do
before do
event = create(:event, title: 'BridgeBridge')
event.rsvps.create!(user: @user, role_id: Role::VOLUNTEER)
end

it "should be able to see workshop history" do
click_link "Profile"
page.should have_content("Workshop History")
page.should have_content("BridgeBridge")
end
end
end
Loading

0 comments on commit d457c79

Please sign in to comment.