This commit is contained in:
ViditChitkara 2017-11-20 22:41:02 +05:30
commit 65304fe7e7
40 changed files with 355 additions and 68 deletions

View file

@ -22,7 +22,7 @@ before_script:
- cp config/database.yml.travis config/database.yml - cp config/database.yml.travis config/database.yml
- cp config/secrets.yml.example config/secrets.yml - cp config/secrets.yml.example config/secrets.yml
- mysql -u root -e 'create database osem_test;' - mysql -u root -e 'create database osem_test;'
- RAILS_ENV=test bundle exec rake db:migrate --trace - RAILS_ENV=test bundle exec rake db:schema:load --trace
script: script:
- "./travis_script.sh $TEST_SUITE" - "./travis_script.sh $TEST_SUITE"
env: env:

View file

@ -44,6 +44,9 @@ gem 'omniauth-openid'
gem 'omniauth-google-oauth2' gem 'omniauth-google-oauth2'
gem 'omniauth-github' gem 'omniauth-github'
# Bot-filtering
gem 'recaptcha', require: 'recaptcha/rails'
# as authorization framework # as authorization framework
gem 'cancancan' gem 'cancancan'
@ -182,6 +185,10 @@ gem 'cloudinary'
# for setting app configuration in the environment # for setting app configuration in the environment
gem 'dotenv-rails' gem 'dotenv-rails'
# configurable toggles for functionality
# https://github.com/mgsnova/feature
gem 'feature'
# For countable.js # For countable.js
gem "countable-rails", "~> 0.0.1" gem "countable-rails", "~> 0.0.1"

View file

@ -179,6 +179,7 @@ GEM
multipart-post (>= 1.2, < 3) multipart-post (>= 1.2, < 3)
fastimage (2.0.0) fastimage (2.0.0)
addressable (~> 2) addressable (~> 2)
feature (1.4.0)
ffi (1.9.18) ffi (1.9.18)
font-awesome-rails (4.7.0.2) font-awesome-rails (4.7.0.2)
railties (>= 3.2, < 5.2) railties (>= 3.2, < 5.2)
@ -420,6 +421,8 @@ GEM
loggability (~> 0.12) loggability (~> 0.12)
rdoc (~> 5.0) rdoc (~> 5.0)
yajl-ruby (~> 1.3) yajl-ruby (~> 1.3)
recaptcha (4.6.2)
json
redcarpet (3.2.3) redcarpet (3.2.3)
referer-parser (0.2.1) referer-parser (0.2.1)
request_store (1.1.0) request_store (1.1.0)
@ -552,7 +555,7 @@ GEM
chronic (>= 0.6.3) chronic (>= 0.6.3)
xpath (2.0.0) xpath (2.0.0)
nokogiri (~> 1.3) nokogiri (~> 1.3)
yajl-ruby (1.3.0) yajl-ruby (1.3.1)
PLATFORMS PLATFORMS
ruby ruby
@ -589,6 +592,7 @@ DEPENDENCIES
dotenv-rails dotenv-rails
factory_girl_rails factory_girl_rails
faker faker
feature
font-awesome-rails font-awesome-rails
formtastic (~> 3.1.1) formtastic (~> 3.1.1)
formtastic-bootstrap formtastic-bootstrap
@ -636,6 +640,7 @@ DEPENDENCIES
rails-i18n (~> 4.0.0) rails-i18n (~> 4.0.0)
rails_12factor rails_12factor
rdoc-generator-fivefish rdoc-generator-fivefish
recaptcha
redcarpet redcarpet
responders (~> 2.0) responders (~> 2.0)
rolify rolify
@ -663,4 +668,4 @@ DEPENDENCIES
whenever whenever
BUNDLED WITH BUNDLED WITH
1.15.4 1.16.0

View file

@ -1,3 +1,5 @@
@import "bootstrap/mixins";
html { html {
position: relative; position: relative;
min-height: 100%; min-height: 100%;
@ -104,3 +106,12 @@ p.comment-body {
.qr-image{ .qr-image{
margin-left: 120px; margin-left: 120px;
} }
.g-recaptcha {
@include clearfix;
padding-bottom: 12px;
div {
float: right;
}
}

View file

@ -193,6 +193,7 @@ module Admin
def edit def edit
@conferences = Conference.all @conferences = Conference.all
@date_string = date_string(@conference.start_date, @conference.end_date) @date_string = date_string(@conference.start_date, @conference.end_date)
@affected_event_count = @conference.program.events.scheduled(@conference.program.selected_schedule_id).count
respond_to do |format| respond_to do |format|
format.html format.html
format.json { render json: @conference.to_json } format.json { render json: @conference.to_json }

View file

@ -4,4 +4,10 @@ class OrganizationsController < ApplicationController
def index def index
@organizations = Organization.all @organizations = Organization.all
end end
def conferences
@current = @organization.conferences.upcoming.reorder(start_date: :asc)
@antiquated = @organization.conferences.past
render '/conferences/index'
end
end end

View file

@ -1,5 +1,5 @@
class RegistrationsController < Devise::RegistrationsController class RegistrationsController < Devise::RegistrationsController
before_action :configure_permitted_parameters, if: :devise_controller? prepend_before_action :check_captcha, only: [:create]
def edit def edit
@openids = Openid.where(user_id: current_user.id).order(:provider) @openids = Openid.where(user_id: current_user.id).order(:provider)
@ -21,14 +21,34 @@ class RegistrationsController < Devise::RegistrationsController
edit_user_registration_path(resource) edit_user_registration_path(resource)
end end
def configure_permitted_parameters private
devise_parameter_sanitizer.permit(:account_update) do |u|
u def sign_up_params
.permit(:email, :password, :password_confirmation, :current_password, :username, :email_public) params.require(:user).permit(
:email,
:password,
:password_confirmation,
:name,
:username
)
end end
devise_parameter_sanitizer.permit(:sign_up) do |u|
u def account_update_params
.permit(:email, :password, :password_confirmation, :name, :username) params.require(:user).permit(
:email,
:password,
:password_confirmation,
:current_password,
:username,
:email_public
)
end
def check_captcha
unless Feature.inactive?(:recaptcha) || verify_recaptcha
self.resource = resource_class.new sign_up_params
resource.validate # Look for any other validation errors besides Recaptcha
respond_with_navigational(resource) { render :new }
end end
end end
end end

View file

@ -163,6 +163,12 @@ module ApplicationHelper
end end
end end
def rescheduling_hint(affected_event_count)
if affected_event_count > 0
"You have #{affected_event_count} scheduled #{'event'.pluralize(affected_event_count)}. Changing the conference hours will unschedule those scheduled outside the conference hours."
end
end
## ##
# ====Gets # ====Gets
# a conference object # a conference object
@ -171,4 +177,18 @@ module ApplicationHelper
def hidden_if_conference_over(conference) def hidden_if_conference_over(conference)
'hidden' if Date.today > conference.end_date 'hidden' if Date.today > conference.end_date
end end
def nav_root_link_for(conference)
link_text = (
conference.try(:organization).try(:name) ||
ENV['OSEM_NAME'] ||
'OSEM'
)
link_to(
link_text,
root_path,
class: 'navbar-brand',
title: 'Open Source Event Manager'
)
end
end end

View file

@ -15,7 +15,7 @@ class Ability
# Abilities for not signed in users (guests) # Abilities for not signed in users (guests)
def not_signed_in def not_signed_in
can [:index], Organization can [:index, :conferences], Organization
can [:index], Conference can [:index], Conference
can [:show], Conference do |conference| can [:show], Conference do |conference|
conference.splashpage && conference.splashpage.public == true conference.splashpage && conference.splashpage.public == true

View file

@ -204,11 +204,12 @@ class Event < ActiveRecord::Base
end end
def speaker_names def speaker_names
result = Set.new speakers.map(&:name).join(', ')
speakers.each do |speaker|
result.add(speaker.name)
end end
result.to_a.to_sentence
# Returns emails of all the speaker belongs to a particular event
def speaker_emails
speakers.map(&:email).join(', ')
end end
## ##

View file

@ -42,7 +42,8 @@ class Program < ActiveRecord::Base
has_many :event_schedules, through: :events has_many :event_schedules, through: :events
has_many :event_users, through: :events has_many :event_users, through: :events
has_many :speakers, -> { distinct }, through: :event_users, source: :user do has_many :program_events_speakers, -> {where(event_role: 'speaker')}, through: :events, source: :event_users
has_many :speakers, -> { distinct }, through: :program_events_speakers, source: :user do
def confirmed def confirmed
joins(:events).where(events: { state: :confirmed }) joins(:events).where(events: { state: :confirmed })
end end

View file

@ -22,11 +22,11 @@
= f.input :timezone, as: :time_zone, hint: 'The conference time zone' = f.input :timezone, as: :time_zone, hint: 'The conference time zone'
= f.input :start_date, as: :string, input_html: { id: 'conference-start-datepicker', readonly: 'readonly' } = f.input :start_date, as: :string, input_html: { id: 'conference-start-datepicker', readonly: 'readonly' }
= f.input :end_date, as: :string, input_html: { id: 'conference-end-datepicker', readonly: 'readonly' } = f.input :end_date, as: :string, input_html: { id: 'conference-end-datepicker', readonly: 'readonly' }
= f.input :start_hour, input_html: {size: 2, type: 'number', min: 0, max: 23} = f.input :start_hour, input_html: {size: 2, type: 'number', min: 0, max: 23}, hint: rescheduling_hint(@affected_event_count)
= f.input :end_hour, input_html: {size: 2, type: 'number', min: 1, max: 24} = f.input :end_hour, input_html: {size: 2, type: 'number', min: 1, max: 24}, hint: rescheduling_hint(@affected_event_count)
= f.inputs name: 'Registrations' do = f.inputs name: 'Registrations' do
= f.input :registration_limit, as: :number, in: 0..9999, hint: 'Limit the number of registrations to the conference (0 no limit). Please note that the registration limit doesn\'t apply to speakers of confirmed events (they will still be able to register even if it has been reached). You currently have ' + pluralize(@conference.registrations.count, 'registration') = f.input :registration_limit, as: :number, in: 0..9999, hint: 'Limit the number of registrations to the conference (0 no limit). Please note that the registration limit doesn\'t apply to speakers of confirmed events (they will still be able to register even if it has been reached). You currently have ' + pluralize(@conference.registrations.count, 'registration')
= f.inputs name: 'Booths' do = f.inputs name: 'Booths' do
= f.input :booth_limit, as: :number, in: 0..9999, = f.input :booth_limit, as: :number, in: 0..9999,
hint: 'Booth limit is the maximum number of booths that you can accept for this conference. By setting this number (0 no limit) you can be sure that you are not going to accept more booths than the conference can accommodate. You currently have ' + pluralize(@conference.booths.accepted.count, 'accepted booth') +'.' hint: 'Booth limit is the maximum number of booths that you can accept for this conference. By setting this number (0 no limit) you can be sure that you are not going to accept more booths than the conference can accommodate. You currently have ' + pluralize(@conference.booths.accepted.count, 'accepted booth') +'.'
= f.action :submit, as: :button, button_html: {class: 'btn btn-primary'} = f.action :submit, as: :button, button_html: { class: 'btn btn-primary', data: { confirm: 'Are you sure you want to proceed?' } }

View file

@ -4,6 +4,7 @@
'Start time', 'Start time',
'Submitter', 'Submitter',
'Speaker', 'Speaker',
'Speaker Email',
'Event Type', 'Event Type',
'Track', 'Track',
'Difficulty Level', 'Difficulty Level',
@ -12,8 +13,15 @@
= CSV.generate_line ['All Events'] = CSV.generate_line ['All Events']
= CSV.generate_line headers = CSV.generate_line headers
- @events.each do |event| - @events.each do |event|
= CSV.generate_line([event.id, event.title, event.abstract, (event.time.present? ? "#{event.time.strftime("%Y-%m-%d")} #{event.time.strftime("%I:%M%p")} " : ''), = CSV.generate_line([event.id,
event.submitter.name, event.speaker_names, event.event_type.title, event.title,
event.abstract,
(event.time.present? ? "#{event.time.strftime("%Y-%m-%d")}#{event.time.strftime("%I:%M%p")} " : ''),
event.submitter.name,
event.speaker_names,
event.speaker_emails,
event.event_type.title,
(event.track.present? ? event.track.name : ''), (event.track.present? ? event.track.name : ''),
(event.difficulty_level.present? ? event.difficulty_level.title : ''), (event.difficulty_level.present? ? event.difficulty_level.title : ''),
(event.room.present? ? event.room.name : ''), event.state]).html_safe (event.room.present? ? event.room.name : ''),
event.state]).html_safe

View file

@ -6,6 +6,7 @@ prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout:
'Start time', 'Start time',
'Submitter', 'Submitter',
'Speaker', 'Speaker',
'Speaker Email',
'Event Type', 'Event Type',
'Track', 'Track',
'Difficulty Level', 'Difficulty Level',
@ -21,6 +22,7 @@ prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout:
row << (event.time.present? ? "#{event.time.strftime("%Y-%m-%d")} #{event.time.strftime("%I:%M%p")} " : '') row << (event.time.present? ? "#{event.time.strftime("%Y-%m-%d")} #{event.time.strftime("%I:%M%p")} " : '')
row << event.submitter.name row << event.submitter.name
row << event.speaker_names row << event.speaker_names
row << event.speaker_emails
row << event.event_type.title row << event.event_type.title
row << (event.track.present? ? event.track.name : '') row << (event.track.present? ? event.track.name : '')
row << (event.difficulty_level.present? ? event.difficulty_level.title : '') row << (event.difficulty_level.present? ? event.difficulty_level.title : '')
@ -30,5 +32,5 @@ prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout:
end end
pdf.text "#{@conference.short_title} Events", font_size: 25, align: :center pdf.text "#{@conference.short_title} Events", font_size: 25, align: :center
pdf.table events_array, header: true, cell_style: {size: 8, border_width: 1} pdf.table events_array, header: true, cell_style: {size: 8, border_width: 1},column_widths: [40,60,90,50,70,65,85,50,55,50,60,45]
end end

View file

@ -1,6 +1,18 @@
wb.add_worksheet(name: 'all events') do |sheet| wb.add_worksheet(name: 'all events') do |sheet|
bold_style = wb.styles.add_style(b: true) bold_style = wb.styles.add_style(b: true)
row = ['Event ID', 'Title', 'Abstract', 'Start time', 'Submitter', 'Speaker', 'Event Type', 'Track', 'Difficulty Level', 'Room', 'State'] wrap_text = wb.styles.add_style alignment: {wrap_text: true}
row = ['Event ID',
'Title',
'Abstract',
'Start time',
'Submitter',
'Speaker',
'Speaker Email',
'Event Type',
'Track',
'Difficulty Level',
'Room',
'State']
sheet.add_row row, style: bold_style sheet.add_row row, style: bold_style
@events.each do |event| @events.each do |event|
@ -11,11 +23,13 @@ wb.add_worksheet(name: 'all events') do |sheet|
row << (event.time.present? ? "#{event.time.strftime("%Y-%m-%d")} #{event.time.strftime("%I:%M%p")} " : '') row << (event.time.present? ? "#{event.time.strftime("%Y-%m-%d")} #{event.time.strftime("%I:%M%p")} " : '')
row << event.submitter.name row << event.submitter.name
row << event.speaker_names row << event.speaker_names
row << event.speaker_emails
row << event.event_type.title row << event.event_type.title
row << (event.track.present? ? event.track.name : '') row << (event.track.present? ? event.track.name : '')
row << (event.difficulty_level.present? ? event.difficulty_level.title : '') row << (event.difficulty_level.present? ? event.difficulty_level.title : '')
row << (event.room.present? ? event.room.name : '') row << (event.room.present? ? event.room.name : '')
row << event.state row << event.state
sheet.add_row row sheet.add_row row , style: wrap_text
sheet.column_widths 10,15,35,13,18,18,28,12,15,15,15,10
end end
end end

View file

@ -4,6 +4,7 @@
'Start time', 'Start time',
'Submitter', 'Submitter',
'Speaker', 'Speaker',
'Speaker Email',
'Event Type', 'Event Type',
'Track', 'Track',
'Difficulty Level', 'Difficulty Level',
@ -16,8 +17,17 @@
- all_comments = '' - all_comments = ''
- event.root_comments.each do |comment| - event.root_comments.each do |comment|
- all_comments << "#{comment.created_at.strftime("%Y-%m-%d")} #{comment.created_at.strftime("%I:%M%p")} #{comment.user.name}: #{comment.body}\n" - all_comments << "#{comment.created_at.strftime("%Y-%m-%d")} #{comment.created_at.strftime("%I:%M%p")} #{comment.user.name}: #{comment.body}\n"
= CSV.generate_line([event.id, event.title, event.abstract, (event.time.present? ? "#{event.time.strftime("%Y-%m-%d")} #{event.time.strftime("%I:%M%p")} " : ''), = CSV.generate_line([event.id,
event.submitter.name, event.speaker_names, event.event_type.title, event.title,
event.abstract,
(event.time.present? ? "#{event.time.strftime("%Y-%m-%d")}#{event.time.strftime("%I:%M%p")} " : ''),
event.submitter.name,
event.speaker_names,
event.speaker_emails,
event.event_type.title,
(event.track.present? ? event.track.name : ''), (event.track.present? ? event.track.name : ''),
(event.difficulty_level.present? ? event.difficulty_level.title : ''), (event.difficulty_level.present? ? event.difficulty_level.title : ''),
(event.room.present? ? event.room.name : ''), event.state, all_comments]).html_safe (event.room.present? ? event.room.name : ''),
event.state,
all_comments]).html_safe

View file

@ -6,6 +6,7 @@ prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout:
'Start time', 'Start time',
'Submitter', 'Submitter',
'Speaker', 'Speaker',
'Speaker Email',
'Event Type', 'Event Type',
'Track', 'Track',
'Difficulty Level', 'Difficulty Level',
@ -21,6 +22,7 @@ prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout:
row << (event.time.present? ? "#{event.time.strftime("%Y-%m-%d")} #{event.time.strftime("%I:%M%p")} " : '') row << (event.time.present? ? "#{event.time.strftime("%Y-%m-%d")} #{event.time.strftime("%I:%M%p")} " : '')
row << event.submitter.name row << event.submitter.name
row << event.speaker_names row << event.speaker_names
row << event.speaker_emails
row << event.event_type.title row << event.event_type.title
row << (event.track.present? ? event.track.name : '') row << (event.track.present? ? event.track.name : '')
row << (event.difficulty_level.present? ? event.difficulty_level.title : '') row << (event.difficulty_level.present? ? event.difficulty_level.title : '')
@ -31,7 +33,7 @@ prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout:
pdf.text "#{@conference.short_title} Events", font_size: 25, align: :center pdf.text "#{@conference.short_title} Events", font_size: 25, align: :center
pdf.move_down 10 pdf.move_down 10
pdf.table events_array, header: true, cell_style: {size: 8, border_width: 1, position: :center} pdf.table events_array, header: true, cell_style: {size: 8, border_width: 1, position: :center},column_widths: [40,60,90,50,70,65,85,50,55,50,60,45]
pdf.start_new_page pdf.start_new_page
pdf.text "#{@conference.short_title} Comments", font_size: 25, align: :center pdf.text "#{@conference.short_title} Comments", font_size: 25, align: :center
pdf.move_down 20 pdf.move_down 20

View file

@ -2,7 +2,19 @@ wb.use_shared_strings = true
wb.add_worksheet(name: 'events with comments') do |sheet| wb.add_worksheet(name: 'events with comments') do |sheet|
bold_style = wb.styles.add_style(b: true) bold_style = wb.styles.add_style(b: true)
cell_style = wb.styles.add_style(alignment: { wrap_text: true, vertical: :top }) cell_style = wb.styles.add_style(alignment: { wrap_text: true, vertical: :top })
row = ['Event ID', 'Title', 'Abstract', 'Start time', 'Submitter', 'Speaker', 'Event Type', 'Track', 'Difficulty Level', 'Room', 'State', 'Comments'] row = ['Event ID',
'Title',
'Abstract',
'Start time',
'Submitter',
'Speaker',
'Speaker Email',
'Event Type',
'Track',
'Difficulty Level',
'Room',
'State',
'Comments']
sheet.add_row row, style: bold_style sheet.add_row row, style: bold_style
@events.each do |event| @events.each do |event|
@ -17,6 +29,7 @@ row = ['Event ID', 'Title', 'Abstract', 'Start time', 'Submitter', 'Speaker', 'E
row << (event.time.present? ? "#{event.time.strftime("%Y-%m-%d")} #{event.time.strftime("%I:%M%p")} " : '') row << (event.time.present? ? "#{event.time.strftime("%Y-%m-%d")} #{event.time.strftime("%I:%M%p")} " : '')
row << event.submitter.name row << event.submitter.name
row << event.speaker_names row << event.speaker_names
row << event.speaker_emails
row << event.event_type.title row << event.event_type.title
row << (event.track.present? ? event.track.name : '') row << (event.track.present? ? event.track.name : '')
row << (event.difficulty_level.present? ? event.difficulty_level.title : '') row << (event.difficulty_level.present? ? event.difficulty_level.title : '')
@ -24,5 +37,6 @@ row = ['Event ID', 'Title', 'Abstract', 'Start time', 'Submitter', 'Speaker', 'E
row << event.state row << event.state
row << all_comments.strip row << all_comments.strip
sheet.add_row row, style: cell_style sheet.add_row row, style: cell_style
sheet.column_widths 10,15,35,13,18,18,28,12,15,15,15,10
end end
end end

View file

@ -4,6 +4,7 @@
'Start time', 'Start time',
'Submitter', 'Submitter',
'Speaker', 'Speaker',
'Speaker Email',
'Event Type', 'Event Type',
'Track', 'Track',
'Difficulty Level', 'Difficulty Level',
@ -12,8 +13,15 @@
= CSV.generate_line ["Confirmed Events"] = CSV.generate_line ["Confirmed Events"]
= CSV.generate_line headers = CSV.generate_line headers
- @events.confirmed.each do |event| - @events.confirmed.each do |event|
= CSV.generate_line([event.id, event.title, event.abstract, (event.time.present? ? "#{event.time.strftime("%Y-%m-%d")} #{event.time.strftime("%I:%M%p")} " : ''), = CSV.generate_line([event.id,
event.submitter.name, event.speaker_names, event.event_type.title, event.title,
event.abstract,
(event.time.present? ? "#{event.time.strftime("%Y-%m-%d")} #{event.time.strftime("%I:%M%p")} " : ''),
event.submitter.name,
event.speaker_names,
event.speaker_emails,
event.event_type.title,
(event.track.present? ? event.track.name : ''), (event.track.present? ? event.track.name : ''),
(event.difficulty_level.present? ? event.difficulty_level.title : ''), (event.difficulty_level.present? ? event.difficulty_level.title : ''),
(event.room.present? ? event.room.name : ''), event.state]).html_safe (event.room.present? ? event.room.name : ''),
event.state]).html_safe

View file

@ -6,6 +6,7 @@ prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout:
'Start time', 'Start time',
'Submitter', 'Submitter',
'Speaker', 'Speaker',
'Speaker Email',
'Event Type', 'Event Type',
'Track', 'Track',
'Difficulty Level', 'Difficulty Level',
@ -21,6 +22,7 @@ prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout:
row << (event.time.present? ? "#{event.time.strftime("%Y-%m-%d")} #{event.time.strftime("%I:%M%p")} " : '') row << (event.time.present? ? "#{event.time.strftime("%Y-%m-%d")} #{event.time.strftime("%I:%M%p")} " : '')
row << event.submitter.name row << event.submitter.name
row << event.speaker_names row << event.speaker_names
row << event.speaker_emails
row << event.event_type.title row << event.event_type.title
row << (event.track.present? ? event.track.name : '') row << (event.track.present? ? event.track.name : '')
row << (event.difficulty_level.present? ? event.difficulty_level.title : '') row << (event.difficulty_level.present? ? event.difficulty_level.title : '')
@ -30,6 +32,6 @@ prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout:
end end
pdf.text "#{@conference.short_title} Confirmed Events", font_size: 25, align: :center pdf.text "#{@conference.short_title} Confirmed Events", font_size: 25, align: :center
pdf.table events_array, header: true, cell_style: {size: 8, border_width: 1} pdf.table events_array, header: true, cell_style: {size: 8, border_width: 1},column_widths: [40,60,90,50,70,65,85,50,55,50,60,45]
end end

View file

@ -1,6 +1,18 @@
wb.add_worksheet(name: 'confirmed events') do |sheet| wb.add_worksheet(name: 'confirmed events') do |sheet|
bold_style = wb.styles.add_style(b: true) bold_style = wb.styles.add_style(b: true)
row = ['Event ID', 'Title', 'Abstract', 'Start time', 'Submitter', 'Speaker', 'Event Type', 'Track', 'Difficulty Level', 'Room', 'State'] wrap_text = wb.styles.add_style alignment: {wrap_text: true}
row = ['Event ID',
'Title',
'Abstract',
'Start time',
'Submitter',
'Speaker',
'Speaker Email',
'Event Type',
'Track',
'Difficulty Level',
'Room',
'State']
sheet.add_row row, style: bold_style sheet.add_row row, style: bold_style
@events.confirmed.each do |event| @events.confirmed.each do |event|
@ -11,11 +23,13 @@ wb.add_worksheet(name: 'confirmed events') do |sheet|
row << (event.time.present? ? "#{event.time.strftime("%Y-%m-%d")} #{event.time.strftime("%I:%M%p")} " : '') row << (event.time.present? ? "#{event.time.strftime("%Y-%m-%d")} #{event.time.strftime("%I:%M%p")} " : '')
row << event.submitter.name row << event.submitter.name
row << event.speaker_names row << event.speaker_names
row << event.speaker_emails
row << event.event_type.title row << event.event_type.title
row << (event.track.present? ? event.track.name : '') row << (event.track.present? ? event.track.name : '')
row << (event.difficulty_level.present? ? event.difficulty_level.title : '') row << (event.difficulty_level.present? ? event.difficulty_level.title : '')
row << (event.room.present? ? event.room.name : '') row << (event.room.present? ? event.room.name : '')
row << event.state row << event.state
sheet.add_row row sheet.add_row row , style: wrap_text
sheet.column_widths 10,15,35,13,18,18,28,12,15,15,15,10
end end
end end

View file

@ -4,7 +4,7 @@
.page-header .page-header
%h2 Upcoming Conferences %h2 Upcoming Conferences
- @current.each do |conference| - @current.each do |conference|
= render partial: 'conference_details', locals: { conference: conference } = render '/conferences/conference_details', conference: conference
-if @antiquated and @antiquated.any? -if @antiquated and @antiquated.any?
.row .row
.col-md-12 .col-md-12
@ -17,7 +17,7 @@
%i.fa.fa-chevron-down{ style: 'display: none' } %i.fa.fa-chevron-down{ style: 'display: none' }
#antiquated.collapse #antiquated.collapse
- @antiquated.each do |conference| - @antiquated.each do |conference|
= render partial: 'conference_details', locals: { conference: conference} = render '/conferences/conference_details', conference: conference
-content_for :script_body do -content_for :script_body do
:javascript :javascript

View file

@ -12,6 +12,8 @@
= f.input :name, input_html: { required: true }, hint: 'This is your real name' = f.input :name, input_html: { required: true }, hint: 'This is your real name'
= f.input :password, input_html: { required: true } = f.input :password, input_html: { required: true }
= f.input :password_confirmation, input_html: { required: true } = f.input :password_confirmation, input_html: { required: true }
- Feature.with(:recaptcha) do
= recaptcha_tags
%p.text-right %p.text-right
= f.action :submit, as: :button, label: 'Sign Up', button_html: { class: 'btn btn-success' } = f.action :submit, as: :button, label: 'Sign Up', button_html: { class: 'btn btn-success' }

View file

@ -13,10 +13,8 @@
%span.icon-bar %span.icon-bar
%span.icon-bar %span.icon-bar
%span.icon-bar %span.icon-bar
- if conference.nil? || conference.new_record? = nav_root_link_for conference
= link_to (ENV['OSEM_NAME'] || 'OSEM'), root_path, class: 'navbar-brand', title: 'Open Source Event Manager'
- else
= link_to conference.organization.name, organizations_path, class: 'navbar-brand', title: 'Open Source Event Manager'
.collapse.navbar-collapse#main-nav .collapse.navbar-collapse#main-nav
- if content_for :splash_nav - if content_for :splash_nav
%ul.nav.navbar-nav#splash-nav %ul.nav.navbar-nav#splash-nav

View file

@ -9,6 +9,8 @@
= javascript_include_tag "application" = javascript_include_tag "application"
= csrf_meta_tags = csrf_meta_tags
= content_for(:script_head)
- if ENV['OSEM_TRANSIFEX_APIKEY']
:javascript :javascript
window.liveSettings = { window.liveSettings = {
api_key: "#{ENV['OSEM_TRANSIFEX_APIKEY']}", api_key: "#{ENV['OSEM_TRANSIFEX_APIKEY']}",
@ -16,7 +18,6 @@
detectlang: true, detectlang: true,
autocollect: true autocollect: true
}; };
= content_for(:script_head)
= javascript_include_tag "//cdn.transifex.com/live.js" = javascript_include_tag "//cdn.transifex.com/live.js"
= yield(:head) = yield(:head)

View file

@ -12,5 +12,7 @@
.caption .caption
%h4 %h4
= organization.name = organization.name
%button.btn.btn-success Conferences = link_to 'Conferences',
conferences_organization_path(organization),
class: 'btn btn-success'
/ = link_to 'Edit', edit_organization_path(organization), class: 'btn btn-mini btn-default' / = link_to 'Edit', edit_organization_path(organization), class: 'btn btn-mini btn-default'

View file

@ -36,6 +36,7 @@
.col-md-8 .col-md-8
%h4 %h4
= link_to speaker.name, user_path(speaker.id) = link_to speaker.name, user_path(speaker.id)
- if speaker.email_public?
= "(#{speaker.email})" = "(#{speaker.email})"
- if speaker.affiliation? - if speaker.affiliation?
.text-muted .text-muted

View file

@ -1,4 +1,10 @@
#!/bin/bash #!/bin/bash
# set env os release variables
. /etc/os-release
if [[ "$ID" == "opensuse" ]]; then
pushd /vagrant pushd /vagrant
echo -e "\ninstalling required software packages...\n" echo -e "\ninstalling required software packages...\n"
@ -14,6 +20,42 @@ echo 'install: --no-format-executable' >> /etc/gemrc
echo -e "\ninstalling bundler...\n" echo -e "\ninstalling bundler...\n"
gem.ruby2.4 install bundler gem.ruby2.4 install bundler
elif [[ "$ID" == "centos" || "$VERSION" == "7" ]]; then
_YELLOW='\033[1;33m' # yellow color
_LRED='\033[1;31m' # Light red color
_NO_COLOUR='\033[0m' # no color
printf "${_YELLOW}CEntOS-7 Setup${_NO_COLOUR}\n"
printf "${_YELLOW}installing ruby-2.4${_NO_COLOUR}\n"
yum install -q -y https://github.com/feedforce/ruby-rpm/releases/download/2.4.2/ruby-2.4.2-1.el7.centos.x86_64.rpm
if [[ ! "$?" -eq 0 ]]; then
printf "${_LRED}Error trying to install ruby-2.4${_NO_COLOUR}\n"
fi
printf "${_YELLOW}installing ruby-2.4 gems dependencies${_NO_COLOUR}\n"
gem install bundler
if [[ ! "$?" -eq 0 ]]; then
printf "${_LRED}Error trying to install ruby-2.4 bundler${_NO_COLOUR}\n"
fi
printf "${_YELLOW}installing nodejs repo${_NO_COLOUR}\n"
curl -sL https://rpm.nodesource.com/setup_9.x | bash - > /dev/null
printf "${_YELLOW}installing nodejs and devel tools${_NO_COLOUR}\n"
yum install -q -y git make gcc gcc-c++ libxml2-devel libxslt-devel nodejs screen mariadb mariadb-devel sqlite-devel ImageMagick bzip2
# for production: bundle install --without test development
printf "${_YELLOW}Opening firewall port: 3000${_NO_COLOUR}\n"
iptables -I INPUT -p tcp --dport 3000 -j ACCEPT
printf "${_YELLOW}installing phantomjs${_NO_COLOUR}\n"
curl -L --silent https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 -o /tmp/phantomjs-2.1.1-linux-x86_64.tar.bz2
tar jxvf /tmp/phantomjs-2.1.1-linux-x86_64.tar.bz2 -C /tmp/ phantomjs-2.1.1-linux-x86_64/bin/phantomjs
mv /tmp/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin
fi
echo -e "\ninstalling your bundle...\n" echo -e "\ninstalling your bundle...\n"
su - vagrant -c "cd /vagrant/; bundle install --quiet" su - vagrant -c "cd /vagrant/; bundle install --quiet"

View file

@ -33,7 +33,7 @@ Osem::Application.configure do
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx # 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. # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true config.force_ssl = !!ENV['FORCE_SSL']
# See everything in the log (default is :info) # See everything in the log (default is :info)
config.log_level = :info config.log_level = :info

View file

@ -0,0 +1,10 @@
require 'feature'
repo = Feature::Repository::SimpleRepository.new
# configure features here
unless(ENV['RECAPTCHA_SITE_KEY'].blank? || ENV['RECAPTCHA_SECRET_KEY'].blank?)
repo.add_active_feature :recaptcha
end
Feature.set_repository repo

View file

@ -149,7 +149,11 @@ Osem::Application.routes.draw do
get '/revision_history/:id/revert_object' => 'versions#revert_object', as: 'revision_history_revert_object' get '/revision_history/:id/revert_object' => 'versions#revert_object', as: 'revision_history_revert_object'
get '/revision_history/:id/revert_attribute' => 'versions#revert_attribute', as: 'revision_history_revert_attribute' get '/revision_history/:id/revert_attribute' => 'versions#revert_attribute', as: 'revision_history_revert_attribute'
end end
resources :organizations, only: [:index] resources :organizations, only: [:index] do
member do
get :conferences
end
end
resources :conferences, only: [:index, :show] do resources :conferences, only: [:index, :show] do
resources :booths do resources :booths do
member do member do

View file

@ -505,7 +505,7 @@ ActiveRecord::Schema.define(version: 20170924190528) do
t.integer "user_id" t.integer "user_id"
t.integer "payment_id" t.integer "payment_id"
t.integer "week" t.integer "week"
t.float "amount_paid" t.float "amount_paid", default: 0.0
end end
create_table "ticket_scannings", force: :cascade do |t| create_table "ticket_scannings", force: :cascade do |t|
@ -579,7 +579,6 @@ ActiveRecord::Schema.define(version: 20170924190528) do
t.boolean "is_admin", default: false t.boolean "is_admin", default: false
t.string "username" t.string "username"
t.boolean "is_disabled", default: false t.boolean "is_disabled", default: false
t.string "token"
end end
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true

View file

@ -63,3 +63,10 @@ OSEM_SMTP_OPENSSL_VERIFY_MODE=""
# Enable the usage of the devise ichain plugin # Enable the usage of the devise ichain plugin
OSEM_ICHAIN_ENABLED=false OSEM_ICHAIN_ENABLED=false
# enable this to force SSL
# FORCE_SSL="1"
# ReCAPTCHA keys
RECAPTCHA_SITE_KEY=""
RECAPTCHA_SECRET_KEY=""

View file

@ -2,6 +2,26 @@ require 'spec_helper'
describe OrganizationsController do describe OrganizationsController do
let!(:organization) { create(:organization) } let!(:organization) { create(:organization) }
let!(:conference) do
create(
:conference,
splashpage: create(:splashpage, public: true),
venue: create(:venue),
organization: organization
)
end
let!(:antiquated_conference) do
create(
:conference,
splashpage: create(:splashpage, public: true),
venue: create(:venue),
organization: organization,
start_date: 2.weeks.ago,
end_date: 1.week.ago
)
end
let!(:other_conference) { create(:conference) }
let!(:user) { create(:user) } let!(:user) { create(:user) }
describe 'GET #index' do describe 'GET #index' do
@ -12,4 +32,27 @@ describe OrganizationsController do
it { expect(response).to render_template('index') } it { expect(response).to render_template('index') }
end end
describe 'GET #conferences' do
before :each do
get :conferences, id: organization.id
end
it 'loads the organization' do
expect(assigns(:organization)).to eq organization
end
it 'includes organization conferences' do
expect(assigns(:current)).to include conference
end
it 'does not include conferences outside organization' do
expect(assigns(:current)).not_to include other_conference
expect(assigns(:antiquated)).not_to include other_conference
end
it 'includes antiquated organization conferences' do
expect(assigns(:antiquated)).to include antiquated_conference
end
end
end end

View file

@ -48,4 +48,12 @@ feature Organization do
it_behaves_like 'successfully updates an organization' it_behaves_like 'successfully updates an organization'
end end
context 'anonymously' do
scenario 'index should link to conferences list' do
visit organizations_path
expect(page).to have_link('Conferences', href: "/organizations/#{organization.id}/conferences")
end
end
end end

View file

@ -62,9 +62,12 @@ feature Splashpage do
end end
end end
context 'public splashpage already created' do context 'navigation' do
let!(:splashpage) { create(:splashpage, conference: conference, public: true)} let!(:splashpage) { create(:splashpage, conference: conference, public: true)}
context 'multiple organizations' do
let!(:additional_organization) { create(:organization) }
scenario 'should have organization name', feature: true, js: true do scenario 'should have organization name', feature: true, js: true do
sign_in participant sign_in participant
visit conference_path(conference.short_title) visit conference_path(conference.short_title)
@ -73,3 +76,4 @@ feature Splashpage do
end end
end end
end end
end

View file

@ -58,5 +58,21 @@ describe ApplicationHelper, type: :helper do
expect(concurrent_events(event).present?).to eq false expect(concurrent_events(event).present?).to eq false
end end
end end
describe 'navigation title link' do
it 'should default to OSEM' do
ENV.delete('OSEM_NAME')
expect(nav_root_link_for(nil)).to match 'OSEM'
end
it 'should use the environment variable' do
ENV['OSEM_NAME'] = Faker::Company.name + "'"
expect(nav_root_link_for(nil)).to match h(ENV['OSEM_NAME'])
end
it 'should use the conference organization name' do
expect(nav_root_link_for(conference)).to match h(conference.organization.name)
end
end
end end
end end

View file

@ -362,7 +362,7 @@ describe Event do
new_event.submitter = submitter new_event.submitter = submitter
new_event.speakers = [speaker1, speaker2] new_event.speakers = [speaker1, speaker2]
expect(new_event.speaker_names).to eq 'user speaker 1 and user speaker 2' expect(new_event.speaker_names).to eq 'user speaker 1, user speaker 2'
end end
end end
end end

View file

@ -15,8 +15,8 @@ describe Program do
it { is_expected.to have_many(:events).dependent(:destroy) } it { is_expected.to have_many(:events).dependent(:destroy) }
it { is_expected.to have_many(:event_schedules).through(:events) } it { is_expected.to have_many(:event_schedules).through(:events) }
it { is_expected.to have_many(:event_users).through(:events) } it { is_expected.to have_many(:event_users).through(:events) }
it { is_expected.to have_many(:speakers).through(:event_users).source(:user) } it { is_expected.to have_many(:program_events_speakers).through(:events).source(:event_users) }
it { is_expected.to have_many(:speakers).through(:program_events_speakers).source(:user) }
it { is_expected.to accept_nested_attributes_for(:event_types) } it { is_expected.to accept_nested_attributes_for(:event_types) }
it { is_expected.to accept_nested_attributes_for(:tracks) } it { is_expected.to accept_nested_attributes_for(:tracks) }
it { is_expected.to accept_nested_attributes_for(:difficulty_levels) } it { is_expected.to accept_nested_attributes_for(:difficulty_levels) }

View file

@ -26,6 +26,10 @@ require 'phantomjs'
# makes it easier to control when PaperTrail is enabled during testing. # makes it easier to control when PaperTrail is enabled during testing.
require 'paper_trail/frameworks/rspec' require 'paper_trail/frameworks/rspec'
# Make htmlescape() available
require 'erb'
include ERB::Util
# Requires supporting ruby files with custom matchers and macros, etc, in # Requires supporting ruby files with custom matchers and macros, etc, in
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
# run as spec files by default. This means that files in spec/support that end # run as spec files by default. This means that files in spec/support that end