Merge master, resolve schema conflicts
This commit is contained in:
commit
04154020a5
42 changed files with 757 additions and 131 deletions
81
.gitignore
vendored
81
.gitignore
vendored
|
|
@ -1,6 +1,27 @@
|
|||
# Global, for Macs
|
||||
*~
|
||||
|
||||
# Compiled Python files
|
||||
*.pyc
|
||||
|
||||
# Folder view configuration files
|
||||
.DS_Store
|
||||
Desktop.ini
|
||||
|
||||
# Thumbnail cache files
|
||||
._*
|
||||
Thumbs.db
|
||||
|
||||
# Files that might appear on external disks
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
|
||||
|
||||
# Legacy from before Feb 2021
|
||||
/db/test.sqlite3-journal
|
||||
config/application.rb
|
||||
config/config.yml
|
||||
config/local_env.yml
|
||||
config/secrets.yml
|
||||
/vendor/cache
|
||||
/vendor/cache-old
|
||||
|
|
@ -40,3 +61,63 @@ docker-compose.override.yml
|
|||
.buildconfig
|
||||
osem_development
|
||||
osem_test
|
||||
config/local_env.yml
|
||||
|
||||
# From GitHub, for Ruby
|
||||
# https://github.com/github/gitignore/blob/master/Ruby.gitignore
|
||||
*.gem
|
||||
*.rbc
|
||||
/.config
|
||||
/coverage/
|
||||
/InstalledFiles
|
||||
/pkg/
|
||||
/spec/reports/
|
||||
/spec/examples.txt
|
||||
/test/tmp/
|
||||
/test/version_tmp/
|
||||
/tmp/
|
||||
|
||||
# Used by dotenv library to load environment variables.
|
||||
# .env
|
||||
|
||||
# Ignore Byebug command history file.
|
||||
.byebug_history
|
||||
|
||||
## Specific to RubyMotion:
|
||||
.dat*
|
||||
.repl_history
|
||||
build/
|
||||
*.bridgesupport
|
||||
build-iPhoneOS/
|
||||
build-iPhoneSimulator/
|
||||
|
||||
## Specific to RubyMotion (use of CocoaPods):
|
||||
#
|
||||
# We recommend against adding the Pods directory to your .gitignore. However
|
||||
# you should judge for yourself, the pros and cons are mentioned at:
|
||||
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
||||
#
|
||||
# vendor/Pods/
|
||||
|
||||
## Documentation cache and generated files:
|
||||
/.yardoc/
|
||||
/_yardoc/
|
||||
/doc/
|
||||
/rdoc/
|
||||
|
||||
## Environment normalization:
|
||||
/.bundle/
|
||||
/vendor/bundle
|
||||
/lib/bundler/man/
|
||||
|
||||
# for a library or gem, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# Gemfile.lock
|
||||
# .ruby-version
|
||||
# .ruby-gemset
|
||||
|
||||
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
||||
.rvmrc
|
||||
|
||||
# Used by RuboCop. Remote config files pulled in from inherit_from directive.
|
||||
.rubocop-https?--*
|
||||
|
|
|
|||
22
Gemfile.lock
22
Gemfile.lock
|
|
@ -104,10 +104,13 @@ GEM
|
|||
rack-test (>= 0.6.3)
|
||||
regexp_parser (~> 1.5)
|
||||
xpath (~> 3.2)
|
||||
carrierwave (1.3.2)
|
||||
activemodel (>= 4.0.0)
|
||||
activesupport (>= 4.0.0)
|
||||
mime-types (>= 1.16)
|
||||
carrierwave (2.2.0)
|
||||
activemodel (>= 5.0.0)
|
||||
activesupport (>= 5.0.0)
|
||||
addressable (~> 2.6)
|
||||
image_processing (~> 1.1)
|
||||
mimemagic (>= 0.3.0)
|
||||
mini_mime (>= 0.1.3)
|
||||
ssrf_filter (~> 1.0)
|
||||
carrierwave-bombshelter (0.2.2)
|
||||
activesupport (>= 3.2.0)
|
||||
|
|
@ -115,7 +118,7 @@ GEM
|
|||
fastimage
|
||||
case_transform (0.2)
|
||||
activesupport
|
||||
chartkick (3.4.0)
|
||||
chartkick (3.4.2)
|
||||
childprocess (3.0.0)
|
||||
chronic (0.10.2)
|
||||
chunky_png (1.3.11)
|
||||
|
|
@ -251,6 +254,9 @@ GEM
|
|||
i18n (1.8.9)
|
||||
concurrent-ruby (~> 1.0)
|
||||
i18n_data (0.8.0)
|
||||
image_processing (1.12.1)
|
||||
mini_magick (>= 4.9.5, < 5)
|
||||
ruby-vips (>= 2.0.17, < 3)
|
||||
inversion (1.1.1)
|
||||
loggability (~> 0.12)
|
||||
io-like (0.3.0)
|
||||
|
|
@ -294,7 +300,7 @@ GEM
|
|||
method_source (0.8.2)
|
||||
mime-types (3.3.1)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2020.1104)
|
||||
mime-types-data (3.2021.0212)
|
||||
mimemagic (0.3.5)
|
||||
mina (1.2.3)
|
||||
open4 (~> 1.3.4)
|
||||
|
|
@ -302,7 +308,7 @@ GEM
|
|||
mini_magick (4.9.5)
|
||||
mini_mime (1.0.2)
|
||||
mini_portile2 (2.5.0)
|
||||
minitest (5.14.3)
|
||||
minitest (5.14.4)
|
||||
momentjs-rails (2.20.1)
|
||||
railties (>= 3.1)
|
||||
monetize (1.9.2)
|
||||
|
|
@ -540,6 +546,8 @@ GEM
|
|||
ruby-openid (2.9.2)
|
||||
ruby-progressbar (1.10.1)
|
||||
ruby-rc4 (0.1.5)
|
||||
ruby-vips (2.0.17)
|
||||
ffi (~> 1.9)
|
||||
ruby2_keywords (0.0.4)
|
||||
ruby_dep (1.5.0)
|
||||
ruby_parser (3.11.0)
|
||||
|
|
|
|||
22
README.md
22
README.md
|
|
@ -1,3 +1,21 @@
|
|||
### Spring 2021 Student Project
|
||||
[](https://travis-ci.com/CactusPuppy/snapcon)
|
||||
[](https://codeclimate.com/github/CactusPuppy/snapcon/maintainability)
|
||||
[](https://codecov.io/gh/CactusPuppy/snapcon)
|
||||
[](https://hakiri.io/github/CactusPuppy/snapcon/master)
|
||||
[](https://depfu.com/github/CactusPuppy/snapcon?project_id=22682)
|
||||
[](http://dashboard.bluejay.governify.io/dashboard/script/dashboardLoader.js?dashboardURL=https://reporter.bluejay.governify.io/api/v4/dashboards/tpa-CS169L-GH-CactusPuppy_snapcon/main)
|
||||
|
||||
<a href="https://heroku.com/deploy?template=https://github.com/openSUSE/osem/tree/v1.0">
|
||||
<img src="https://www.herokucdn.com/deploy/button.svg" height="20px" alt="Deploy">
|
||||
</a>
|
||||
|
||||
<a href="https://www.pivotaltracker.com/n/projects/2487653">
|
||||
<img src="https://www.pivotaltracker.com/marketing_assets/shared_home/tracker-4679313e699d9ba696371344953de96c81d207d967a43f121d353391c81c9ba7.svg" height="20px" alt="Pivotal Tracker">
|
||||
</a>
|
||||
|
||||
---
|
||||
|
||||
[](https://travis-ci.com/snap-cloud/snapcon)
|
||||
[](https://codeclimate.com/github/snap-cloud/snapcon/maintainability)
|
||||
[](https://codeclimate.com/github/snap-cloud/snapcon/test_coverage)
|
||||
|
|
@ -11,15 +29,19 @@
|
|||
# [Snap!Con](https://snapcon.org)
|
||||
forked from:
|
||||
## Open Source Event Manager - [osem.io](https://osem.io)
|
||||
|
||||

|
||||
|
||||
An event management tool tailored to Free and Open Source Software conferences.
|
||||
|
||||
## Installation
|
||||
|
||||
Please refer to our [installation guide](INSTALL.md).
|
||||
|
||||
## How to contribute to OSEM
|
||||
|
||||
Please refer to our [contributing guide](CONTRIBUTING.md).
|
||||
|
||||
## Contact
|
||||
|
||||
GitHub issues are the primary way for communicating about specific proposed changes to this project. If you have other questions feel free to subscribe to the [opensuse-web@opensuse.org](http://lists.opensuse.org/opensuse-web/) mailinglist, all OSEM contributors are on that list! Additionally you can use #osem channel on freenode IRC.
|
||||
|
|
|
|||
|
|
@ -149,15 +149,21 @@ function word_count(text, divId, maxcount) {
|
|||
|
||||
/* Wait for the DOM to be ready before attaching events to the elements */
|
||||
$( document ).ready(function() {
|
||||
/* Set the minimum and maximum proposal abstract word length */
|
||||
/* Set the minimum and maximum proposal abstract and submission text word length */
|
||||
$("#event_event_type_id").change(function () {
|
||||
var $selected = $("#event_event_type_id option:selected")
|
||||
var max = $selected.data("max-words");
|
||||
var min = $selected.data("min-words");
|
||||
|
||||
$("#abstract-maximum-word-count").text(max);
|
||||
$("#submission-maximum-word-count").text(max);
|
||||
$("#abstract-minimum-word-count").text(min);
|
||||
$("#submission-minimum-word-count").text(min);
|
||||
word_count($('#event_abstract').get(0), 'abstract-count', max);
|
||||
word_count($('#event_submission_text').get(0), 'submission-count', max);
|
||||
|
||||
// Set the placeholder text for the abstract
|
||||
$('#event_submission_text').attr("placeholder", $selected.data("help"));
|
||||
})
|
||||
.trigger('change');
|
||||
|
||||
|
|
@ -167,6 +173,13 @@ $( document ).ready(function() {
|
|||
var max = $selected.data("max-words");
|
||||
word_count(this, 'abstract-count', max);
|
||||
} );
|
||||
|
||||
/* Count the submission text length */
|
||||
$("#event_submission_text").bind('change keyup paste input', function() {
|
||||
var $selected = $("event_event_type_id option:selected")
|
||||
var max = $selected.data("max-words");
|
||||
word_count(this, 'submission-count', max);
|
||||
});
|
||||
});
|
||||
|
||||
/* Commodity function for modal windows */
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ module Admin
|
|||
def event_params
|
||||
params.require(:event).permit(
|
||||
# Set also in proposals controller
|
||||
:title, :subtitle, :event_type_id, :abstract, :description, :require_registration, :difficulty_level_id,
|
||||
:title, :subtitle, :event_type_id, :abstract, :submission_text, :description, :require_registration, :difficulty_level_id,
|
||||
# Set only in admin/events controller
|
||||
:track_id, :state, :language, :is_highlight, :max_attendees,
|
||||
# Not used anymore?
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class ApplicationController < ActionController::Base
|
|||
!request.xhr?) # don't store ajax calls
|
||||
session[:return_to] = request.fullpath
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def after_sign_in_path_for(_resource)
|
||||
if (can? :view, Conference) &&
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ class ProposalsController < ApplicationController
|
|||
|
||||
def event_params
|
||||
params.require(:event).permit(:event_type_id, :track_id, :difficulty_level_id,
|
||||
:title, :subtitle, :abstract, :description,
|
||||
:title, :subtitle, :abstract, :submission_text, :description,
|
||||
:require_registration, :max_attendees, :language,
|
||||
speaker_ids: [], volunteer_ids: []
|
||||
)
|
||||
|
|
|
|||
|
|
@ -31,7 +31,9 @@ class UsersController < ApplicationController
|
|||
end
|
||||
|
||||
# Somewhat of a hack: users/current/edit
|
||||
# rubocop:disable Naming/MemoizedInstanceVariableName
|
||||
def load_user
|
||||
@user ||= (params[:id] && params[:id] != 'current' && User.find(params[:id]) || current_user)
|
||||
end
|
||||
# rubocop:enable Naming/MemoizedInstanceVariableName
|
||||
end
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ module ApplicationHelper
|
|||
concurrent_events << other_event_schedule.event
|
||||
end
|
||||
end
|
||||
concurrent_events.sort_by { |event_schedule| event_schedule.room&.order }
|
||||
concurrent_events.sort_by { |schedule| schedule.room&.order }
|
||||
end
|
||||
|
||||
def speaker_links(event)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# TODO: Split this module into smaller modules
|
||||
# rubocop:disable Metrics/ModuleLength
|
||||
module EventsHelper
|
||||
##
|
||||
# Includes functions related to events
|
||||
|
|
@ -193,7 +195,7 @@ module EventsHelper
|
|||
end
|
||||
end
|
||||
|
||||
def calendar_timestamp(timestamp, timezone)
|
||||
def calendar_timestamp(timestamp, _timezone)
|
||||
timestamp = timestamp.in_time_zone('GMT')
|
||||
timestamp -= timestamp.utc_offset
|
||||
timestamp.strftime('%Y%m%dT%H%M%S')
|
||||
|
|
@ -256,3 +258,4 @@ module EventsHelper
|
|||
end
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/ModuleLength
|
||||
|
|
|
|||
|
|
@ -1,17 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
SNAPCON_BCC_ADDRESS = 'messages@snap.berkeley.edu'
|
||||
EMAIL_TEMPLATE = 'email_template'
|
||||
YTLF_TICKET_ID = 50
|
||||
|
||||
class Mailbot < ActionMailer::Base
|
||||
def registration_mail(conference, user)
|
||||
mail(to: user.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.registration_subject,
|
||||
body: conference.email_settings.generate_email_on_conf_updates(conference,
|
||||
user,
|
||||
conference.email_settings.registration_body))
|
||||
@email_body = conference.email_settings.generate_email_on_conf_updates(conference, user, conference.email_settings.registration_body)
|
||||
@logo = conference.picture.thumb.url
|
||||
|
||||
mail(to: user.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.registration_subject,
|
||||
template_name: EMAIL_TEMPLATE)
|
||||
end
|
||||
|
||||
def ticket_confirmation_mail(ticket_purchase)
|
||||
|
|
@ -39,108 +41,128 @@ class Mailbot < ActionMailer::Base
|
|||
def acceptance_mail(event)
|
||||
conference = event.program.conference
|
||||
|
||||
mail(to: event.submitter.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.accepted_subject,
|
||||
body: conference.email_settings.generate_event_mail(event, conference.email_settings.accepted_body))
|
||||
@logo = conference.picture.thumb.url
|
||||
@email_body = conference.email_settings.generate_event_mail(event, conference.email_settings.accepted_body)
|
||||
|
||||
mail(to: event.submitter.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.accepted_subject,
|
||||
template_name: EMAIL_TEMPLATE)
|
||||
end
|
||||
|
||||
def submitted_proposal_mail(event)
|
||||
conference = event.program.conference
|
||||
|
||||
mail(to: event.submitter.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.submitted_proposal_subject,
|
||||
body: conference.email_settings.generate_event_mail(event, conference.email_settings.submitted_proposal_body))
|
||||
@logo = conference.picture.thumb.url
|
||||
@email_body = conference.email_settings.generate_event_mail(event, conference.email_settings.submitted_proposal_body)
|
||||
|
||||
mail(to: event.submitter.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.submitted_proposal_subject,
|
||||
template_name: EMAIL_TEMPLATE)
|
||||
end
|
||||
|
||||
def rejection_mail(event)
|
||||
conference = event.program.conference
|
||||
|
||||
mail(to: event.submitter.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.rejected_subject,
|
||||
body: conference.email_settings.generate_event_mail(event, conference.email_settings.rejected_body))
|
||||
@logo = conference.picture.thumb.url
|
||||
@email_body = conference.email_settings.generate_event_mail(event, conference.email_settings.rejected_body)
|
||||
|
||||
mail(to: event.submitter.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.rejected_subject,
|
||||
template_name: EMAIL_TEMPLATE)
|
||||
end
|
||||
|
||||
def confirm_reminder_mail(event)
|
||||
conference = event.program.conference
|
||||
|
||||
mail(to: event.submitter.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.confirmed_without_registration_subject,
|
||||
body: conference.email_settings.generate_event_mail(event,
|
||||
conference.email_settings.confirmed_without_registration_body))
|
||||
@logo = conference.picture.thumb.url
|
||||
@email_body = conference.email_settings.generate_event_mail(event, conference.email_settings.confirmed_without_registration_body)
|
||||
|
||||
mail(to: event.submitter.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.confirmed_without_registration_subject,
|
||||
template_name: EMAIL_TEMPLATE)
|
||||
end
|
||||
|
||||
def conference_date_update_mail(conference, user)
|
||||
mail(to: user.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.conference_dates_updated_subject,
|
||||
body: conference.email_settings.generate_email_on_conf_updates(conference,
|
||||
user,
|
||||
conference.email_settings.conference_dates_updated_body))
|
||||
@logo = conference.picture.thumb.url
|
||||
@email_body = conference.email_settings.generate_email_on_conf_updates(conference, user, conference.email_settings.conference_dates_updated_body)
|
||||
|
||||
mail(to: user.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.conference_dates_updated_subject,
|
||||
template_name: EMAIL_TEMPLATE)
|
||||
end
|
||||
|
||||
def conference_registration_date_update_mail(conference, user)
|
||||
mail(to: user.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.conference_registration_dates_updated_subject,
|
||||
body: conference.email_settings.generate_email_on_conf_updates(conference,
|
||||
user,
|
||||
conference.email_settings.conference_registration_dates_updated_body))
|
||||
@logo = conference.picture.thumb.url
|
||||
@email_body = conference.email_settings.generate_email_on_conf_updates(conference, user, conference.email_settings.conference_registration_dates_updated_body)
|
||||
|
||||
mail(to: user.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.conference_registration_dates_updated_subject,
|
||||
template_name: EMAIL_TEMPLATE)
|
||||
end
|
||||
|
||||
def conference_venue_update_mail(conference, user)
|
||||
mail(to: user.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.venue_updated_subject,
|
||||
body: conference.email_settings.generate_email_on_conf_updates(conference,
|
||||
user,
|
||||
conference.email_settings.venue_updated_body))
|
||||
@logo = conference.picture.thumb.url
|
||||
@email_body = conference.email_settings.generate_email_on_conf_updates(conference, user, conference.email_settings.venue_updated_body)
|
||||
|
||||
mail(to: user.email,
|
||||
bcc: SNAPCON_BCC_ADDRESS,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.venue_updated_subject,
|
||||
template_name: EMAIL_TEMPLATE)
|
||||
end
|
||||
|
||||
def conference_schedule_update_mail(conference, user)
|
||||
mail(to: user.email,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.program_schedule_public_subject,
|
||||
body: conference.email_settings.generate_email_on_conf_updates(conference,
|
||||
user,
|
||||
conference.email_settings.program_schedule_public_body))
|
||||
@logo = conference.picture.thumb.url
|
||||
@email_body = conference.email_settings.generate_email_on_conf_updates(conference, user, conference.email_settings.program_schedule_public_body)
|
||||
|
||||
mail(to: user.email,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.program_schedule_public_subject,
|
||||
template_name: EMAIL_TEMPLATE)
|
||||
end
|
||||
|
||||
def conference_cfp_update_mail(conference, user)
|
||||
mail(to: user.email,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.cfp_dates_updated_subject,
|
||||
body: conference.email_settings.generate_email_on_conf_updates(conference,
|
||||
user,
|
||||
conference.email_settings.cfp_dates_updated_body))
|
||||
@logo = conference.picture.thumb.url
|
||||
@email_body = conference.email_settings.generate_email_on_conf_updates(conference, user, conference.email_settings.cfp_dates_updated_body)
|
||||
|
||||
mail(to: user.email,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.cfp_dates_updated_subject,
|
||||
template_name: EMAIL_TEMPLATE)
|
||||
end
|
||||
|
||||
def conference_booths_acceptance_mail(booth)
|
||||
conference = booth.conference
|
||||
@logo = conference.picture.thumb.url
|
||||
@email_body = conference.email_settings.generate_booth_mail(booth, conference.email_settings.booths_acceptance_body)
|
||||
|
||||
mail(to: booth.submitter.email,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.booths_acceptance_subject,
|
||||
body: conference.email_settings.generate_booth_mail(booth, conference.email_settings.booths_acceptance_body))
|
||||
mail(to: booth.submitter.email,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.booths_acceptance_subject,
|
||||
template_name: EMAIL_TEMPLATE)
|
||||
end
|
||||
|
||||
def conference_booths_rejection_mail(booth)
|
||||
conference = booth.conference
|
||||
@logo = conference.picture.thumb.url
|
||||
@email_body = conference.email_settings.generate_booth_mail(booth, conference.email_settings.booths_rejection_body)
|
||||
|
||||
mail(to: booth.submitter.email,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.booths_rejection_subject,
|
||||
body: conference.email_settings.generate_booth_mail(booth, conference.email_settings.booths_rejection_body))
|
||||
mail(to: booth.submitter.email,
|
||||
from: conference.contact.email,
|
||||
subject: conference.email_settings.booths_rejection_subject,
|
||||
template_name: EMAIL_TEMPLATE)
|
||||
end
|
||||
|
||||
def event_comment_mail(comment, user)
|
||||
|
|
|
|||
|
|
@ -68,6 +68,8 @@ class Ability
|
|||
end
|
||||
|
||||
# Abilities for signed in users
|
||||
# TODO: Refactor into multiple functions
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
def signed_in(user)
|
||||
# Abilities from not_signed_in user are also inherited
|
||||
not_signed_in
|
||||
|
|
@ -140,6 +142,7 @@ class Ability
|
|||
user == track.submitter && !(track.accepted? || track.confirmed?)
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
|
||||
# Abilities for users with roles wandering around in non-admin views.
|
||||
def common_abilities_for_admins(user)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class Commercial < ApplicationRecord
|
|||
begin
|
||||
resource = OEmbed::Providers.get(url, maxwidth: 560, maxheight: 315)
|
||||
{ html: resource.html.html_safe }
|
||||
rescue StandardError => exception
|
||||
rescue StandardError
|
||||
{ html: iframe_fallback(url) }
|
||||
# { error: exception.message }
|
||||
end
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#
|
||||
# index_conferences_on_organization_id (organization_id)
|
||||
#
|
||||
# rubocop:disable Metrics/ClassLength
|
||||
class Conference < ApplicationRecord
|
||||
include RevisionCount
|
||||
require 'uri'
|
||||
|
|
@ -1234,3 +1235,4 @@ class Conference < ApplicationRecord
|
|||
]
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/ClassLength
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
# require_registration :boolean
|
||||
# start_time :datetime
|
||||
# state :string default("new"), not null
|
||||
# submission_text :text
|
||||
# subtitle :string
|
||||
# title :string not null
|
||||
# week :integer
|
||||
|
|
@ -74,6 +75,7 @@ class Event < ApplicationRecord
|
|||
before_create :generate_guid
|
||||
|
||||
validate :abstract_limit
|
||||
validate :submission_limit
|
||||
validate :before_end_of_conference, on: :create
|
||||
validates :title, presence: true
|
||||
validates :abstract, presence: true
|
||||
|
|
@ -218,6 +220,10 @@ class Event < ApplicationRecord
|
|||
abstract.to_s.split.size
|
||||
end
|
||||
|
||||
def submission_word_count
|
||||
submission_text.to_s.split.size
|
||||
end
|
||||
|
||||
def self.get_state_color(state)
|
||||
COLORS[state.to_sym] || '#00FFFF' # azure
|
||||
end
|
||||
|
|
@ -342,16 +348,28 @@ class Event < ApplicationRecord
|
|||
errors.add(:max_attendees, "cannot be more than the room's capacity (#{room.size})") if max_attendees && (max_attendees > room.size)
|
||||
end
|
||||
|
||||
def abstract_limit
|
||||
# If we don't have an event type, there is no need to count anything
|
||||
return unless event_type && abstract
|
||||
def word_limit(field)
|
||||
# If we don't have an event type or the requested field, don't count
|
||||
return unless event_type && respond_to?(field) && self[field]
|
||||
|
||||
len = abstract.split.size
|
||||
len = self[field].split.size
|
||||
# TODO: Use different limits for different text fields
|
||||
# Uncomment the two lines below this when the separate word limits are implemented.
|
||||
# max_words = event_type["maximum_#{field}_length"]
|
||||
# min_words = event_type["minimum_#{field}_length"]
|
||||
max_words = event_type.maximum_abstract_length
|
||||
min_words = event_type.minimum_abstract_length
|
||||
|
||||
errors.add(:abstract, "cannot have less than #{min_words} words") if len < min_words
|
||||
errors.add(:abstract, "cannot have more than #{max_words} words") if len > max_words
|
||||
errors.add(field.to_sym, "cannot have less than #{min_words} words") if len < min_words
|
||||
errors.add(field.to_sym, "cannot have more than #{max_words} words") if len > max_words
|
||||
end
|
||||
|
||||
def abstract_limit
|
||||
word_limit(:abstract)
|
||||
end
|
||||
|
||||
def submission_limit
|
||||
word_limit(:submission_text)
|
||||
end
|
||||
|
||||
# TODO: create a module to be mixed into model to perform same operation
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ class User < ApplicationRecord
|
|||
# TODO: Use a real authorization in the right place....
|
||||
def manages_volunteers?(conference)
|
||||
organizer_roles = get_roles['organizer']
|
||||
organizer_roles&.include?(conference.short_title) # TODO or Volunteer Coorinator.
|
||||
organizer_roles&.include?(conference.short_title) # TODO: or Volunteer Coorinator.
|
||||
end
|
||||
|
||||
def registered
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
# require_registration :boolean
|
||||
# start_time :datetime
|
||||
# state :string default("new"), not null
|
||||
# submission_text :text
|
||||
# subtitle :string
|
||||
# title :string not null
|
||||
# week :integer
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
%small
|
||||
= @event.subtitle
|
||||
.btn-group.pull-right
|
||||
- if @event.public
|
||||
= link_to 'Preview', conference_program_proposal_path(@conference.short_title, @event.id), class: 'btn btn-mini btn-primary'
|
||||
= link_to 'Registrations', registrations_admin_conference_program_event_path(@conference.short_title, @event), class: 'btn btn-success'
|
||||
= link_to 'Edit', edit_admin_conference_program_event_path(@conference.short_title, @event), class: 'btn btn-mini btn-primary'
|
||||
|
||||
|
|
@ -111,6 +113,10 @@
|
|||
%td
|
||||
%b Abstract
|
||||
%td= markdown(@event.abstract)
|
||||
%tr
|
||||
%td
|
||||
%b Submission Description
|
||||
%td= markdown(@event.submission_text)
|
||||
%tr
|
||||
%td
|
||||
%b Requirements
|
||||
|
|
|
|||
|
|
@ -1,10 +1,83 @@
|
|||
Dear <%= @user.name %>,
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<!-- CSS -->
|
||||
<link rel="stylesheet" href="main.css">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:100,200,300,400,500,600,700,800" rel="stylesheet">
|
||||
<style>
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
User <%= @comment.user.name %> posted a new comment for event <%= @event.title %> of <%= @conference.short_title %> .
|
||||
body {
|
||||
background: #fff;
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, 0.06);
|
||||
color: #000;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
"<%= @comment.body %>"
|
||||
h1,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-weight: 400;
|
||||
line-height: 1.3;
|
||||
}
|
||||
p {
|
||||
color: #0B3559;
|
||||
font-weight: 400;
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
To reply to this comment, please go to <%= h(admin_conference_program_event_url(@conference.short_title, @event, only_path: false)) %>
|
||||
#border {
|
||||
background-color: #0B3559;
|
||||
padding: 25px;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
Best wishes,
|
||||
<%= @conference.title %> Team
|
||||
#content {
|
||||
background-color: #fff;
|
||||
padding: 100px;
|
||||
color: #0B3559;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Page Title -->
|
||||
<title>Email</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="border">
|
||||
<div class="row">
|
||||
<!-- Uncomment below to get logo -->
|
||||
<div class="col-md-2">
|
||||
</div>
|
||||
<div class="col-md-10"><h1></h1></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<span style="white-space: pre-line">
|
||||
Dear <%= @user.name %>,
|
||||
|
||||
User <%= @comment.user.name %> posted a new comment for event <%= @event.title %> of <%= @conference.short_title %> .
|
||||
|
||||
"<%= @comment.body %>"
|
||||
|
||||
To reply to this comment, please go to <%= h(admin_conference_program_event_url(@conference.short_title, @event, only_path: false)) %>
|
||||
|
||||
Best wishes,
|
||||
<%= @conference.title %> Team
|
||||
</span>
|
||||
</div>
|
||||
<div id="border">
|
||||
<h1></h1>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
77
app/views/mailbot/email_template.erb
Normal file
77
app/views/mailbot/email_template.erb
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<!-- CSS -->
|
||||
<link rel="stylesheet" href="main.css">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:100,200,300,400,500,600,700,800" rel="stylesheet">
|
||||
<style>
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #fff;
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, 0.06);
|
||||
color: #000;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
h1,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-weight: 400;
|
||||
line-height: 1.3;
|
||||
}
|
||||
p {
|
||||
color: #0B3559;
|
||||
font-weight: 400;
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
#border {
|
||||
background-color: #0B3559;
|
||||
padding: 25px;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
#content {
|
||||
background-color: #fff;
|
||||
padding: 100px;
|
||||
color: #0B3559;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Page Title -->
|
||||
<title>Email</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="border">
|
||||
<div class="row">
|
||||
<!-- Uncomment below to get logo -->
|
||||
<div class="col-md-2">
|
||||
<% if !@logo.nil? %>
|
||||
<%= image_tag(@logo, style: "display:block") %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="col-md-10"><h1></h1></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<span style="white-space: pre-line">
|
||||
<%= @email_body %>
|
||||
</span>
|
||||
</div>
|
||||
<div id="border">
|
||||
<h1></h1>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,8 +1,81 @@
|
|||
Dear <%= @user.name %>,
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<!-- CSS -->
|
||||
<link rel="stylesheet" href="main.css">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:100,200,300,400,500,600,700,800" rel="stylesheet">
|
||||
<style>
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
Thanks! You have successfully booked <%= @ticket_purchase.quantity %> <%= @ticket_purchase.ticket.title %> ticket(s) for the event <%= @conference.title %>. Your transaction id is <%= @ticket_purchase.id %>.
|
||||
body {
|
||||
background: #fff;
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, 0.06);
|
||||
color: #000;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
Please, find the ticket(s) pdf attached.
|
||||
h1,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-weight: 400;
|
||||
line-height: 1.3;
|
||||
}
|
||||
p {
|
||||
color: #0B3559;
|
||||
font-weight: 400;
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
Best wishes,
|
||||
<%= @conference.title %> Team
|
||||
#border {
|
||||
background-color: #0B3559;
|
||||
padding: 25px;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
#content {
|
||||
background-color: #fff;
|
||||
padding: 100px;
|
||||
color: #0B3559;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Page Title -->
|
||||
<title>Email</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="border">
|
||||
<div class="row">
|
||||
<!-- Uncomment below to get logo -->
|
||||
<div class="col-md-2">
|
||||
</div>
|
||||
<div class="col-md-10"><h1></h1></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<span style="white-space: pre-line">
|
||||
Dear <%= @user.name %>,
|
||||
|
||||
Thanks! You have successfully booked <%= @ticket_purchase.quantity %> <%= @ticket_purchase.ticket.title %> ticket(s) for the event <%= @conference.title %>. Your transaction id is <%= @ticket_purchase.id %>.
|
||||
|
||||
Please, find the ticket(s) pdf attached.
|
||||
|
||||
Best wishes,
|
||||
<%= @conference.title %> Team
|
||||
</span>
|
||||
</div>
|
||||
<div id="border">
|
||||
<h1></h1>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,83 @@
|
|||
Dear <%= @user.name %>,
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<!-- CSS -->
|
||||
<link rel="stylesheet" href="main.css">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:100,200,300,400,500,600,700,800" rel="stylesheet">
|
||||
<style>
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
Thanks! You have successfully booked <%= @ticket_purchase.quantity %> <%= @ticket_purchase.ticket.title %> ticket(s) for the event <%= @conference.title %>. Your transaction id is <%= @ticket_purchase.id %>.
|
||||
body {
|
||||
background: #fff;
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, 0.06);
|
||||
color: #000;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
Please, find the ticket(s) pdf attached.
|
||||
h1,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-weight: 400;
|
||||
line-height: 1.3;
|
||||
}
|
||||
p {
|
||||
color: #0B3559;
|
||||
font-weight: 400;
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
The SAP Young Thinkers team will reach out to you with information on how to participate in the event soon. In the meantime, you can check the event page (https://events.sap.com/yt-learning-festival-at-snapcon-2020/en/home) or send an email with your questions to youngthinkers@sap.com.
|
||||
#border {
|
||||
background-color: #0B3559;
|
||||
padding: 25px;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
Best wishes,
|
||||
<%= @conference.title %> Team
|
||||
#content {
|
||||
background-color: #fff;
|
||||
padding: 100px;
|
||||
color: #0B3559;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Page Title -->
|
||||
<title>Email</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="border">
|
||||
<div class="row">
|
||||
<!-- Uncomment below to get logo -->
|
||||
<div class="col-md-2">
|
||||
</div>
|
||||
<div class="col-md-10"><h1></h1></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<span style="white-space: pre-line">
|
||||
Dear <%= @user.name %>,
|
||||
|
||||
Thanks! You have successfully booked <%= @ticket_purchase.quantity %> <%= @ticket_purchase.ticket.title %> ticket(s) for the event <%= @conference.title %>. Your transaction id is <%= @ticket_purchase.id %>.
|
||||
|
||||
Please, find the ticket(s) pdf attached.
|
||||
|
||||
The SAP Young Thinkers team will reach out to you with information on how to participate in the event soon. In the meantime, you can check the event page (https://events.sap.com/yt-learning-festival-at-snapcon-2020/en/home) or send an email with your questions to youngthinkers@sap.com.
|
||||
|
||||
Best wishes,
|
||||
<%= @conference.title %> Team
|
||||
</span>
|
||||
</div>
|
||||
<div id="border">
|
||||
<h1></h1>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
= f.input :event_type_id, as: :select,
|
||||
collection: @conference.program.event_types.map {|type| ["#{type.title} - #{show_time(type.length)}", type.id,
|
||||
data: { min_words: type.minimum_abstract_length, max_words: type.maximum_abstract_length }]},
|
||||
data: { min_words: type.minimum_abstract_length, max_words: type.maximum_abstract_length, help: type.description }]},
|
||||
include_blank: false, label: 'Type', input_html: { class: 'select-help-toggle' }
|
||||
|
||||
- if @program.languages.present?
|
||||
|
|
@ -46,6 +46,22 @@
|
|||
250
|
||||
words.
|
||||
|
||||
%br
|
||||
|
||||
= f.input :submission_text, input_html: { rows: 5, data: { provide: 'markdown' }, placeholder: '' },
|
||||
hint: markdown_hint('Only conference organizers will read this.')
|
||||
|
||||
%p
|
||||
You have used
|
||||
%span#submission-count #{@event.submission_word_count}
|
||||
words. Submission descriptions must be between
|
||||
%span#submission-minimum-word-count
|
||||
0
|
||||
and
|
||||
%span#submission-maximum-word-count
|
||||
250
|
||||
words.
|
||||
|
||||
- if current_user.is_admin? or @program.cfp.enable_registrations?
|
||||
= f.inputs 'Enable pre-registration' do
|
||||
= f.input :require_registration, label: 'Require participants to register to your event'
|
||||
|
|
|
|||
|
|
@ -61,6 +61,22 @@
|
|||
250
|
||||
words.
|
||||
|
||||
= f.input :submission_text, input_html: { rows: 5, data: { provide: 'markdown' } },
|
||||
hint: markdown_hint
|
||||
|
||||
%p
|
||||
You have used
|
||||
%span#submission-count #{@event.submission_word_count}
|
||||
words. Submission descriptions must be between
|
||||
%span#submission-minimum-word-count
|
||||
0
|
||||
and
|
||||
%span#submission-maximum-word-count
|
||||
250
|
||||
words.
|
||||
|
||||
|
||||
|
||||
- if @program.cfp.enable_registrations?
|
||||
= f.input :require_registration, label: 'Require participants to register to your event'
|
||||
|
||||
|
|
|
|||
|
|
@ -65,5 +65,14 @@ module Osem
|
|||
config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=31536000' }
|
||||
|
||||
config.active_job.queue_adapter = :delayed_job
|
||||
|
||||
config.before_configuration do
|
||||
env_file = File.join(Rails.root, 'config', 'local_env.yml')
|
||||
if File.exist?(env_file)
|
||||
YAML.safe_load(File.open(env_file)).each do |key, value|
|
||||
ENV[key.to_s] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ default: &default
|
|||
encoding: <%= encoding %>
|
||||
host: <%= ENV['OSEM_DB_HOST'] || 'database' %>
|
||||
port: <%= ENV['OSEM_DB_PORT'] || '5432' %>
|
||||
# username: <%= ENV['OSEM_DB_USER'] || 'postgres' %>
|
||||
# password: <%= ENV['OSEM_DB_PASSWORD'] || 'mysecretpassword' %>
|
||||
username: <%= ENV['OSEM_DB_USER'] || 'postgres' %>
|
||||
password: <%= ENV['OSEM_DB_PASSWORD'] || 'mysecretpassword' %>
|
||||
database: <%= ENV['OSEM_DB_NAME'] || 'postgres' %>
|
||||
pool: 5
|
||||
timeout: 50000
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Osem::Application.routes.draw do
|
||||
|
||||
mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development?
|
||||
mount LetterOpenerWeb::Engine, at: '/letter_opener' if Rails.env.development?
|
||||
|
||||
if ENV['OSEM_ICHAIN_ENABLED'] == 'true'
|
||||
devise_for :users, controllers: { registrations: :registrations }
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ class AddVisibleToTickets < ActiveRecord::Migration[5.0]
|
|||
def up
|
||||
add_column :tickets, :visible, :boolean, default: true
|
||||
Ticket.reset_column_information
|
||||
Ticket.update_all(visible: true) # rubocop:disable Rails/SkipsModelValidations
|
||||
Ticket.update_all(visible: true)
|
||||
end
|
||||
|
||||
def down
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
class AddSubmissionTextToEvents < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :events, :submission_text, :text
|
||||
end
|
||||
end
|
||||
|
|
@ -258,6 +258,7 @@ ActiveRecord::Schema.define(version: 2021_03_03_052026) do
|
|||
t.integer "max_attendees"
|
||||
t.integer "comments_count", default: 0, null: false
|
||||
t.text "committee_review"
|
||||
t.text "submission_text"
|
||||
end
|
||||
|
||||
create_table "events_registrations", force: :cascade do |t|
|
||||
|
|
|
|||
20
info.yml
Normal file
20
info.yml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
project:
|
||||
name: 'snapcon'
|
||||
owner: 'cs169'
|
||||
teamId: '5'
|
||||
identities:
|
||||
pivotal:
|
||||
url: 'https://www.pivotaltracker.com/n/projects/2487653'
|
||||
heroku:
|
||||
url: 'https://cs169l-sp2021-snapcon.herokuapp.com'
|
||||
travis:
|
||||
url: 'https://travis-ci.com/github/CactusPuppy/snapcon'
|
||||
codeclimate:
|
||||
url: 'https://codeclimate.com/github/CactusPuppy/snapcon'
|
||||
members:
|
||||
member1:
|
||||
name: 'Coby'
|
||||
surname: 'Zhong'
|
||||
githubUsername: 'CactusPuppy'
|
||||
pivotalUsername: 'cobyzhong'
|
||||
herokuEmail: 'coby.zhong@berkeley.edu'
|
||||
|
|
@ -13,24 +13,24 @@ namespace :db do
|
|||
end
|
||||
end
|
||||
|
||||
desc "Import a given file into the database"
|
||||
desc 'Import a given file into the database'
|
||||
task :import, [:path] => :environment do |_t, args|
|
||||
dump_path = args.path
|
||||
connection_config = ActiveRecord::Base.connection_config
|
||||
|
||||
case connection_config[:adapter]
|
||||
when "postgresql"
|
||||
when 'postgresql'
|
||||
system("PGPASSWORD=#{connection_config[:password]} pg_restore " \
|
||||
"--verbose --clean --no-acl --no-owner " \
|
||||
'--verbose --clean --no-acl --no-owner ' \
|
||||
"--username=#{connection_config[:username]} " \
|
||||
"-d #{connection_config[:database]} #{dump_path}")
|
||||
when "mysql", "mysql2"
|
||||
when 'mysql', 'mysql2'
|
||||
system("mysql -u #{connection_config[:username]} " \
|
||||
"-p#{connection_config[:password]} " \
|
||||
"#{connection_config[:database]} < #{dump_path}")
|
||||
else
|
||||
raise NotImplementedError, "An importer hasn't been implemented for: " \
|
||||
"#{connection_config[:adapter]}"
|
||||
raise NotImplementedError.new("An importer hasn't been implemented for: " \
|
||||
"#{connection_config[:adapter]}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
namespace :registrations do
|
||||
desc "Create missing registrations for those how have a registration ticket."
|
||||
task :create_missing, [:conference] => :environment do |t, args|
|
||||
desc 'Create missing registrations for those how have a registration ticket.'
|
||||
task :create_missing, [:conference] => :environment do |_t, args|
|
||||
|
||||
fail 'Please supply a conference short name.' unless args.conference
|
||||
raise 'Please supply a conference short name.' unless args.conference
|
||||
|
||||
conf = Conference.find_by(short_title: args.conference)
|
||||
# Check if a user is found based on the supplied email address
|
||||
fail "Coud not find conference #{args.conference}" unless conf
|
||||
raise "Coud not find conference #{args.conference}" unless conf
|
||||
|
||||
purchases = conf.ticket_purchases.where(ticket: conf.registration_tickets, paid: true)
|
||||
unregistered = purchases.select { |tp| !conf.user_registered?(tp.user) }
|
||||
unregistered = purchases.reject { |tp| conf.user_registered?(tp.user) }
|
||||
puts "Found #{unregistered.count} unregistered users for #{purchases.count} ticket purchases."
|
||||
puts "There are currently #{conf.participants.count} registered users."
|
||||
|
||||
|
|
@ -19,17 +19,17 @@ namespace :registrations do
|
|||
puts "Creating registration for #{tp.user.email}"
|
||||
Registration.create(user: tp.user, conference: conf)
|
||||
end
|
||||
puts "Done."
|
||||
puts 'Done.'
|
||||
end
|
||||
|
||||
desc "Show User emails who have not paid, but did register"
|
||||
task :list_unpaid, [:conference] => :environment do |t, args|
|
||||
desc 'Show User emails who have not paid, but did register'
|
||||
task :list_unpaid, [:conference] => :environment do |_t, args|
|
||||
|
||||
fail 'Please supply a conference short name.' unless args.conference
|
||||
raise 'Please supply a conference short name.' unless args.conference
|
||||
|
||||
conf = Conference.find_by(short_title: args.conference)
|
||||
# Check if a user is found based on the supplied email address
|
||||
fail "Coud not find conference #{args.conference}" unless conf
|
||||
raise "Coud not find conference #{args.conference}" unless conf
|
||||
|
||||
registered = conf.participants
|
||||
unpaid = registered.select do |user|
|
||||
|
|
@ -41,6 +41,6 @@ namespace :registrations do
|
|||
unpaid.each do |user|
|
||||
puts "'#{user.name}'<#{user.email}>, "
|
||||
end
|
||||
puts ""
|
||||
puts ''
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
# require_registration :boolean
|
||||
# start_time :datetime
|
||||
# state :string default("new"), not null
|
||||
# submission_text :text
|
||||
# subtitle :string
|
||||
# title :string not null
|
||||
# week :integer
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@ feature 'BaseController' do
|
|||
|
||||
describe 'GET #verify_user_admin' do
|
||||
context 'when user is a guest' do
|
||||
before(:each) do
|
||||
sign_out
|
||||
end
|
||||
|
||||
it 'redirects to sign in page' do
|
||||
visit admin_conferences_path
|
||||
expect(current_path).to eq new_user_session_path
|
||||
|
|
|
|||
|
|
@ -27,6 +27,21 @@ feature Event do
|
|||
sign_in organizer
|
||||
end
|
||||
|
||||
scenario 'can preview a proposal if it is public', feature: true, js: true do
|
||||
visit admin_conference_program_event_path(conference.short_title, @event)
|
||||
expect(page).to have_selector(:link_or_button, 'Preview')
|
||||
click_link 'Preview'
|
||||
expect(current_path).to eq(conference_program_proposal_path(conference.short_title, @event.id))
|
||||
end
|
||||
|
||||
scenario 'cannot preview a proposal if it is not public', feature: true, js: true do
|
||||
event = create(:event, program: conference.program, title: 'Example Proposal')
|
||||
event.public = false
|
||||
event.save!
|
||||
visit admin_conference_program_event_path(conference.short_title, event)
|
||||
expect(page).to_not have_selector(:link_or_button, 'Preview')
|
||||
end
|
||||
|
||||
scenario 'rejects a proposal', feature: true, js: true do
|
||||
visit admin_conference_program_events_path(conference.short_title)
|
||||
expect(page).to have_content 'Example Proposal'
|
||||
|
|
@ -82,6 +97,7 @@ feature Event do
|
|||
fill_in 'event_title', with: 'Example Proposal'
|
||||
select('Example Event Type', from: 'event[event_type_id]')
|
||||
fill_in 'event_abstract', with: 'Lorem ipsum abstract'
|
||||
fill_in 'event_submission_text', with: 'Lorem ipsum submission'
|
||||
|
||||
click_button 'Submit Proposal'
|
||||
page.find('#flash')
|
||||
|
|
@ -123,6 +139,9 @@ feature Event do
|
|||
fill_in 'event_abstract', with: 'Lorem ipsum abstract'
|
||||
expect(page).to have_text('You have used 3 words')
|
||||
|
||||
fill_in 'event_submission_text', with: 'Lorem ipsum submission_text'
|
||||
expect(page).to have_text('Submission description')
|
||||
|
||||
click_link 'Do you require something special?'
|
||||
fill_in 'event_description', with: 'Lorem ipsum description'
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ describe ApplicationHelper, type: :helper do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'navigation link titke text' do
|
||||
describe 'navigation link title text' do
|
||||
it 'should default to OSEM' do
|
||||
ENV.delete('OSEM_NAME')
|
||||
expect(nav_link_text(nil)).to match 'OSEM'
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ require 'spec_helper'
|
|||
describe EventsHelper, type: :helper do
|
||||
let(:conference) { create(:conference) }
|
||||
let(:event) { create(:event_full, program: conference.program) }
|
||||
let(:event_schedule) { create(:event_schedule) }
|
||||
let(:my_vote) { 3 }
|
||||
let(:max_rating) { 5 }
|
||||
let(:fraction) { my_vote.to_s + '/' + max_rating.to_s }
|
||||
|
|
@ -28,6 +29,27 @@ describe EventsHelper, type: :helper do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#canceled_replacement_event_label' do
|
||||
describe 'returns nothing' do
|
||||
it "when the event isn't cancelled and is not a replacement" do
|
||||
event.state = 'confirmed'
|
||||
expect(canceled_replacement_event_label(event, nil, 'text-class')).to eq nil
|
||||
end
|
||||
|
||||
it 'when the event is canceled' do
|
||||
event.state = 'canceled'
|
||||
expect(canceled_replacement_event_label(event, nil, 'test-class')).to eq '<span class="label label-danger test-class">CANCELED</span>'
|
||||
end
|
||||
|
||||
it 'when the event is a replacement but is not canceled' do
|
||||
event.state = 'confirmed'
|
||||
allow(event_schedule).to receive(:replacement?) { true }
|
||||
expect(canceled_replacement_event_label(event, event_schedule, 'tent-class')).to eq '<span class="label label-info tent-class">REPLACEMENT</span>'
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
describe '#rating_tooltip' do
|
||||
let(:vote_count) { pluralize(event.voters.length, 'vote') }
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ describe Mailbot do
|
|||
end
|
||||
|
||||
it 'assigns the email body' do
|
||||
expect(mail.body).to eq 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit'
|
||||
expect(mail.body).to include 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit'
|
||||
end
|
||||
|
||||
it 'delivers the email' do
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
# require_registration :boolean
|
||||
# start_time :datetime
|
||||
# state :string default("new"), not null
|
||||
# submission_text :text
|
||||
# subtitle :string
|
||||
# title :string not null
|
||||
# week :integer
|
||||
|
|
@ -110,6 +111,35 @@ describe Event do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#submission_limit' do
|
||||
before :each do
|
||||
event.event_type.maximum_abstract_length = 3
|
||||
event.event_type.minimum_abstract_length = 2
|
||||
end
|
||||
|
||||
context 'is invalid' do
|
||||
it 'when submission text is too long' do
|
||||
event.submission_text = 'four too many words'
|
||||
expect(event.valid?).to eq false
|
||||
expect(event.errors[:submission_text]).to eq ['cannot have more than 3 words']
|
||||
end
|
||||
|
||||
it 'when submission text is too short' do
|
||||
event.submission_text = 'word'
|
||||
expect(event.valid?).to eq false
|
||||
expect(event.errors[:submission_text]).to eq ['cannot have less than 2 words']
|
||||
end
|
||||
end
|
||||
|
||||
context 'is valid' do
|
||||
it 'when submission text is within limts' do
|
||||
event.abstract = 'the magic three'
|
||||
expect(event.valid?).to eq true
|
||||
expect(event.errors.size).to eq 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#before_end_of_conference' do
|
||||
context 'is invalid' do
|
||||
it 'when event is created after the conference end_date, and returns an error message' do
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
# require_registration :boolean
|
||||
# start_time :datetime
|
||||
# state :string default("new"), not null
|
||||
# submission_text :text
|
||||
# subtitle :string
|
||||
# title :string not null
|
||||
# week :integer
|
||||
|
|
|
|||
|
|
@ -88,6 +88,10 @@ module OmniauthMacros
|
|||
# account is available for every supported omniauth provider.
|
||||
# These must be identical to the ones in /config/environments/development.rb
|
||||
# Remember to keep them in sync with development.rb
|
||||
#
|
||||
# Note that the method length check is disabled to allow for better formatting
|
||||
# of the user params.
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def mock_auth_accounts
|
||||
OmniAuth.config.mock_auth[:facebook] =
|
||||
OmniAuth::AuthHash.new(
|
||||
|
|
@ -164,4 +168,5 @@ module OmniauthMacros
|
|||
}
|
||||
)
|
||||
end
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue