195 lines
5.5 KiB
Ruby
195 lines
5.5 KiB
Ruby
class ContestsController < ApplicationController
|
|
before_action :set_contest, only: %i[ destroy edit show update ]
|
|
before_action :offline_setup, only: %i[ offline_new offline_create offline_edit offline_update offline_completed ]
|
|
skip_before_action :require_authentication, only: %i[ scoreboard offline_new offline_create offline_edit offline_update offline_completed ]
|
|
|
|
def index
|
|
authorize :contest
|
|
|
|
@contests = current_user.contests
|
|
@title = I18n.t("contests.index.title", username: current_user.username)
|
|
end
|
|
|
|
def show
|
|
authorize @contest
|
|
|
|
@title = I18n.t("contests.show.title", name: @contest.name)
|
|
@action_name = t("helpers.buttons.edit")
|
|
@action_path = edit_contest_path(@contest)
|
|
@contestants = @contest.contestants.sort_by { |contestant| [
|
|
-contestant.completions.where(remaining_pieces: nil).size,
|
|
(contestant.completions.where(remaining_pieces: nil).size == @contest.puzzles.length ? 1 : 0) * contestant.time_seconds,
|
|
contestant.completions.size > 0 && contestant.completions[-1].remaining_pieces ? contestant.completions[-1].remaining_pieces : 1000000,
|
|
contestant.time_seconds
|
|
] }
|
|
filter_contestants_per_category
|
|
@puzzles = @contest.puzzles.order(:id)
|
|
@messages = @contest.messages.order(:time_seconds)
|
|
set_badges
|
|
end
|
|
|
|
def edit
|
|
authorize @contest
|
|
|
|
@action_name = t("helpers.buttons.back")
|
|
@action_path = contest_path(@contest)
|
|
end
|
|
|
|
def new
|
|
authorize :contest
|
|
|
|
@contest = Contest.new
|
|
end
|
|
|
|
def create
|
|
authorize :contest
|
|
|
|
@contest = Contest.new(contest_params)
|
|
@contest.user_id = current_user.id
|
|
if @contest.save
|
|
redirect_to @contest, notice: t("contests.new.notice")
|
|
else
|
|
render :new, status: :unprocessable_entity
|
|
end
|
|
end
|
|
|
|
def update
|
|
authorize @contest
|
|
|
|
if @contest.update(contest_params)
|
|
redirect_to @contest, notice: t("contests.edit.notice")
|
|
else
|
|
@action_name = t("helpers.buttons.back")
|
|
@action_path = contest_path(@contest)
|
|
render :edit, status: :unprocessable_entity
|
|
end
|
|
end
|
|
|
|
def destroy
|
|
authorize @contest
|
|
|
|
@contest.destroy
|
|
redirect_to contests_path, notice: t("contests.destroy.notice")
|
|
end
|
|
|
|
def scoreboard
|
|
@contest = Contest.find_by(slug: params[:id])
|
|
unless @contest && @contest.public
|
|
skip_authorization
|
|
not_found and return
|
|
end
|
|
authorize @contest
|
|
|
|
I18n.locale = @contest.lang
|
|
|
|
@title = I18n.t("contests.scoreboard.title", name: @contest.name)
|
|
@contestants = @contest.contestants.sort_by { |contestant| [
|
|
-contestant.completions.where(remaining_pieces: nil).size,
|
|
(contestant.completions.where(remaining_pieces: nil).size == @contest.puzzles.length ? 1 : 0) * contestant.time_seconds,
|
|
contestant.completions.size > 0 && contestant.completions[-1].remaining_pieces ? contestant.completions[-1].remaining_pieces : 1000000,
|
|
contestant.time_seconds
|
|
] }
|
|
filter_contestants_per_category
|
|
@puzzles = @contest.puzzles.order(:id)
|
|
@action_name = t("helpers.buttons.refresh")
|
|
if params.key?(:category)
|
|
@action_path = "/public/#{@contest.friendly_id}?category=#{params[:category]}"
|
|
else
|
|
@action_path = "/public/#{@contest.friendly_id}"
|
|
end
|
|
render :scoreboard
|
|
end
|
|
|
|
def offline_new
|
|
authorize @contest
|
|
@offline = Offline.new
|
|
end
|
|
|
|
def offline_create
|
|
authorize @contest
|
|
@offline = Offline.new(offline_start_params)
|
|
@offline.contest = @contest
|
|
@offline.start_time = Time.now()
|
|
if @offline.save
|
|
redirect_to "/public/#{@contest.friendly_id}/offline/#{@offline.generate_token_for(:token)}"
|
|
else
|
|
render :offline_new, status: :unprocessable_entity
|
|
end
|
|
end
|
|
|
|
def offline_edit
|
|
authorize @contest
|
|
|
|
@offline = Offline.find_by_token_for(:token, params[:token])
|
|
if !@offline
|
|
not_found and return
|
|
end
|
|
end
|
|
|
|
def offline_update
|
|
authorize @contest
|
|
|
|
@offline = Offline.find_by_token_for(:token, params[:token])
|
|
if !@offline
|
|
not_found and return
|
|
end
|
|
|
|
@offline.completed = true
|
|
@offline.images.attach(params[:offline][:end_image])
|
|
if @offline.save
|
|
redirect_to "/public/#{@contest.friendly_id}/offline/#{@offline.generate_token_for(:token)}/completed"
|
|
else
|
|
render :offline_edit, status: :unprocessable_entity
|
|
end
|
|
end
|
|
|
|
def offline_completed
|
|
authorize @contest
|
|
|
|
@offline = Offline.find_by_token_for(:token, params[:token])
|
|
if !@offline
|
|
not_found and return
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def offline_setup
|
|
@contest = Contest.find_by(slug: params[:id])
|
|
I18n.locale = @contest.lang
|
|
@title = I18n.t("contests.scoreboard.title", name: @contest.name)
|
|
end
|
|
|
|
def set_badges
|
|
@badges = []
|
|
@badges.push(t("helpers.badges.team")) if @contest.team
|
|
@badges.push(t("helpers.badges.registration")) if @contest.allow_registration
|
|
end
|
|
|
|
def set_contest
|
|
@contest = Contest.find(params[:id])
|
|
end
|
|
|
|
def contest_params
|
|
params.expect(contest: [ :lang, :name, :offline_form, :public, :team, :allow_registration ])
|
|
end
|
|
|
|
def filter_contestants_per_category
|
|
if params.key?(:category) && params[:category] != "-1"
|
|
if params[:category] == "-2"
|
|
@contestants = @contestants.select { |contestant| contestant.categories.size == 0 }
|
|
else
|
|
@contestants = @contestants.select { |contestant| contestant.categories.where(id: params[:category]).any? }
|
|
end
|
|
end
|
|
end
|
|
|
|
def offline_start_params
|
|
params.expect(offline: [ :name, :images ])
|
|
end
|
|
|
|
def offline_end_params
|
|
params.expect(offline: [ :completed, :end_image ])
|
|
end
|
|
end
|