199 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			199 lines
		
	
	
		
			5.6 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
 | 
						|
 | 
						|
    if @offline.images.length > 1
 | 
						|
      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.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
 |