Merge branch 'master' of https://github.com/openSUSE/osem
This commit is contained in:
commit
65304fe7e7
40 changed files with 355 additions and 68 deletions
|
|
@ -22,7 +22,7 @@ before_script:
|
|||
- cp config/database.yml.travis config/database.yml
|
||||
- cp config/secrets.yml.example config/secrets.yml
|
||||
- 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:
|
||||
- "./travis_script.sh $TEST_SUITE"
|
||||
env:
|
||||
|
|
|
|||
7
Gemfile
7
Gemfile
|
|
@ -44,6 +44,9 @@ gem 'omniauth-openid'
|
|||
gem 'omniauth-google-oauth2'
|
||||
gem 'omniauth-github'
|
||||
|
||||
# Bot-filtering
|
||||
gem 'recaptcha', require: 'recaptcha/rails'
|
||||
|
||||
# as authorization framework
|
||||
gem 'cancancan'
|
||||
|
||||
|
|
@ -182,6 +185,10 @@ gem 'cloudinary'
|
|||
# for setting app configuration in the environment
|
||||
gem 'dotenv-rails'
|
||||
|
||||
# configurable toggles for functionality
|
||||
# https://github.com/mgsnova/feature
|
||||
gem 'feature'
|
||||
|
||||
# For countable.js
|
||||
gem "countable-rails", "~> 0.0.1"
|
||||
|
||||
|
|
|
|||
|
|
@ -179,6 +179,7 @@ GEM
|
|||
multipart-post (>= 1.2, < 3)
|
||||
fastimage (2.0.0)
|
||||
addressable (~> 2)
|
||||
feature (1.4.0)
|
||||
ffi (1.9.18)
|
||||
font-awesome-rails (4.7.0.2)
|
||||
railties (>= 3.2, < 5.2)
|
||||
|
|
@ -420,6 +421,8 @@ GEM
|
|||
loggability (~> 0.12)
|
||||
rdoc (~> 5.0)
|
||||
yajl-ruby (~> 1.3)
|
||||
recaptcha (4.6.2)
|
||||
json
|
||||
redcarpet (3.2.3)
|
||||
referer-parser (0.2.1)
|
||||
request_store (1.1.0)
|
||||
|
|
@ -552,7 +555,7 @@ GEM
|
|||
chronic (>= 0.6.3)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
yajl-ruby (1.3.0)
|
||||
yajl-ruby (1.3.1)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
|
@ -589,6 +592,7 @@ DEPENDENCIES
|
|||
dotenv-rails
|
||||
factory_girl_rails
|
||||
faker
|
||||
feature
|
||||
font-awesome-rails
|
||||
formtastic (~> 3.1.1)
|
||||
formtastic-bootstrap
|
||||
|
|
@ -636,6 +640,7 @@ DEPENDENCIES
|
|||
rails-i18n (~> 4.0.0)
|
||||
rails_12factor
|
||||
rdoc-generator-fivefish
|
||||
recaptcha
|
||||
redcarpet
|
||||
responders (~> 2.0)
|
||||
rolify
|
||||
|
|
@ -663,4 +668,4 @@ DEPENDENCIES
|
|||
whenever
|
||||
|
||||
BUNDLED WITH
|
||||
1.15.4
|
||||
1.16.0
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
@import "bootstrap/mixins";
|
||||
|
||||
html {
|
||||
position: relative;
|
||||
min-height: 100%;
|
||||
|
|
@ -104,3 +106,12 @@ p.comment-body {
|
|||
.qr-image{
|
||||
margin-left: 120px;
|
||||
}
|
||||
|
||||
.g-recaptcha {
|
||||
@include clearfix;
|
||||
padding-bottom: 12px;
|
||||
|
||||
div {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -193,6 +193,7 @@ module Admin
|
|||
def edit
|
||||
@conferences = Conference.all
|
||||
@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|
|
||||
format.html
|
||||
format.json { render json: @conference.to_json }
|
||||
|
|
|
|||
|
|
@ -4,4 +4,10 @@ class OrganizationsController < ApplicationController
|
|||
def index
|
||||
@organizations = Organization.all
|
||||
end
|
||||
|
||||
def conferences
|
||||
@current = @organization.conferences.upcoming.reorder(start_date: :asc)
|
||||
@antiquated = @organization.conferences.past
|
||||
render '/conferences/index'
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
class RegistrationsController < Devise::RegistrationsController
|
||||
before_action :configure_permitted_parameters, if: :devise_controller?
|
||||
prepend_before_action :check_captcha, only: [:create]
|
||||
|
||||
def edit
|
||||
@openids = Openid.where(user_id: current_user.id).order(:provider)
|
||||
|
|
@ -21,14 +21,34 @@ class RegistrationsController < Devise::RegistrationsController
|
|||
edit_user_registration_path(resource)
|
||||
end
|
||||
|
||||
def configure_permitted_parameters
|
||||
devise_parameter_sanitizer.permit(:account_update) do |u|
|
||||
u
|
||||
.permit(:email, :password, :password_confirmation, :current_password, :username, :email_public)
|
||||
end
|
||||
devise_parameter_sanitizer.permit(:sign_up) do |u|
|
||||
u
|
||||
.permit(:email, :password, :password_confirmation, :name, :username)
|
||||
private
|
||||
|
||||
def sign_up_params
|
||||
params.require(:user).permit(
|
||||
:email,
|
||||
:password,
|
||||
:password_confirmation,
|
||||
:name,
|
||||
:username
|
||||
)
|
||||
end
|
||||
|
||||
def account_update_params
|
||||
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
|
||||
|
|
|
|||
|
|
@ -163,6 +163,12 @@ module ApplicationHelper
|
|||
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
|
||||
# a conference object
|
||||
|
|
@ -171,4 +177,18 @@ module ApplicationHelper
|
|||
def hidden_if_conference_over(conference)
|
||||
'hidden' if Date.today > conference.end_date
|
||||
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
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class Ability
|
|||
|
||||
# Abilities for not signed in users (guests)
|
||||
def not_signed_in
|
||||
can [:index], Organization
|
||||
can [:index, :conferences], Organization
|
||||
can [:index], Conference
|
||||
can [:show], Conference do |conference|
|
||||
conference.splashpage && conference.splashpage.public == true
|
||||
|
|
|
|||
|
|
@ -204,11 +204,12 @@ class Event < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def speaker_names
|
||||
result = Set.new
|
||||
speakers.each do |speaker|
|
||||
result.add(speaker.name)
|
||||
end
|
||||
result.to_a.to_sentence
|
||||
speakers.map(&:name).join(', ')
|
||||
end
|
||||
|
||||
# Returns emails of all the speaker belongs to a particular event
|
||||
def speaker_emails
|
||||
speakers.map(&:email).join(', ')
|
||||
end
|
||||
|
||||
##
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ class Program < ActiveRecord::Base
|
|||
has_many :event_schedules, 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
|
||||
joins(:events).where(events: { state: :confirmed })
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,11 +22,11 @@
|
|||
= 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 :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 :end_hour, input_html: {size: 2, type: 'number', min: 1, max: 24}
|
||||
= 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}, hint: rescheduling_hint(@affected_event_count)
|
||||
= 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.inputs name: 'Booths' do
|
||||
= 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') +'.'
|
||||
= 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?' } }
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
'Start time',
|
||||
'Submitter',
|
||||
'Speaker',
|
||||
'Speaker Email',
|
||||
'Event Type',
|
||||
'Track',
|
||||
'Difficulty Level',
|
||||
|
|
@ -12,8 +13,15 @@
|
|||
= CSV.generate_line ['All Events']
|
||||
= CSV.generate_line headers
|
||||
- @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")} " : ''),
|
||||
event.submitter.name, event.speaker_names, event.event_type.title,
|
||||
= CSV.generate_line([event.id,
|
||||
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.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
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout:
|
|||
'Start time',
|
||||
'Submitter',
|
||||
'Speaker',
|
||||
'Speaker Email',
|
||||
'Event Type',
|
||||
'Track',
|
||||
'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.submitter.name
|
||||
row << event.speaker_names
|
||||
row << event.speaker_emails
|
||||
row << event.event_type.title
|
||||
row << (event.track.present? ? event.track.name : '')
|
||||
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
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,18 @@
|
|||
wb.add_worksheet(name: 'all events') do |sheet|
|
||||
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
|
||||
|
||||
@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.submitter.name
|
||||
row << event.speaker_names
|
||||
row << event.speaker_emails
|
||||
row << event.event_type.title
|
||||
row << (event.track.present? ? event.track.name : '')
|
||||
row << (event.difficulty_level.present? ? event.difficulty_level.title : '')
|
||||
row << (event.room.present? ? event.room.name : '')
|
||||
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
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
'Start time',
|
||||
'Submitter',
|
||||
'Speaker',
|
||||
'Speaker Email',
|
||||
'Event Type',
|
||||
'Track',
|
||||
'Difficulty Level',
|
||||
|
|
@ -16,8 +17,17 @@
|
|||
- all_comments = ''
|
||||
- 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"
|
||||
= CSV.generate_line([event.id, 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.event_type.title,
|
||||
= CSV.generate_line([event.id,
|
||||
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.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
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout:
|
|||
'Start time',
|
||||
'Submitter',
|
||||
'Speaker',
|
||||
'Speaker Email',
|
||||
'Event Type',
|
||||
'Track',
|
||||
'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.submitter.name
|
||||
row << event.speaker_names
|
||||
row << event.speaker_emails
|
||||
row << event.event_type.title
|
||||
row << (event.track.present? ? event.track.name : '')
|
||||
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.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.text "#{@conference.short_title} Comments", font_size: 25, align: :center
|
||||
pdf.move_down 20
|
||||
|
|
|
|||
|
|
@ -1,8 +1,20 @@
|
|||
wb.use_shared_strings = true
|
||||
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 })
|
||||
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
|
||||
|
||||
@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.submitter.name
|
||||
row << event.speaker_names
|
||||
row << event.speaker_emails
|
||||
row << event.event_type.title
|
||||
row << (event.track.present? ? event.track.name : '')
|
||||
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 << all_comments.strip
|
||||
sheet.add_row row, style: cell_style
|
||||
sheet.column_widths 10,15,35,13,18,18,28,12,15,15,15,10
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
'Start time',
|
||||
'Submitter',
|
||||
'Speaker',
|
||||
'Speaker Email',
|
||||
'Event Type',
|
||||
'Track',
|
||||
'Difficulty Level',
|
||||
|
|
@ -12,8 +13,15 @@
|
|||
= CSV.generate_line ["Confirmed Events"]
|
||||
= CSV.generate_line headers
|
||||
- @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")} " : ''),
|
||||
event.submitter.name, event.speaker_names, event.event_type.title,
|
||||
= CSV.generate_line([event.id,
|
||||
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.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
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout:
|
|||
'Start time',
|
||||
'Submitter',
|
||||
'Speaker',
|
||||
'Speaker Email',
|
||||
'Event Type',
|
||||
'Track',
|
||||
'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.submitter.name
|
||||
row << event.speaker_names
|
||||
row << event.speaker_emails
|
||||
row << event.event_type.title
|
||||
row << (event.track.present? ? event.track.name : '')
|
||||
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
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,18 @@
|
|||
wb.add_worksheet(name: 'confirmed events') do |sheet|
|
||||
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
|
||||
|
||||
@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.submitter.name
|
||||
row << event.speaker_names
|
||||
row << event.speaker_emails
|
||||
row << event.event_type.title
|
||||
row << (event.track.present? ? event.track.name : '')
|
||||
row << (event.difficulty_level.present? ? event.difficulty_level.title : '')
|
||||
row << (event.room.present? ? event.room.name : '')
|
||||
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
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
.page-header
|
||||
%h2 Upcoming Conferences
|
||||
- @current.each do |conference|
|
||||
= render partial: 'conference_details', locals: { conference: conference }
|
||||
= render '/conferences/conference_details', conference: conference
|
||||
-if @antiquated and @antiquated.any?
|
||||
.row
|
||||
.col-md-12
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
%i.fa.fa-chevron-down{ style: 'display: none' }
|
||||
#antiquated.collapse
|
||||
- @antiquated.each do |conference|
|
||||
= render partial: 'conference_details', locals: { conference: conference}
|
||||
= render '/conferences/conference_details', conference: conference
|
||||
|
||||
-content_for :script_body do
|
||||
:javascript
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
= f.input :name, input_html: { required: true }, hint: 'This is your real name'
|
||||
= f.input :password, input_html: { required: true }
|
||||
= f.input :password_confirmation, input_html: { required: true }
|
||||
- Feature.with(:recaptcha) do
|
||||
= recaptcha_tags
|
||||
%p.text-right
|
||||
= f.action :submit, as: :button, label: 'Sign Up', button_html: { class: 'btn btn-success' }
|
||||
|
||||
|
|
|
|||
|
|
@ -13,10 +13,8 @@
|
|||
%span.icon-bar
|
||||
%span.icon-bar
|
||||
%span.icon-bar
|
||||
- if conference.nil? || conference.new_record?
|
||||
= 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'
|
||||
= nav_root_link_for conference
|
||||
|
||||
.collapse.navbar-collapse#main-nav
|
||||
- if content_for :splash_nav
|
||||
%ul.nav.navbar-nav#splash-nav
|
||||
|
|
|
|||
|
|
@ -9,15 +9,16 @@
|
|||
= 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"
|
||||
- if ENV['OSEM_TRANSIFEX_APIKEY']
|
||||
:javascript
|
||||
window.liveSettings = {
|
||||
api_key: "#{ENV['OSEM_TRANSIFEX_APIKEY']}",
|
||||
picker: "bottom-right",
|
||||
detectlang: true,
|
||||
autocollect: true
|
||||
};
|
||||
= javascript_include_tag "//cdn.transifex.com/live.js"
|
||||
|
||||
= yield(:head)
|
||||
%body
|
||||
|
|
|
|||
|
|
@ -12,5 +12,7 @@
|
|||
.caption
|
||||
%h4
|
||||
= 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'
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@
|
|||
.col-md-8
|
||||
%h4
|
||||
= link_to speaker.name, user_path(speaker.id)
|
||||
= "(#{speaker.email})"
|
||||
- if speaker.email_public?
|
||||
= "(#{speaker.email})"
|
||||
- if speaker.affiliation?
|
||||
.text-muted
|
||||
from
|
||||
|
|
|
|||
42
bootstrap.sh
42
bootstrap.sh
|
|
@ -1,4 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
# set env os release variables
|
||||
. /etc/os-release
|
||||
|
||||
if [[ "$ID" == "opensuse" ]]; then
|
||||
|
||||
pushd /vagrant
|
||||
|
||||
echo -e "\ninstalling required software packages...\n"
|
||||
|
|
@ -14,6 +20,42 @@ echo 'install: --no-format-executable' >> /etc/gemrc
|
|||
echo -e "\ninstalling bundler...\n"
|
||||
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"
|
||||
su - vagrant -c "cd /vagrant/; bundle install --quiet"
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ Osem::Application.configure do
|
|||
# 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
|
||||
config.force_ssl = !!ENV['FORCE_SSL']
|
||||
|
||||
# See everything in the log (default is :info)
|
||||
config.log_level = :info
|
||||
|
|
|
|||
10
config/initializers/feature.rb
Normal file
10
config/initializers/feature.rb
Normal 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
|
||||
|
|
@ -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_attribute' => 'versions#revert_attribute', as: 'revision_history_revert_attribute'
|
||||
end
|
||||
resources :organizations, only: [:index]
|
||||
resources :organizations, only: [:index] do
|
||||
member do
|
||||
get :conferences
|
||||
end
|
||||
end
|
||||
resources :conferences, only: [:index, :show] do
|
||||
resources :booths do
|
||||
member do
|
||||
|
|
|
|||
|
|
@ -505,7 +505,7 @@ ActiveRecord::Schema.define(version: 20170924190528) do
|
|||
t.integer "user_id"
|
||||
t.integer "payment_id"
|
||||
t.integer "week"
|
||||
t.float "amount_paid"
|
||||
t.float "amount_paid", default: 0.0
|
||||
end
|
||||
|
||||
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.string "username"
|
||||
t.boolean "is_disabled", default: false
|
||||
t.string "token"
|
||||
end
|
||||
|
||||
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
|
||||
|
|
|
|||
|
|
@ -63,3 +63,10 @@ OSEM_SMTP_OPENSSL_VERIFY_MODE=""
|
|||
|
||||
# Enable the usage of the devise ichain plugin
|
||||
OSEM_ICHAIN_ENABLED=false
|
||||
|
||||
# enable this to force SSL
|
||||
# FORCE_SSL="1"
|
||||
|
||||
# ReCAPTCHA keys
|
||||
RECAPTCHA_SITE_KEY=""
|
||||
RECAPTCHA_SECRET_KEY=""
|
||||
|
|
|
|||
|
|
@ -2,6 +2,26 @@ require 'spec_helper'
|
|||
|
||||
describe OrganizationsController do
|
||||
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) }
|
||||
|
||||
describe 'GET #index' do
|
||||
|
|
@ -12,4 +32,27 @@ describe OrganizationsController do
|
|||
|
||||
it { expect(response).to render_template('index') }
|
||||
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
|
||||
|
|
|
|||
|
|
@ -48,4 +48,12 @@ feature Organization do
|
|||
|
||||
it_behaves_like 'successfully updates an organization'
|
||||
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
|
||||
|
|
|
|||
|
|
@ -62,14 +62,18 @@ feature Splashpage do
|
|||
end
|
||||
end
|
||||
|
||||
context 'public splashpage already created' do
|
||||
context 'navigation' do
|
||||
let!(:splashpage) { create(:splashpage, conference: conference, public: true)}
|
||||
|
||||
scenario 'should have organization name', feature: true, js: true do
|
||||
sign_in participant
|
||||
visit conference_path(conference.short_title)
|
||||
context 'multiple organizations' do
|
||||
let!(:additional_organization) { create(:organization) }
|
||||
|
||||
expect(page).to have_text(conference.organization.name)
|
||||
scenario 'should have organization name', feature: true, js: true do
|
||||
sign_in participant
|
||||
visit conference_path(conference.short_title)
|
||||
|
||||
expect(page).to have_text(conference.organization.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -58,5 +58,21 @@ describe ApplicationHelper, type: :helper do
|
|||
expect(concurrent_events(event).present?).to eq false
|
||||
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
|
||||
|
|
|
|||
|
|
@ -362,7 +362,7 @@ describe Event do
|
|||
new_event.submitter = submitter
|
||||
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
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ describe Program do
|
|||
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_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(:tracks) }
|
||||
it { is_expected.to accept_nested_attributes_for(:difficulty_levels) }
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@ require 'phantomjs'
|
|||
# makes it easier to control when PaperTrail is enabled during testing.
|
||||
require 'paper_trail/frameworks/rspec'
|
||||
|
||||
# Make htmlescape() available
|
||||
require 'erb'
|
||||
include ERB::Util
|
||||
|
||||
# Requires supporting ruby files with custom matchers and macros, etc, in
|
||||
# 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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue