156 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			156 lines
		
	
	
		
			4.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 ]
 | |
|   skip_before_action :require_authentication, only: %i[ scoreboard offline_new offline_create ]
 | |
| 
 | |
|   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/test"
 | |
|     else
 | |
|       render :offline_new, status: :unprocessable_entity
 | |
|     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, :start_image ])
 | |
|   end
 | |
| end
 |