Merge 514a88e0be into a4ef10cf1b
This commit is contained in:
commit
f1e37df5a0
21 changed files with 264 additions and 3 deletions
3
Gemfile
3
Gemfile
|
|
@ -183,9 +183,10 @@ gem 'dotenv-rails'
|
|||
gem 'faker'
|
||||
# for seeds
|
||||
gem 'factory_girl_rails'
|
||||
|
||||
# for integrating Stripe payment gateway
|
||||
gem 'stripe'
|
||||
#For embedding tweets
|
||||
gem 'twitter'
|
||||
|
||||
# Provides Sprockets implementation for Rails Asset Pipeline
|
||||
gem 'sprockets-rails'
|
||||
|
|
|
|||
25
Gemfile.lock
25
Gemfile.lock
|
|
@ -82,6 +82,7 @@ GEM
|
|||
bootstrap3-datetimepicker-rails (3.0.3)
|
||||
momentjs-rails (>= 2.8.1)
|
||||
browser (0.6.0)
|
||||
buftok (0.2.0)
|
||||
builder (3.2.2)
|
||||
byebug (3.1.2)
|
||||
columnize (~> 0.8)
|
||||
|
|
@ -167,6 +168,7 @@ GEM
|
|||
dotenv-rails (2.1.1)
|
||||
dotenv (= 2.1.1)
|
||||
railties (>= 4.0, < 5.1)
|
||||
equalizer (0.0.10)
|
||||
erubis (2.7.0)
|
||||
execjs (2.6.0)
|
||||
factory_girl (4.5.0)
|
||||
|
|
@ -214,8 +216,15 @@ GEM
|
|||
activesupport
|
||||
builder
|
||||
htmlentities (4.3.4)
|
||||
http (1.0.4)
|
||||
addressable (~> 2.3)
|
||||
http-cookie (~> 1.0)
|
||||
http-form_data (~> 1.0.1)
|
||||
http_parser.rb (~> 0.6.0)
|
||||
http-cookie (1.0.2)
|
||||
domain_name (~> 0.5)
|
||||
http-form_data (1.0.1)
|
||||
http_parser.rb (0.6.0)
|
||||
i18n (0.7.0)
|
||||
i18n_data (0.7.0)
|
||||
inversion (0.12.3)
|
||||
|
|
@ -253,6 +262,8 @@ GEM
|
|||
lumberjack (1.0.5)
|
||||
mail (2.6.3)
|
||||
mime-types (>= 1.16, < 3)
|
||||
memoizable (0.4.2)
|
||||
thread_safe (~> 0.3, >= 0.3.1)
|
||||
method_source (0.8.2)
|
||||
mime-types (2.99.1)
|
||||
mina (0.3.8)
|
||||
|
|
@ -277,6 +288,7 @@ GEM
|
|||
multi_xml (0.5.5)
|
||||
multipart-post (2.0.0)
|
||||
mysql2 (0.4.2)
|
||||
naught (1.1.0)
|
||||
netrc (0.11.0)
|
||||
nio4r (1.2.1)
|
||||
nokogiri (1.6.8)
|
||||
|
|
@ -460,6 +472,7 @@ GEM
|
|||
sprockets-rails (~> 2.0)
|
||||
shoulda-matchers (2.6.1)
|
||||
activesupport (>= 3.0.0)
|
||||
simple_oauth (0.3.1)
|
||||
simplecov (0.11.2)
|
||||
docile (~> 1.1.0)
|
||||
json (~> 1.8)
|
||||
|
|
@ -500,6 +513,17 @@ GEM
|
|||
ttfunk (1.1.1)
|
||||
turbolinks (2.5.3)
|
||||
coffee-rails
|
||||
twitter (5.16.0)
|
||||
addressable (~> 2.3)
|
||||
buftok (~> 0.2.0)
|
||||
equalizer (= 0.0.10)
|
||||
faraday (~> 0.9.0)
|
||||
http (~> 1.0)
|
||||
http_parser.rb (~> 0.6.0)
|
||||
json (~> 1.8)
|
||||
memoizable (~> 0.4.0)
|
||||
naught (~> 1.0)
|
||||
simple_oauth (~> 0.3.0)
|
||||
tzinfo (1.2.2)
|
||||
thread_safe (~> 0.1)
|
||||
uglifier (3.0.0)
|
||||
|
|
@ -628,6 +652,7 @@ DEPENDENCIES
|
|||
timecop
|
||||
transitions
|
||||
turbolinks
|
||||
twitter
|
||||
uglifier (>= 1.3.0)
|
||||
unobtrusive_flash (>= 3)
|
||||
web-console (~> 2.0)
|
||||
|
|
|
|||
12
INSTALL.md
12
INSTALL.md
|
|
@ -52,6 +52,10 @@ There are a couple of environment variables you can set to configure OSEM.
|
|||
| CLOUDINARY_URL | *string* | Configure your cloudinary.com cloud name and api key/secret
|
||||
| STRIPE_PUBLISHABLE_KEY | *string* | Publishable Key for Stripe Gateway
|
||||
| STRIPE_SECRET_KEY | *string* | Secret Key for Stripe Gateway
|
||||
| OSEM_TWITTER_CONSUMER_KEY | *string* | To embed tweets about the conference in the conference wide page
|
||||
| OSEM_TWITTER_CONSUMER_SECRET | *string* | To embed tweets about the conference in the conference wide page
|
||||
| OSEM_TWITTER_ACCESS_TOKEN | *string* | To embed tweets about the conference in the conference wide page
|
||||
| OSEM_TWITTER_ACCESS_TOKEN_SECRET | *string* | To embed tweets about the conference in the conference wide page
|
||||
|
||||
### Online Ticket Payments
|
||||
We use [Stripe](https://stripe.com) for accepting your ticket payments securely over the web.
|
||||
|
|
@ -71,6 +75,14 @@ $ bundle exec rake logo:reprocess
|
|||
### openID
|
||||
In order to use [openID](http://openid.net/) logins for your OSEM installation you need to register your application with the providers ([Google](https://code.google.com/apis/console#:access), [GitHub](https://github.com/settings/applications/new) or [Facebook](https://developers.facebook.com/)) and enter their API keys in `config/secrets.yml` file, changing the existing sample values.
|
||||
|
||||
### Twitter
|
||||
In order to embed conference tweets in the application you need to register your application here [twitter](https://apps.twitter.com/) and get twitter consumer and access keys.
|
||||
Add your Twitter API keys in `.env` file into these variables:
|
||||
OSEM_TWITTER_CONSUMER_KEY=""
|
||||
OSEM_TWITTER_CONSUMER_SECRET=""
|
||||
OSEM_TWITTER_ACCESS_TOKEN=""
|
||||
OSEM_TWITTER_ACCESS_TOKEN_SECRET=""
|
||||
|
||||
## Recurring Jobs
|
||||
=======
|
||||
Open a separate terminal and go into the directory where the rails app is present, and type the following to start the delayed_jobs worker for sending email notifications.
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
//= require osem-commercials
|
||||
//= require unobtrusive_flash
|
||||
//= require unobtrusive_flash_bootstrap
|
||||
//= require refresh_current_events
|
||||
|
||||
$(document).ready(function() {
|
||||
$('a[disabled=disabled]').click(function(event){
|
||||
|
|
|
|||
32
app/assets/javascripts/refresh_current_events.js
Normal file
32
app/assets/javascripts/refresh_current_events.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
$(document).ready(function() {
|
||||
// will call refreshCurrentEvents every 15 minutes
|
||||
setInterval(refreshCurrentEvents,900000);
|
||||
|
||||
// Only show the first child of tweet and sponsor containers on page load
|
||||
$('#tweet-container').children().hide();
|
||||
$('#tweet-container').children().eq(0).show();
|
||||
$('#sponsor-container').children().hide();
|
||||
$('#sponsor-container').children().eq(0).show();
|
||||
|
||||
setInterval(function(){ cycleVisibleElement($('#tweet-container'))}, 5000)
|
||||
setInterval(function(){ cycleVisibleElement($('#sponsor-container'))}, 10000)
|
||||
});
|
||||
|
||||
// Makes an ajax call for fresh data
|
||||
function refreshCurrentEvents(){
|
||||
$.ajax({
|
||||
url: "conference_info.js"
|
||||
});
|
||||
};
|
||||
|
||||
// Cycle through children in a container and toggles visibility
|
||||
function cycleVisibleElement(container){
|
||||
var childrens = $(container).children();
|
||||
for(var i = 0; i < childrens.length; i++ ){
|
||||
if(childrens.eq(i).is(":visible")){
|
||||
childrens.eq(i).hide();
|
||||
childrens.eq(++i % childrens.length).show();
|
||||
return
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -90,3 +90,20 @@ p.comment-body {
|
|||
.changeset{
|
||||
display: none;
|
||||
}
|
||||
|
||||
#conference-header{
|
||||
margin: auto;
|
||||
width: 304px;
|
||||
.conference-heading{
|
||||
float: left;
|
||||
width: 150px;
|
||||
}
|
||||
.conference-logo{
|
||||
float: left;
|
||||
width: 150px;
|
||||
img{
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,8 +173,25 @@ module Admin
|
|||
end
|
||||
end
|
||||
|
||||
def conference_info
|
||||
# To display sponsors in the conference wide information page
|
||||
@sponsors = @conference.sponsors
|
||||
@tweets = twitter_client.search_tweets(15, @conference.contact.social_tag)
|
||||
@current_event_schedules = @program.selected_schedule.event_schedules.current.group_by{|es| es.event.track.name}
|
||||
|
||||
respond_to do |format|
|
||||
format.html{render layout: 'conference_info'}
|
||||
format.js {render action: 'conference_info.js.haml'}
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# To create a twitter client
|
||||
def twitter_client
|
||||
@twitter_client ||= TwitterWrapper.new
|
||||
end
|
||||
|
||||
def conference_params
|
||||
params.require(:conference).permit(:title, :short_title, :description, :timezone,
|
||||
:start_date, :end_date, :rooms_attributes, :tracks_attributes,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ class EventSchedule < ActiveRecord::Base
|
|||
scope :confirmed, -> { joins(:event).where('state = ?', 'confirmed') }
|
||||
scope :canceled, -> { joins(:event).where('state = ?', 'canceled') }
|
||||
scope :withdrawn, -> { joins(:event).where('state = ?', 'withdrawn') }
|
||||
scope :current, -> { where('start_time <= ?', Time.current).select{ |es| es.end_time >= Time.current }}
|
||||
|
||||
delegate :guid, to: :room, prefix: true
|
||||
|
||||
|
|
|
|||
21
app/models/twitter_wrapper.rb
Normal file
21
app/models/twitter_wrapper.rb
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
class TwitterWrapper
|
||||
attr_accessor :client
|
||||
|
||||
def initialize
|
||||
@client = Twitter::REST::Client.new do |config|
|
||||
config.consumer_key = ENV['OSEM_TWITTER_CONSUMER_KEY']
|
||||
config.consumer_secret = ENV['OSEM_TWITTER_CONSUMER_SECRET']
|
||||
config.access_token = ENV['OSEM_TWITTER_ACCESS_TOKEN']
|
||||
config.access_token_secret = ENV['OSEM_TWITTER_ACCESS_TOKEN_SECRET']
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Fetches tweets from twitter api based on search_term and no_of_tweets
|
||||
#
|
||||
def search_tweets(no_of_tweets, search_term)
|
||||
@client.search(search_term, result_type: 'recent').take(no_of_tweets).collect
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
end
|
||||
13
app/views/admin/conferences/_conference_tweets.html.haml
Normal file
13
app/views/admin/conferences/_conference_tweets.html.haml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
.container
|
||||
.row
|
||||
.col-md-12.text-center
|
||||
%h2
|
||||
= "##{@conference.contact.social_tag} Tweets"
|
||||
%div#tweet-container
|
||||
- @tweets.each do |tweet|
|
||||
%div#tweet
|
||||
%blockquote.twitter-tweet
|
||||
%p{:lang => "en"}
|
||||
= tweet.text
|
||||
= link_to "— @" + tweet.user.name, "http://www.twitter.com/#{tweet.user.name}", target: "_blank"
|
||||
= link_to tweet.url, tweet.url.to_s
|
||||
14
app/views/admin/conferences/_current_events.html.haml
Normal file
14
app/views/admin/conferences/_current_events.html.haml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
.container
|
||||
.row.row-centered
|
||||
- @current_event_schedules.each do |track, event_schedules|
|
||||
.col-md-4.col-sm-4.col-centered
|
||||
%h2.text-center
|
||||
= track
|
||||
- event_schedules.each do |event_schedule|
|
||||
%h3.text-center
|
||||
= event_schedule.event.title
|
||||
%h4.text-center
|
||||
presented by
|
||||
= event_schedule.event.speaker_names
|
||||
in
|
||||
= event_schedule.event.room.name
|
||||
12
app/views/admin/conferences/_sponsors.html.haml
Normal file
12
app/views/admin/conferences/_sponsors.html.haml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
.container
|
||||
.row
|
||||
.col-md-12.text-center
|
||||
%h2 Sponsors
|
||||
%div#sponsor-container
|
||||
- @conference.sponsorship_levels.each do |sponsorship_level|
|
||||
-if sponsorship_level.sponsors.any?
|
||||
- sponsorship_level.sponsors.each_slice(3) do |slice|
|
||||
.row.row-centered#sponsor
|
||||
- slice.each do |sponsor|
|
||||
.col-md-4.col-sm-4.col-centered.col-top
|
||||
= image_tag get_logo(sponsor), class: "img-responsive img-sponsor img-sponsor-#{sponsorship_level.position}"
|
||||
23
app/views/admin/conferences/conference_info.html.haml
Normal file
23
app/views/admin/conferences/conference_info.html.haml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
.container
|
||||
- if @conference.present?
|
||||
.row
|
||||
.col-md-12.text-center
|
||||
%div#conference-header
|
||||
%div.conference-logo
|
||||
= image_tag(@conference.picture_url, class: 'img-responsive') if @conference.picture?
|
||||
%div.conference-heading
|
||||
%h1
|
||||
= @conference.title
|
||||
%span
|
||||
= @conference.short_title
|
||||
- if @conference.description.present?
|
||||
%h3
|
||||
= @conference.description
|
||||
- if @current_event_schedules.present?
|
||||
.row#current-events
|
||||
= render 'current_events'
|
||||
- if @conference.contact.social_tag.present? && @tweets.any?
|
||||
.row#conference-tweets
|
||||
= render 'conference_tweets'
|
||||
- if @sponsors.any?
|
||||
= render 'sponsors'
|
||||
4
app/views/admin/conferences/conference_info.js.haml
Normal file
4
app/views/admin/conferences/conference_info.js.haml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
$('#current-events').html("#{escape_javascript(render 'current_events', data: @current_events)}");
|
||||
$('#conference-tweets').html("#{escape_javascript(render 'conference_tweets', data: @tweets)}");
|
||||
$('#tweet-container').children().hide();
|
||||
$('#tweet-container').children().eq(0).show();
|
||||
|
|
@ -139,3 +139,9 @@
|
|||
= link_to(admin_conference_roles_path(@conference.short_title)) do
|
||||
%span.fa.fa-group
|
||||
Roles
|
||||
|
||||
- if can? :show, @conference
|
||||
%li{:class=> active_nav_li(conference_info_admin_conference_path(@conference.short_title))}
|
||||
= link_to(conference_info_admin_conference_path(@conference.short_title)) do
|
||||
%span.fa.fa-expand
|
||||
Conference Info
|
||||
|
|
|
|||
25
app/views/layouts/conference_info.html.haml
Normal file
25
app/views/layouts/conference_info.html.haml
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
%html{:xmlns => "http://www.w3.org/1999/html"}
|
||||
%head
|
||||
%meta{:charset => "utf-8"}
|
||||
%meta{:name => "viewport", :content => "width=device-width, initial-scale=1, maximum-scale=1"}
|
||||
%title= content_for?(:title) ? yield(:title) : (ENV['OSEM_NAME'] || 'OSEM')
|
||||
%meta{:content => "", :name => "description"}
|
||||
%meta{:content => "", :name => "author"}
|
||||
= stylesheet_link_tag "application", :media => "all"
|
||||
= javascript_include_tag "application"
|
||||
|
||||
= csrf_meta_tags
|
||||
:javascript
|
||||
window.liveSettings = {
|
||||
api_key: "#{ENV['OSEM_TRANSIFEX_APIKEY']}",
|
||||
picker: "bottom-right",
|
||||
detectlang: true,
|
||||
autocollect: true
|
||||
};
|
||||
= content_for(:script_head)
|
||||
= javascript_include_tag "//cdn.transifex.com/live.js"
|
||||
|
||||
= yield(:head)
|
||||
%body
|
||||
.container
|
||||
= yield
|
||||
|
|
@ -26,6 +26,9 @@ Osem::Application.routes.draw do
|
|||
end
|
||||
resources :comments, only: [:index]
|
||||
resources :conferences do
|
||||
member do
|
||||
get :conference_info
|
||||
end
|
||||
resource :contact, except: [:index, :new, :create, :show, :destroy]
|
||||
resources :schedules, only: [:index, :create, :show, :update, :destroy]
|
||||
resources :event_schedules, only: [:create, :update, :destroy]
|
||||
|
|
@ -103,7 +106,7 @@ Osem::Application.routes.draw do
|
|||
get '/revision_history/:id/revert_attribute' => 'versions#revert_attribute', as: 'revision_history_revert_attribute'
|
||||
end
|
||||
|
||||
resources :conferences, only: [:index, :show] do
|
||||
resources :conferences, only: [:index, :show ] do
|
||||
resource :program, only: [] do
|
||||
resources :proposals, except: :destroy do
|
||||
get 'commercials/render_commercial' => 'commercials#render_commercial'
|
||||
|
|
|
|||
|
|
@ -57,3 +57,9 @@ OSEM_SMTP_DOMAIN=""
|
|||
|
||||
# Enable the usage of the devise ichain plugin
|
||||
OSEM_ICHAIN_ENABLED=false
|
||||
|
||||
# To embed tweets about the conference in the conference wide screen
|
||||
OSEM_TWITTER_CONSUMER_KEY=""
|
||||
OSEM_TWITTER_CONSUMER_SECRET=""
|
||||
OSEM_TWITTER_ACCESS_TOKEN=""
|
||||
OSEM_TWITTER_ACCESS_TOKEN_SECRET=""
|
||||
|
|
|
|||
|
|
@ -20,5 +20,20 @@ FactoryGirl.define do
|
|||
event_schedule.schedule = program.selected_schedule
|
||||
end
|
||||
end
|
||||
factory :current_event_schedule do
|
||||
after(:build) do |event_schedule|
|
||||
event_schedule.start_time = DateTime.current
|
||||
end
|
||||
end
|
||||
factory :past_event_schedule do
|
||||
after(:build) do |event_schedule|
|
||||
event_schedule.start_time = (DateTime.current - 2.days).to_s
|
||||
end
|
||||
end
|
||||
factory :future_event_schedule do
|
||||
after(:build) do |event_schedule|
|
||||
event_schedule.start_time = (DateTime.current + 2.days).to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe EventSchedule do
|
||||
subject { create(:event_schedule) }
|
||||
let(:schedule) { create(:schedule) }
|
||||
let(:program) { create(:program, selected_schedule: schedule) }
|
||||
let!(:current_event_schedule) { create(:current_event_schedule, schedule: program.selected_schedule) }
|
||||
let!(:past_event_schedule) { create(:past_event_schedule) }
|
||||
let!(:future_event_schedule) { create(:future_event_schedule) }
|
||||
|
||||
describe 'association' do
|
||||
it { should belong_to(:schedule) }
|
||||
|
|
@ -18,4 +24,12 @@ describe EventSchedule do
|
|||
it { is_expected.to validate_presence_of(:room) }
|
||||
it { is_expected.to validate_presence_of(:start_time) }
|
||||
end
|
||||
|
||||
describe 'scope' do
|
||||
context 'current' do
|
||||
it 'returns only current events' do
|
||||
expect(program.selected_schedule.event_schedules.current).to match_array([current_event_schedule])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Schedule do
|
||||
|
||||
describe 'association' do
|
||||
it { should belong_to(:program) }
|
||||
it { should have_many(:event_schedules).dependent(:destroy) }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue