Skip to content

Commit

Permalink
Merge branch 'dev' into 148__ConsGerman_Errors_MeineBewerbungen
Browse files Browse the repository at this point in the history
  • Loading branch information
Niklas Kiefer committed Jan 6, 2017
2 parents f9d3a88 + 2f36f77 commit 482b22c
Show file tree
Hide file tree
Showing 50 changed files with 656 additions and 150 deletions.
7 changes: 5 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ gem 'coveralls', require: false
gem 'prawn'
gem 'prawn-table'

# pdf inspection
gem 'pdf-inspector', require: "pdf/inspector"

# Simple, Heroku-friendly Rails app configuration using ENV and a single YAML file
gem 'figaro'

Expand Down Expand Up @@ -135,9 +138,9 @@ group :test do
gem 'parser', '~> 2.2.2.5'
# Stubbing external calls by blocking traffic with WebMock.disable_net_connect! or allow:
# gem 'webmock'

end

# PDF testing
gem 'pdf-inspector', require: "pdf/inspector"end

group :production do
# Use Puma web server
Expand Down
Binary file added app/assets/images/example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/assets/images/front-welcome.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions app/assets/stylesheets/application.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,45 @@ label.required:after {
content:" *";
color: red
}

body {
/* font styles as found in bootstrap v4 */
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

footer.front-section {
border: none;
}
footer {
margin-top: 60px;
}
.m-l-1 { margin-left: 15px; }
.m-r-1 { margin-right: 15px; }
.m-t-1 { margin-top: 15px; }
.m-b-1 { margin-bottom: 15px; }

.img-float-corner-tr {
float: right;
margin: 0 0 15px 15px;
}
@media (max-width: 768px) {
.img-float-corner-tr {
float: none;
margin: auto;
margin-bottom: 15px;
}
}
.front-section {
border-bottom: 1px solid #eee;
padding: 60px 0;
}
.front-section:first-child {
padding-top: 30px;
}
.front-section:last-of-type {
border: none;
}
.front-section:nth-child(even), footer {
background-color: #333;
color: #eee;
}
5 changes: 1 addition & 4 deletions app/assets/stylesheets/bootstrap_and_overrides.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
/*
=require twitter-bootstrap-static/bootstrap
Use Font Awesome icons (default)
To use Glyphicons sprites instead of Font Awesome, replace with "require twitter-bootstrap-static/sprites"
=require twitter-bootstrap-static/fontawesome
=require twitter-bootstrap-static/sprites
*/

.no-padding {
Expand Down
57 changes: 57 additions & 0 deletions app/assets/stylesheets/events.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,60 @@
.tooltip .btn[disabled] {
pointer-events: none;
}

/* styles for the event preview (every item in an event list) */
.event-preview {
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
margin: 15px 0;
padding-bottom: 15px;
}
.event-preview.event-past {
opacity: 0.7;
}
.front-section:nth-child(even) .event-preview {
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
}
.event-list .event-preview:last-of-type {
border-bottom: none;
}
.event-preview h3 {
margin-top: 0;
}
.event-date {
text-align: center;
line-height: 3em;
margin-right: 15px;
float: left;
}
.event-date > span {
display: block;
}
.event-day {
font-weight: 800;
font-size: 4em;
}
.event-month {
font-size: 2em;
font-weight: 100;
}
.event-year {
margin: -1.2em 0;
}
@media (max-width: 768px) {
.event-date {
float: none;
margin-bottom: 15px;
}
.event-day:after {
content: '.';
}
.event-year {
}
.event-date > span {
margin-left: 5px;
font-weight: 100;
display: inline-block;
vertical-align: middle;
font-size: 1.5em;
}
}
13 changes: 0 additions & 13 deletions app/assets/stylesheets/scaffold.css
Original file line number Diff line number Diff line change
@@ -1,22 +1,9 @@
body { background-color: #fff; color: #333; }

body, p, ol, ul, td {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 13px;
line-height: 18px;
}

pre {
background-color: #eee;
padding: 10px;
font-size: 11px;
}

/* not-selector to prevent override of bootstrap button color */
a:not(.btn) { color: #000; }
a:visited:not(.btn) { color: #666; }
a:hover:not(.btn) { color: #fff; background-color:#000; }

.field, .actions {
margin-bottom: 10px;
}
Expand Down
9 changes: 8 additions & 1 deletion app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,14 @@ class ApplicationController < ActionController::Base
end

def index

# FIXME application-side filtering isn't all that great, but
# unless we want to write custom SQL joins (which
# we should if this becomes a perf problem), there is no
# other solution
@events = Event.sorted_by_start_date(true)
.select { |a| a.start_date > Time.now }
.first(3)
render 'index', locals: { full_width: true }
end

protected
Expand Down
40 changes: 39 additions & 1 deletion app/controllers/events_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ class EventsController < ApplicationController

# GET /events
def index
@events = Event.draft_is false
@events = Event.sorted_by_start_date(!can?(:edit, Event)).reverse
end

# GET /events/1
def show
@free_places = @event.compute_free_places
@occupied_places = @event.compute_occupied_places
@application_letters = filter_application_letters(@event.application_letters)
@material_files = get_material_files(@event)
end

# GET /events/new
Expand Down Expand Up @@ -108,6 +109,26 @@ def send_rejection_emails
render :email
end

# POST /events/1/upload_material
def upload_material
event = Event.find(params[:event_id])
material_path = event.material_path
Dir.mkdir(material_path) unless File.exists?(material_path)

file = params[:file_upload]
unless is_file?(file)
redirect_to event_path(event), alert: t("events.material_area.no_file_given")
return false
end
begin
File.write(File.join(material_path, file.original_filename), file.read, mode: "wb")
rescue IOError
redirect_to event_path(event), alert: I18n.t("events.material_area.saving_fails")
return false
end
redirect_to event_path(event), notice: I18n.t("events.material_area.success_message")
end

private
# Use callbacks to share common setup or constraints between actions.
def set_event
Expand Down Expand Up @@ -163,4 +184,21 @@ def create_badge_page(pdf, names, index)
create_badge(pdf, right, 260, 750 - row * 150) unless right.nil?
end
end

# Checks if a file is valid and not empty
#
# @param [ActionDispatch::Http::UploadedFile] is a file object
# @return [Boolean] whether @file is a valid file
def is_file?(file)
file.respond_to?(:open) && file.respond_to?(:content_type) && file.respond_to?(:size)
end

# Gets all file names stored in the material storage of the event
#
# @param [Event]
# @return [Array of Strings]
def get_material_files(event)
material_path = event.material_path
File.exists?(material_path) ? Dir.glob(File.join(material_path, "*")) : []
end
end
2 changes: 1 addition & 1 deletion app/controllers/requests_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ def set_request

# Only allow a trusted parameter "white list" through.
def request_params
params.require(:request).permit(:topics, :user_id)
params.require(:request).permit(:form_of_address, :first_name, :last_name, :phone_number, :address, :topic_of_workshop, :time_period, :email, :number_of_participants, :knowledge_level, :annotations)
end
end
1 change: 0 additions & 1 deletion app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module ApplicationHelper
def menu_items
(menu_item t(:home, scope: 'navbar'), root_path) +
(menu_item t(:events, scope: 'navbar'), events_path) +
(menu_item t(:requests, scope: 'navbar'), requests_path)
end
Expand Down
8 changes: 4 additions & 4 deletions app/models/ability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,17 @@ def initialize(user)
can [:new, :create], Request
end
if user.role? :coach
# Coaches can view Applications and participants for Event
can [:view_applicants, :view_participants], Event
# Coaches can view Applications and participants for and upload materials for Event
can [:view_applicants, :view_participants, :upload_material], Event
can [:view_and_add_notes, :show], ApplicationLetter
can [:print_applications], Event
end
if user.role? :organizer
can [:index, :show], Profile
can [:index, :show, :view_and_add_notes, :update_status], ApplicationLetter
cannot :update, ApplicationLetter
# Organizers can view, edit and print Applications, view participants for and manage Events
can [:view_applicants, :edit_applicants, :view_participants, :print_applications, :manage], Event
# Organizers can view, edit and print Applications, view participants for, upload materials for and manage Events
can [:view_applicants, :edit_applicants, :view_participants, :print_applications, :manage, :upload_material], Event
can :manage, Request
end
if user.role? :admin
Expand Down
13 changes: 13 additions & 0 deletions app/models/agreement_letter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
# created_at :datetime not null
# updated_at :datetime not null
#

class AgreementLetter < ActiveRecord::Base
belongs_to :user
belongs_to :event
Expand Down Expand Up @@ -74,6 +75,9 @@ def valid_file?(file)
elsif wrong_filetype?(file)
errors.add(:file, I18n.t("agreement_letters.wrong_filetype"))
false
elsif unable_to_open?(file)
errors.add(:file, I18n.t("agreement_letters.corrupt_document"))
false
else
true
end
Expand All @@ -90,4 +94,13 @@ def too_big?(file)
def wrong_filetype?(file)
file.content_type != ALLOWED_MIMETYPE
end

def unable_to_open? file
begin
PDF::Inspector::Page.analyze_file(file.open)
false
rescue PDF::Reader::UnsupportedFeatureError, PDF::Reader::MalformedPDFError
true
end
end
end
53 changes: 53 additions & 0 deletions app/models/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

class Event < ActiveRecord::Base
UNREASONABLY_LONG_DATE_SPAN = 300
TRUNCATE_DESCRIPTION_TEXT_LENGTH = 250

has_many :application_letters
has_many :agreement_letters
Expand Down Expand Up @@ -154,13 +155,54 @@ def compute_occupied_places
application_letters.where(status: ApplicationLetter.statuses[:accepted]).count
end

# Returns a label listing the number of days to the deadline if
# it's <= 7 days to go. Otherwise returns nil.
#
# @return string containing the label or nil
def application_deadline_label
days = (application_deadline - Date.current).to_i
I18n.t('events.notices.deadline_approaching', count: days) if days <= 7 and days > 0
end

# Uses the start date to determine whether or not this event is in the past (or more
# precisely, in the past or currently running)
#
# @return boolean if it's in the past
def is_past
return start_date < Date.current
end

# Returns a label that describes the duration of the event in days,
# also mentioning whether or not the event happens on consecutive
# days. If the event is only on a single day, it returns nothing.
#
# @return the duration label or nil
def duration_label
# gotta add 1 since from Sunday to Monday is on two days, but only
# a difference of a single day
days = (end_date - start_date).to_i + 1

if date_ranges.size > 1
I18n.t('events.notices.time_span_non_consecutive', count: days)
elsif days > 1
I18n.t('events.notices.time_span_consecutive', count: days)
end
end

# Make sure any assignment coming from the controller
# replaces all date ranges instead of adding new ones
def date_ranges_attributes=(*args)
self.date_ranges.clear
super(*args)
end

# Gets the path of the event in the material storage
#
# @return [String] path in the material storage
def material_path
File.join("storage/materials/", self.id.to_s + "_" + self.name)
end

# Make sure we add errors from our date_range children
# to the base event object for displaying
validate do |event|
Expand All @@ -174,6 +216,17 @@ def date_ranges_attributes=(*args)

scope :draft_is, ->(draft) { where("draft = ?", draft) }

# Returns events sorted by start date, returning only public ones
# if requested
#
# @param limit Maximum number of events to return
# @param only_public Set to true to not include drafts
# @return List of events
def self.sorted_by_start_date(only_public)
(only_public ? Event.draft_is(false) : Event.all)
.sort_by(&:start_date)
end

protected
# Compares two participants to achieve following order:
# 1. All participants that have to submit an letter of agreement but did not yet do so, ordered by name.
Expand Down
Loading

0 comments on commit 482b22c

Please sign in to comment.