238 lines
6.8 KiB
Ruby
238 lines
6.8 KiB
Ruby
class ContestsController < ApplicationController
|
|
include CompletionsConcern
|
|
include ContestantsConcern
|
|
|
|
before_action :set_contest, only: %i[ destroy show ]
|
|
before_action :set_settings_contest, only: %i[ settings_general_edit settings_general_update settings_offline_edit settings_offline_update settings_categories_edit ]
|
|
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
|
|
|
|
redirect_to contest_contestants_path(@contest)
|
|
end
|
|
|
|
def settings_general_edit
|
|
authorize @contest
|
|
end
|
|
|
|
def settings_offline_edit
|
|
authorize @contest
|
|
end
|
|
|
|
def settings_categories_edit
|
|
authorize @contest
|
|
end
|
|
|
|
def settings_general_update
|
|
authorize @contest
|
|
|
|
if @contest.update(settings_general_params)
|
|
redirect_to "/contests/#{@contest.id}/settings/general", notice: t("contests.edit.notice")
|
|
else
|
|
render :settings_general_edit, status: :unprocessable_entity
|
|
end
|
|
end
|
|
|
|
def settings_offline_update
|
|
authorize @contest
|
|
|
|
if @contest.update(settings_offline_params)
|
|
redirect_to "/contests/#{@contest.id}/settings/offline", notice: t("contests.edit.notice")
|
|
else
|
|
render :settings_offline_edit, status: :unprocessable_entity
|
|
end
|
|
end
|
|
|
|
def new
|
|
authorize :contest
|
|
|
|
@contest = Contest.new
|
|
@title = I18n.t("contests.new.title")
|
|
@nonav = true
|
|
end
|
|
|
|
def create
|
|
authorize :contest
|
|
|
|
@contest = Contest.new(new_contest_params)
|
|
@contest.lang = @current_user.lang
|
|
@contest.ranking_mode = "actual"
|
|
@contest.user_id = current_user.id
|
|
if @contest.save
|
|
redirect_to "/contests/#{@contest.id}/settings/general", notice: t("contests.new.notice")
|
|
else
|
|
@title = I18n.t("contests.new.title")
|
|
@nonav = true
|
|
render :new, 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 = ranked_contestants(@contest)
|
|
filter_contestants_per_category
|
|
if params.key?(:hide_offline) && params[:hide_offline] == "true"
|
|
@contestants = @contestants.select { |contestant| !contestant.offline.present? }
|
|
end
|
|
@puzzles = @contest.puzzles.order(:id)
|
|
if params.key?(:hide_offline) && params.key?(:category)
|
|
@action_path = "/public/#{@contest.friendly_id}?hide_offline=#{params[:hide_offline]}&category=#{params[:category]}"
|
|
elsif params.key?(:category)
|
|
@action_path = "/public/#{@contest.friendly_id}?category=#{params[:category]}"
|
|
elsif params.key?(:hide_offline)
|
|
@action_path = "/public/#{@contest.friendly_id}?hide_offline=#{params[:hide_offline]}"
|
|
else
|
|
@action_path = "/public/#{@contest.friendly_id}"
|
|
end
|
|
@space = " "
|
|
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
|
|
|
|
if @offline.submitted
|
|
render :offline_already_submitted 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.submitted = true
|
|
@offline.completed = params[:offline][:completed]
|
|
@offline.end_time = Time.now()
|
|
@offline.images.attach(params[:offline][:end_image])
|
|
if @offline.completed
|
|
@offline.missing_pieces = params[:offline][:missing_pieces]
|
|
else
|
|
@offline.remaining_pieces = params[:offline][:remaining_pieces]
|
|
end
|
|
if @offline.save
|
|
if @contest.puzzles.length > 0
|
|
dp = display_time(@offline.end_time.to_i - @offline.start_time.to_i)
|
|
contestant = Contestant.create(contest: @contest, name: @offline.name, offline: @offline)
|
|
Completion.create(contest: @contest,
|
|
contestant: contestant,
|
|
offline: @offline,
|
|
puzzle: @contest.puzzles[0],
|
|
completed: @offline.completed,
|
|
display_time_from_start: dp,
|
|
missing_pieces: @offline.missing_pieces,
|
|
remaining_pieces: @offline.remaining_pieces)
|
|
extend_completions!(contestant)
|
|
end
|
|
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_contest
|
|
@contest = Contest.find(params[:id])
|
|
end
|
|
|
|
def set_settings_contest
|
|
@contest = Contest.find(params[:contest_id])
|
|
end
|
|
|
|
def new_contest_params
|
|
params.expect(contest: [ :name, :duration ])
|
|
end
|
|
|
|
def settings_general_params
|
|
params.expect(contest: [ :lang, :name, :duration, :public, :ranking_mode, :team, :allow_registration, :code ])
|
|
end
|
|
|
|
def settings_offline_params
|
|
params.expect(contest: [ :offline_form ])
|
|
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, :remaining_pieces, :missing_pieces ])
|
|
end
|
|
end
|