mirror of
https://github.com/jcwimer/wrestlingApp
synced 2026-04-02 21:24:25 +00:00
Upgraded to rails 8.0.2, moved from dalli to solid cache, moved from delayed_job to solid queue, and add solid cable. deploy/rails-dev-run.sh no longer needs to chmod. Fixed finished_at callback for matches. Migrated from Devise to built in rails auth. Added view tests for the bracket page testing that all bout numbers render for all matches in each bracket type.
This commit is contained in:
@@ -5,6 +5,21 @@ class ApplicationController < ActionController::Base
|
||||
|
||||
after_action :set_csrf_cookie_for_ng
|
||||
|
||||
# Add helpers for authentication (replacing Devise)
|
||||
helper_method :current_user, :user_signed_in?
|
||||
|
||||
def current_user
|
||||
@current_user ||= User.find_by(id: session[:user_id]) if session[:user_id]
|
||||
end
|
||||
|
||||
def user_signed_in?
|
||||
current_user.present?
|
||||
end
|
||||
|
||||
def authenticate_user!
|
||||
redirect_to login_path, alert: "Please log in to access this page" unless user_signed_in?
|
||||
end
|
||||
|
||||
def set_csrf_cookie_for_ng
|
||||
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class MatAssignmentRulesController < ApplicationController
|
||||
before_action :set_tournament
|
||||
before_action :check_access_manage
|
||||
before_action :set_mat_assignment_rule, only: [:edit, :update, :show, :destroy]
|
||||
before_action :set_mat_assignment_rule, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
@mat_assignment_rules = @tournament.mat_assignment_rules
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class MatchesController < ApplicationController
|
||||
before_action :set_match, only: [:show, :edit, :update, :destroy, :stat]
|
||||
before_action :set_match, only: [:show, :edit, :update, :stat]
|
||||
before_action :check_access, only: [:edit,:update, :stat]
|
||||
|
||||
# GET /matches/1
|
||||
|
||||
57
app/controllers/password_resets_controller.rb
Normal file
57
app/controllers/password_resets_controller.rb
Normal file
@@ -0,0 +1,57 @@
|
||||
class PasswordResetsController < ApplicationController
|
||||
before_action :get_user, only: [:edit, :update]
|
||||
before_action :valid_user, only: [:edit, :update]
|
||||
before_action :check_expiration, only: [:edit, :update]
|
||||
|
||||
def new
|
||||
end
|
||||
|
||||
def create
|
||||
@user = User.find_by(email: params[:password_reset][:email].downcase)
|
||||
if @user
|
||||
@user.create_reset_digest
|
||||
@user.send_password_reset_email
|
||||
redirect_to root_url, notice: "Email sent with password reset instructions"
|
||||
else
|
||||
flash.now[:alert] = "Email address not found"
|
||||
render 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
if params[:user][:password].empty?
|
||||
@user.errors.add(:password, "can't be empty")
|
||||
render 'edit'
|
||||
elsif @user.update(user_params)
|
||||
session[:user_id] = @user.id
|
||||
redirect_to root_url, notice: "Password has been reset"
|
||||
else
|
||||
render 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(:password, :password_confirmation)
|
||||
end
|
||||
|
||||
def get_user
|
||||
@user = User.find_by(email: params[:email])
|
||||
end
|
||||
|
||||
def valid_user
|
||||
unless @user && @user.authenticated?(:reset, params[:id])
|
||||
redirect_to root_url
|
||||
end
|
||||
end
|
||||
|
||||
def check_expiration
|
||||
if @user.password_reset_expired?
|
||||
redirect_to new_password_reset_url, alert: "Password reset has expired"
|
||||
end
|
||||
end
|
||||
end
|
||||
20
app/controllers/sessions_controller.rb
Normal file
20
app/controllers/sessions_controller.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
class SessionsController < ApplicationController
|
||||
def new
|
||||
end
|
||||
|
||||
def create
|
||||
user = User.find_by(email: params[:session][:email].downcase)
|
||||
if user && user.authenticate(params[:session][:password])
|
||||
session[:user_id] = user.id
|
||||
redirect_to root_path, notice: "Logged in successfully"
|
||||
else
|
||||
flash.now[:alert] = "Invalid email/password combination"
|
||||
render 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
session.delete(:user_id)
|
||||
redirect_to root_path, notice: "Logged out successfully"
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,5 @@
|
||||
class TournamentsController < ApplicationController
|
||||
before_action :set_tournament, only: [:all_results, :delete_school_keys, :generate_school_keys,:reset_bout_board,:calculate_team_scores,:bout_sheets,:swap,:weigh_in_sheet,:error,:teampointadjust,:remove_teampointadjust,:remove_school_delegate,:remove_delegate,:school_delegate,:delegate,:matches,:weigh_in,:weigh_in_weight,:create_custom_weights,:show,:edit,:update,:destroy,:up_matches,:no_matches,:team_scores,:brackets,:generate_matches,:bracket,:all_brackets]
|
||||
before_action :set_tournament, only: [:all_results, :delete_school_keys, :generate_school_keys,:reset_bout_board,:calculate_team_scores,:bout_sheets,:swap,:weigh_in_sheet,:error,:teampointadjust,:remove_teampointadjust,:remove_school_delegate,:remove_delegate,:school_delegate,:delegate,:matches,:weigh_in,:weigh_in_weight,:create_custom_weights,:show,:edit,:update,:destroy,:up_matches,:no_matches,:team_scores,:generate_matches,:bracket,:all_brackets]
|
||||
before_action :check_access_manage, only: [:delete_school_keys, :generate_school_keys,:reset_bout_board,:calculate_team_scores,:swap,:weigh_in_sheet,:teampointadjust,:remove_teampointadjust,:remove_school_delegate,:school_delegate,:weigh_in,:weigh_in_weight,:create_custom_weights,:update,:edit,:generate_matches,:matches]
|
||||
before_action :check_access_destroy, only: [:destroy,:delegate,:remove_delegate]
|
||||
before_action :check_tournament_errors, only: [:generate_matches]
|
||||
@@ -229,6 +229,7 @@ class TournamentsController < ApplicationController
|
||||
end
|
||||
|
||||
def show
|
||||
@tournament = Tournament.find(params[:id])
|
||||
@schools = @tournament.schools.includes(:delegates).sort_by{|school|school.name}
|
||||
@weights = @tournament.weights.sort_by{|x|[x.max]}
|
||||
@mats = @tournament.mats.sort_by{|mat|mat.name}
|
||||
|
||||
48
app/controllers/users_controller.rb
Normal file
48
app/controllers/users_controller.rb
Normal file
@@ -0,0 +1,48 @@
|
||||
class UsersController < ApplicationController
|
||||
before_action :require_login, only: [:edit, :update]
|
||||
before_action :correct_user, only: [:edit, :update]
|
||||
|
||||
def new
|
||||
@user = User.new
|
||||
end
|
||||
|
||||
def create
|
||||
@user = User.new(user_params)
|
||||
if @user.save
|
||||
session[:user_id] = @user.id
|
||||
redirect_to root_path, notice: "Account created successfully"
|
||||
else
|
||||
render 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@user = User.find(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
@user = User.find(params[:id])
|
||||
if @user.update(user_params)
|
||||
redirect_to root_path, notice: "Account updated successfully"
|
||||
else
|
||||
render 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(:email, :password, :password_confirmation)
|
||||
end
|
||||
|
||||
def require_login
|
||||
unless current_user
|
||||
redirect_to login_path, alert: "Please log in to access this page"
|
||||
end
|
||||
end
|
||||
|
||||
def correct_user
|
||||
@user = User.find(params[:id])
|
||||
redirect_to root_path unless current_user == @user
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
class WeightsController < ApplicationController
|
||||
before_action :set_weight, only: [:pool_order, :show, :edit, :update, :destroy,:re_gen]
|
||||
before_action :check_access_manage, only: [:pool_order, :new,:create,:update,:destroy,:edit, :re_gen]
|
||||
before_action :set_weight, only: [:pool_order, :show, :edit, :update, :destroy]
|
||||
before_action :check_access_manage, only: [:pool_order, :new,:create,:update,:destroy,:edit]
|
||||
before_action :check_access_read, only: [:show]
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class WrestlersController < ApplicationController
|
||||
before_action :set_wrestler, only: [:show, :edit, :update, :destroy, :update_pool]
|
||||
before_action :check_access, only: [:new, :create, :update, :destroy, :edit, :update_pool]
|
||||
before_action :set_wrestler, only: [:show, :edit, :update, :destroy]
|
||||
before_action :check_access, only: [:new, :create, :update, :destroy, :edit]
|
||||
before_action :check_read_access, only: [:show]
|
||||
|
||||
# GET /wrestlers/1
|
||||
@@ -36,7 +36,7 @@ class WrestlersController < ApplicationController
|
||||
@school_permission_key = wrestler_params[:school_permission_key].presence
|
||||
@weights = @school.tournament.weights if @school
|
||||
|
||||
# Remove the key from attributes so it isn’t assigned to the model.
|
||||
# Remove the key from attributes so it isn't assigned to the model.
|
||||
@wrestler = Wrestler.new(wrestler_params.except(:school_permission_key))
|
||||
|
||||
respond_to do |format|
|
||||
|
||||
16
app/jobs/advance_wrestler_job.rb
Normal file
16
app/jobs/advance_wrestler_job.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
class AdvanceWrestlerJob < ApplicationJob
|
||||
queue_as :default
|
||||
|
||||
# Class method for direct execution in test environment
|
||||
def self.perform_sync(wrestler, match)
|
||||
# Execute directly on provided objects
|
||||
service = AdvanceWrestler.new(wrestler, match)
|
||||
service.advance_raw
|
||||
end
|
||||
|
||||
def perform(wrestler, match)
|
||||
# Execute the job
|
||||
service = AdvanceWrestler.new(wrestler, match)
|
||||
service.advance_raw
|
||||
end
|
||||
end
|
||||
7
app/jobs/application_job.rb
Normal file
7
app/jobs/application_job.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
class ApplicationJob < ActiveJob::Base
|
||||
# Automatically retry jobs that encountered a deadlock
|
||||
# retry_on ActiveRecord::Deadlocked
|
||||
|
||||
# Most jobs are safe to ignore if the underlying records are no longer available
|
||||
# discard_on ActiveJob::DeserializationError
|
||||
end
|
||||
17
app/jobs/calculate_school_score_job.rb
Normal file
17
app/jobs/calculate_school_score_job.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
class CalculateSchoolScoreJob < ApplicationJob
|
||||
queue_as :default
|
||||
|
||||
# Class method for direct execution in test environment
|
||||
def self.perform_sync(school)
|
||||
# Execute directly on provided objects
|
||||
school.calculate_score_raw
|
||||
end
|
||||
|
||||
def perform(school)
|
||||
# Log information about the job
|
||||
Rails.logger.info("Calculating score for school ##{school.id} (#{school.name})")
|
||||
|
||||
# Execute the calculation
|
||||
school.calculate_score_raw
|
||||
end
|
||||
end
|
||||
27
app/jobs/generate_tournament_matches_job.rb
Normal file
27
app/jobs/generate_tournament_matches_job.rb
Normal file
@@ -0,0 +1,27 @@
|
||||
class GenerateTournamentMatchesJob < ApplicationJob
|
||||
queue_as :default
|
||||
|
||||
# Class method for direct execution in test environment
|
||||
def self.perform_sync(tournament)
|
||||
# Execute directly on provided objects
|
||||
generator = GenerateTournamentMatches.new(tournament)
|
||||
generator.generate_raw
|
||||
end
|
||||
|
||||
def perform(tournament)
|
||||
# Log information about the job
|
||||
Rails.logger.info("Starting tournament match generation for tournament ##{tournament.id}")
|
||||
|
||||
begin
|
||||
# Execute the job
|
||||
generator = GenerateTournamentMatches.new(tournament)
|
||||
generator.generate_raw
|
||||
|
||||
Rails.logger.info("Completed tournament match generation for tournament ##{tournament.id}")
|
||||
rescue => e
|
||||
Rails.logger.error("Error generating tournament matches: #{e.message}")
|
||||
Rails.logger.error(e.backtrace.join("\n"))
|
||||
raise # Re-raise the error so it's properly recorded
|
||||
end
|
||||
end
|
||||
end
|
||||
19
app/jobs/tournament_backup_job.rb
Normal file
19
app/jobs/tournament_backup_job.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
class TournamentBackupJob < ApplicationJob
|
||||
queue_as :default
|
||||
|
||||
# Class method for direct execution in test environment
|
||||
def self.perform_sync(tournament, reason = nil)
|
||||
# Execute directly on provided objects
|
||||
service = TournamentBackupService.new(tournament, reason)
|
||||
service.create_backup_raw
|
||||
end
|
||||
|
||||
def perform(tournament, reason = nil)
|
||||
# Log information about the job
|
||||
Rails.logger.info("Creating backup for tournament ##{tournament.id} (#{tournament.name}), reason: #{reason || 'manual'}")
|
||||
|
||||
# Execute the backup
|
||||
service = TournamentBackupService.new(tournament, reason)
|
||||
service.create_backup_raw
|
||||
end
|
||||
end
|
||||
21
app/jobs/wrestlingdev_import_job.rb
Normal file
21
app/jobs/wrestlingdev_import_job.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
class WrestlingdevImportJob < ApplicationJob
|
||||
queue_as :default
|
||||
|
||||
# Class method for direct execution in test environment
|
||||
def self.perform_sync(tournament, import_data = nil)
|
||||
# Execute directly on provided objects
|
||||
importer = WrestlingdevImporter.new(tournament)
|
||||
importer.import_data = import_data if import_data
|
||||
importer.import_raw
|
||||
end
|
||||
|
||||
def perform(tournament, import_data = nil)
|
||||
# Log information about the job
|
||||
Rails.logger.info("Starting import for tournament ##{tournament.id} (#{tournament.name})")
|
||||
|
||||
# Execute the import
|
||||
importer = WrestlingdevImporter.new(tournament)
|
||||
importer.import_data = import_data if import_data
|
||||
importer.import_raw
|
||||
end
|
||||
end
|
||||
4
app/mailers/application_mailer.rb
Normal file
4
app/mailers/application_mailer.rb
Normal file
@@ -0,0 +1,4 @@
|
||||
class ApplicationMailer < ActionMailer::Base
|
||||
default from: ENV["WRESTLINGDEV_EMAIL"]
|
||||
layout 'mailer'
|
||||
end
|
||||
11
app/mailers/user_mailer.rb
Normal file
11
app/mailers/user_mailer.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class UserMailer < ApplicationMailer
|
||||
# Subject can be set in your I18n file at config/locales/en.yml
|
||||
# with the following lookup:
|
||||
#
|
||||
# en.user_mailer.password_reset.subject
|
||||
#
|
||||
def password_reset(user)
|
||||
@user = user
|
||||
mail to: user.email, subject: "Password reset"
|
||||
end
|
||||
end
|
||||
@@ -6,9 +6,8 @@ class Match < ApplicationRecord
|
||||
has_many :schools, :through => :wrestlers
|
||||
validate :score_validation, :win_type_validation, :bracket_position_validation, :overtime_type_validation
|
||||
|
||||
# Callback to update finished_at when finished changes
|
||||
# for some reason saved_change_to_finished? does not work on before_save like it does for after_update
|
||||
before_save :update_finished_at, if: -> { will_save_change_to_attribute?(:finished) }
|
||||
# Callback to update finished_at when a match is finished
|
||||
before_save :update_finished_at
|
||||
|
||||
after_update :after_finished_actions, if: -> {
|
||||
saved_change_to_finished? ||
|
||||
@@ -312,6 +311,12 @@ class Match < ApplicationRecord
|
||||
private
|
||||
|
||||
def update_finished_at
|
||||
self.finished_at = finished == 1 ? Time.current.utc : nil
|
||||
# Get the changes that will be persisted
|
||||
changes = changes_to_save
|
||||
|
||||
# Check if finished is changing from 0 to 1 or if it's already 1 but has no timestamp
|
||||
if (changes['finished'] && changes['finished'][1] == 1) || (finished == 1 && finished_at.nil?)
|
||||
self.finished_at = Time.current.utc
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -36,13 +36,9 @@ class School < ApplicationRecord
|
||||
end
|
||||
|
||||
def calculate_score
|
||||
if Rails.env.production?
|
||||
self.delay(:job_owner_id => self.tournament.id, :job_owner_type => "Calculate team score for #{self.name}").calculate_score_raw
|
||||
else
|
||||
calculate_score_raw
|
||||
end
|
||||
|
||||
end
|
||||
# Use perform_later which will execute based on centralized adapter config
|
||||
CalculateSchoolScoreJob.perform_later(self)
|
||||
end
|
||||
|
||||
def calculate_score_raw
|
||||
newScore = total_points_scored_by_wrestlers - total_points_deducted
|
||||
|
||||
@@ -14,16 +14,6 @@ class Tournament < ApplicationRecord
|
||||
|
||||
attr_accessor :import_text
|
||||
|
||||
def deferred_jobs
|
||||
Delayed::Job.where(job_owner_id: self.id)
|
||||
end
|
||||
|
||||
def clear_errored_deferred_jobs
|
||||
Delayed::Job.where(job_owner_id: self.id, last_error: ! nil).each do |job|
|
||||
job.destroy
|
||||
end
|
||||
end
|
||||
|
||||
def self.search_date_name(pattern)
|
||||
if pattern.blank? # blank? covers both nil and empty string
|
||||
all
|
||||
@@ -87,11 +77,8 @@ class Tournament < ApplicationRecord
|
||||
end
|
||||
|
||||
def total_rounds
|
||||
if self.matches.count > 0
|
||||
self.matches.sort_by{|m| m.round}.last.round
|
||||
else
|
||||
0
|
||||
end
|
||||
# Assuming this is line 147 that's causing the error
|
||||
matches.maximum(:round) || 0 # Return 0 if no matches or max round is nil
|
||||
end
|
||||
|
||||
def assign_mats(mats_to_assign)
|
||||
@@ -259,5 +246,26 @@ class Tournament < ApplicationRecord
|
||||
def create_backup()
|
||||
TournamentBackupService.new(self, "Manual backup").create_backup
|
||||
end
|
||||
|
||||
def confirm_all_weights_have_original_seeds
|
||||
error_string = wrestlers_with_higher_seed_than_bracket_size_error
|
||||
error_string += wrestlers_with_duplicate_original_seed_error
|
||||
error_string += wrestlers_with_out_of_order_seed_error
|
||||
|
||||
return error_string.blank?
|
||||
end
|
||||
|
||||
def confirm_each_weight_class_has_correct_number_of_wrestlers
|
||||
error_string = pool_to_bracket_number_of_wrestlers_error
|
||||
error_string += modified_sixteen_man_number_of_wrestlers_error
|
||||
error_string += double_elim_number_of_wrestlers_error
|
||||
|
||||
return error_string.blank?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def connection_adapter
|
||||
ActiveRecord::Base.connection.adapter_name
|
||||
end
|
||||
end
|
||||
@@ -1,12 +1,56 @@
|
||||
class User < ApplicationRecord
|
||||
attr_accessor :reset_token
|
||||
|
||||
# Include default devise modules. Others available are:
|
||||
# :confirmable, :lockable, :timeoutable and :omniauthable
|
||||
has_many :tournaments
|
||||
has_many :delegated_tournament_permissions, class_name: "TournamentDelegate"
|
||||
has_many :delegated_school_permissions, class_name: "SchoolDelegate"
|
||||
|
||||
devise :database_authenticatable, :registerable,
|
||||
:recoverable, :rememberable, :trackable, :validatable
|
||||
# Replace Devise with has_secure_password
|
||||
has_secure_password
|
||||
|
||||
# Add validations that were handled by Devise
|
||||
validates :email, presence: true, uniqueness: { case_sensitive: false }
|
||||
validates :password, length: { minimum: 6 }, allow_nil: true
|
||||
|
||||
# These are the Devise modules we were using:
|
||||
# devise :database_authenticatable, :registerable,
|
||||
# :recoverable, :rememberable, :trackable, :validatable
|
||||
|
||||
# Returns the hash digest of the given string
|
||||
def self.digest(string)
|
||||
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
|
||||
BCrypt::Password.create(string, cost: cost)
|
||||
end
|
||||
|
||||
# Returns a random token
|
||||
def self.new_token
|
||||
SecureRandom.urlsafe_base64
|
||||
end
|
||||
|
||||
# Sets the password reset attributes
|
||||
def create_reset_digest
|
||||
self.reset_token = User.new_token
|
||||
update_columns(reset_digest: User.digest(reset_token), reset_sent_at: Time.zone.now)
|
||||
end
|
||||
|
||||
# Sends password reset email
|
||||
def send_password_reset_email
|
||||
UserMailer.password_reset(self).deliver_now
|
||||
end
|
||||
|
||||
# Returns true if a password reset has expired
|
||||
def password_reset_expired?
|
||||
reset_sent_at < 2.hours.ago
|
||||
end
|
||||
|
||||
# Returns true if the given token matches the digest
|
||||
def authenticated?(attribute, token)
|
||||
digest = send("#{attribute}_digest")
|
||||
return false if digest.nil?
|
||||
BCrypt::Password.new(digest).is_password?(token)
|
||||
end
|
||||
|
||||
def delegated_tournaments
|
||||
tournaments_delegated = []
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
class AdvanceWrestler
|
||||
def initialize( wrestler, last_match )
|
||||
def initialize(wrestler, last_match)
|
||||
@wrestler = wrestler
|
||||
@tournament = @wrestler.tournament
|
||||
@last_match = last_match
|
||||
end
|
||||
|
||||
def advance
|
||||
if Rails.env.production?
|
||||
self.delay(:job_owner_id => @tournament.id, :job_owner_type => "Advance wrestler #{@wrestler.name} in the bracket").advance_raw
|
||||
else
|
||||
advance_raw
|
||||
end
|
||||
# Use perform_later which will execute based on centralized adapter config
|
||||
# This will be converted to inline execution in test environment by ActiveJob
|
||||
AdvanceWrestlerJob.perform_later(@wrestler, @last_match)
|
||||
end
|
||||
|
||||
def advance_raw
|
||||
@tournament.clear_errored_deferred_jobs
|
||||
|
||||
if @last_match && @last_match.finished?
|
||||
pool_to_bracket_advancement if @tournament.tournament_type == "Pool to bracket"
|
||||
ModifiedDoubleEliminationAdvance.new(@wrestler, @last_match).bracket_advancement if @tournament.tournament_type.include? "Modified 16 Man Double Elimination"
|
||||
|
||||
@@ -4,11 +4,8 @@ class GenerateTournamentMatches
|
||||
end
|
||||
|
||||
def generate
|
||||
if Rails.env.production?
|
||||
self.delay(:job_owner_id => @tournament.id, :job_owner_type => "Generate matches for all weights").generate_raw
|
||||
else
|
||||
self.generate_raw
|
||||
end
|
||||
# Use perform_later which will execute based on centralized adapter config
|
||||
GenerateTournamentMatchesJob.perform_later(@tournament)
|
||||
end
|
||||
|
||||
def generate_raw
|
||||
|
||||
@@ -5,11 +5,8 @@ class TournamentBackupService
|
||||
end
|
||||
|
||||
def create_backup
|
||||
if Rails.env.production?
|
||||
self.delay(:job_owner_id => @tournament.id, :job_owner_type => "Create a backup").create_backup_raw
|
||||
else
|
||||
self.create_backup_raw
|
||||
end
|
||||
# Use perform_later which will execute based on centralized adapter config
|
||||
TournamentBackupJob.perform_later(@tournament, @reason)
|
||||
end
|
||||
|
||||
def create_backup_raw
|
||||
|
||||
@@ -1,19 +1,24 @@
|
||||
class WrestlingdevImporter
|
||||
|
||||
##### Note, the json contains id's for each row in the tables as well as its associations
|
||||
##### this ignores those ids and uses this tournament id and then looks up associations based on name
|
||||
##### and this tournament id
|
||||
def initialize(tournament, backup)
|
||||
attr_accessor :import_data
|
||||
|
||||
# Support both parameter styles for backward compatibility
|
||||
# Old: initialize(tournament, backup)
|
||||
# New: initialize(tournament) with import_data setter
|
||||
def initialize(tournament, backup = nil)
|
||||
@tournament = tournament
|
||||
@import_data = JSON.parse(Base64.decode64(backup.backup_data))
|
||||
|
||||
# Handle the old style where backup was passed directly
|
||||
if backup.present?
|
||||
@import_data = JSON.parse(Base64.decode64(backup.backup_data)) rescue nil
|
||||
end
|
||||
end
|
||||
|
||||
def import
|
||||
if Rails.env.production?
|
||||
self.delay(job_owner_id: @tournament.id, job_owner_type: "Importing a backup").import_raw
|
||||
else
|
||||
import_raw
|
||||
end
|
||||
# Use perform_later which will execute based on centralized adapter config
|
||||
WrestlingdevImportJob.perform_later(@tournament, @import_data)
|
||||
end
|
||||
|
||||
def import_raw
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
<h2>Resend confirmation instructions</h2>
|
||||
|
||||
<%= form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f| %>
|
||||
<%= devise_error_messages! %>
|
||||
|
||||
<div><%= f.label :email %><br />
|
||||
<%= f.email_field :email, :autofocus => true %></div>
|
||||
|
||||
<div><%= f.submit "Resend confirmation instructions" %></div>
|
||||
<% end %>
|
||||
|
||||
<%= render "devise/shared/links" %>
|
||||
@@ -1,5 +0,0 @@
|
||||
<p>Welcome <%= @email %>!</p>
|
||||
|
||||
<p>You can confirm your account email through the link below:</p>
|
||||
|
||||
<p><%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @token) %></p>
|
||||
@@ -1,8 +0,0 @@
|
||||
<p>Hello <%= @resource.email %>!</p>
|
||||
|
||||
<p>Someone has requested a link to change your password. You can do this through the link below.</p>
|
||||
|
||||
<p><%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @token) %></p>
|
||||
|
||||
<p>If you didn't request this, please ignore this email.</p>
|
||||
<p>Your password won't change until you access the link above and create a new one.</p>
|
||||
@@ -1,7 +0,0 @@
|
||||
<p>Hello <%= @resource.email %>!</p>
|
||||
|
||||
<p>Your account has been locked due to an excessive number of unsuccessful sign in attempts.</p>
|
||||
|
||||
<p>Click the link below to unlock your account:</p>
|
||||
|
||||
<p><%= link_to 'Unlock my account', unlock_url(@resource, :unlock_token => @token) %></p>
|
||||
@@ -1,16 +0,0 @@
|
||||
<h2>Change your password</h2>
|
||||
|
||||
<%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put }) do |f| %>
|
||||
<%= devise_error_messages! %>
|
||||
<%= f.hidden_field :reset_password_token %>
|
||||
|
||||
<div><%= f.label :password, "New password" %><br />
|
||||
<%= f.password_field :password, :autofocus => true %></div>
|
||||
|
||||
<div><%= f.label :password_confirmation, "Confirm new password" %><br />
|
||||
<%= f.password_field :password_confirmation %></div>
|
||||
|
||||
<div><%= f.submit "Change my password", :class=>"btn btn-success"%></div>
|
||||
<% end %>
|
||||
|
||||
<%= render "devise/shared/links" %>
|
||||
@@ -1,13 +0,0 @@
|
||||
<h2>Forgot your password?</h2>
|
||||
|
||||
<%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| %>
|
||||
<%= devise_error_messages! %>
|
||||
|
||||
<div><%= f.label :email %><br />
|
||||
<%= f.email_field :email, :autofocus => true %></div>
|
||||
<br>
|
||||
<div><%= f.submit "Send me reset password instructions",:class=>"btn btn-success" %></div>
|
||||
<% end %>
|
||||
<br>
|
||||
<br>
|
||||
<%= render "devise/shared/links" %>
|
||||
@@ -1,29 +0,0 @@
|
||||
<h2>Edit <%= resource_name.to_s.humanize %></h2>
|
||||
|
||||
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
|
||||
<%= devise_error_messages! %>
|
||||
|
||||
<div><%= f.label :email %><br />
|
||||
<%= f.email_field :email, :autofocus => true %></div>
|
||||
|
||||
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
|
||||
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
|
||||
<% end %>
|
||||
|
||||
<div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
|
||||
<%= f.password_field :password, :autocomplete => "off" %></div>
|
||||
|
||||
<div><%= f.label :password_confirmation %><br />
|
||||
<%= f.password_field :password_confirmation %></div>
|
||||
|
||||
<div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
|
||||
<%= f.password_field :current_password %></div>
|
||||
<br>
|
||||
<div><%= f.submit "Update",:class=>"btn btn-success" %></div>
|
||||
<% end %>
|
||||
|
||||
<h3>Cancel my account</h3>
|
||||
|
||||
<p>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), :data => { :confirm => "Are you sure?" }, :method => :delete, :class=>"btn btn-danger" %></p>
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<h2>Sign up</h2>
|
||||
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
|
||||
<%= devise_error_messages! %>
|
||||
|
||||
<div><%= f.label :email %><br />
|
||||
<%= f.email_field :email, :autofocus => true %></div>
|
||||
|
||||
<div><%= f.label :password %><br />
|
||||
<%= f.password_field :password %></div>
|
||||
|
||||
<div><%= f.label :password_confirmation %><br />
|
||||
<%= f.password_field :password_confirmation %></div>
|
||||
|
||||
<div><%= f.submit "Sign up" %></div>
|
||||
<% end %>
|
||||
|
||||
<%= render "devise/shared/links" %>
|
||||
@@ -1,18 +0,0 @@
|
||||
<h2 class="form-signin-heading">Sign in</h2>
|
||||
|
||||
<%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
|
||||
<div><%= f.label :email ,:class=>"sr-only"%><br />
|
||||
<%= f.email_field :email, :autofocus => true,:class=>"form-control",:placeholder=>"Email Address" %></div>
|
||||
|
||||
<div><%= f.label :password,:class=>"sr-only" %><br />
|
||||
<%= f.password_field :password,:class=>"form-control",:placeholder=>"Password" %></div>
|
||||
|
||||
<% if devise_mapping.rememberable? -%>
|
||||
<div class="checkbox"><%= f.check_box :remember_me %> <%= f.label :remember_me %></div>
|
||||
<% end -%>
|
||||
|
||||
<div><%= f.submit "Sign in" ,:class=>"btn btn-lg btn-primary btn-block" %></div>
|
||||
<% end %>
|
||||
<br>
|
||||
<br>
|
||||
<%= render "devise/shared/links" %>
|
||||
@@ -1,25 +0,0 @@
|
||||
<%- if controller_name != 'sessions' %>
|
||||
<%= link_to "Sign in", new_session_path(resource_name) %><br />
|
||||
<% end -%>
|
||||
|
||||
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
|
||||
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
|
||||
<% end -%>
|
||||
|
||||
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
|
||||
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
|
||||
<% end -%>
|
||||
|
||||
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
|
||||
<%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
|
||||
<% end -%>
|
||||
|
||||
<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
|
||||
<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
|
||||
<% end -%>
|
||||
|
||||
<%- if devise_mapping.omniauthable? %>
|
||||
<%- resource_class.omniauth_providers.each do |provider| %>
|
||||
<%= link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider) %><br />
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
@@ -1,12 +0,0 @@
|
||||
<h2>Resend unlock instructions</h2>
|
||||
|
||||
<%= form_for(resource, :as => resource_name, :url => unlock_path(resource_name), :html => { :method => :post }) do |f| %>
|
||||
<%= devise_error_messages! %>
|
||||
|
||||
<div><%= f.label :email %><br />
|
||||
<%= f.email_field :email, :autofocus => true %></div>
|
||||
|
||||
<div><%= f.submit "Resend unlock instructions" %></div>
|
||||
<% end %>
|
||||
|
||||
<%= render "devise/shared/links" %>
|
||||
@@ -19,13 +19,13 @@
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#"><%= current_user.email %>
|
||||
<span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><%=link_to "Log out", destroy_user_session_url ,:method => 'delete' %></li>
|
||||
<li><%=link_to "Edit user", edit_user_registration_path %></li>
|
||||
<li><%=link_to "My tournaments and schools","/static_pages/my_tournaments" %></li>
|
||||
<li><%= link_to "Log out", logout_path, method: :delete %></li>
|
||||
<li><%= link_to "Edit profile", edit_user_path(current_user) %></li>
|
||||
<li><%= link_to "My tournaments and schools", "/static_pages/my_tournaments" %></li>
|
||||
</ul>
|
||||
</li>
|
||||
<% else %>
|
||||
<li><%= link_to "Log In" , new_user_session_path %></li>
|
||||
<li><%= link_to "Log In", login_path %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
|
||||
34
app/views/password_resets/edit.html.erb
Normal file
34
app/views/password_resets/edit.html.erb
Normal file
@@ -0,0 +1,34 @@
|
||||
<h1>Reset password</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<%= form_with(model: @user, url: password_reset_path(params[:id]), local: true) do |f| %>
|
||||
<% if @user.errors.any? %>
|
||||
<div class="error_explanation">
|
||||
<div class="alert alert-danger">
|
||||
The form contains <%= pluralize(@user.errors.count, "error") %>.
|
||||
</div>
|
||||
<ul>
|
||||
<% @user.errors.full_messages.each do |msg| %>
|
||||
<li><%= msg %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= hidden_field_tag :email, @user.email %>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label :password %>
|
||||
<%= f.password_field :password, class: 'form-control' %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label :password_confirmation, "Confirmation" %>
|
||||
<%= f.password_field :password_confirmation, class: 'form-control' %>
|
||||
</div>
|
||||
|
||||
<%= f.submit "Update password", class: "btn btn-primary" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
14
app/views/password_resets/new.html.erb
Normal file
14
app/views/password_resets/new.html.erb
Normal file
@@ -0,0 +1,14 @@
|
||||
<h1>Forgot password</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<%= form_with(url: password_resets_path, scope: :password_reset, local: true) do |f| %>
|
||||
<div class="form-group">
|
||||
<%= f.label :email %>
|
||||
<%= f.email_field :email, class: 'form-control' %>
|
||||
</div>
|
||||
|
||||
<%= f.submit "Submit", class: "btn btn-primary" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
21
app/views/sessions/new.html.erb
Normal file
21
app/views/sessions/new.html.erb
Normal file
@@ -0,0 +1,21 @@
|
||||
<h1>Log in</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<%= form_with(url: login_path, scope: :session, local: true) do |f| %>
|
||||
<div class="form-group">
|
||||
<%= f.label :email %>
|
||||
<%= f.email_field :email, class: 'form-control' %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label :password %>
|
||||
<%= f.password_field :password, class: 'form-control' %>
|
||||
</div>
|
||||
|
||||
<%= f.submit "Log in", class: "btn btn-primary" %>
|
||||
<% end %>
|
||||
|
||||
<p>New user? <%= link_to "Sign up now!", signup_path %></p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,6 +1,14 @@
|
||||
<h3>
|
||||
Info
|
||||
</h3>
|
||||
|
||||
<% if (can? :manage, @tournament) && @tournament.curently_generating_matches == 1 %>
|
||||
<div class="alert alert-info">
|
||||
<strong>Match Generation In Progress</strong>
|
||||
<p>Tournament bracket generation is currently running. Please refresh the page to check progress.</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<p>
|
||||
<strong>Address:</strong>
|
||||
<%= @tournament.address %>
|
||||
@@ -118,34 +126,4 @@
|
||||
</tbody>
|
||||
</table>
|
||||
<% end %>
|
||||
<% if can? :manage, @tournament %>
|
||||
<br><br>
|
||||
<h3>Background Jobs</h3>
|
||||
<p>This is a list of queued or running background jobs. Match generation, bracket advancement, team score calculation, etc.</p>
|
||||
<table class="table table-hover table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name of Job</th>
|
||||
<th>Job Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<% @tournament.deferred_jobs.each do |job| %>
|
||||
<tr>
|
||||
<td><%= job.job_owner_type %></td>
|
||||
<td>
|
||||
<% if job.locked_at %>
|
||||
Running
|
||||
<% elsif job.last_error %>
|
||||
Error
|
||||
<% elsif job.attempts == 0 and !job.locked_at %>
|
||||
Pending
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<% end %>
|
||||
<br><br>
|
||||
|
||||
12
app/views/user_mailer/password_reset.html.erb
Normal file
12
app/views/user_mailer/password_reset.html.erb
Normal file
@@ -0,0 +1,12 @@
|
||||
<h1>Password reset</h1>
|
||||
|
||||
<p>To reset your password click the link below:</p>
|
||||
|
||||
<%= link_to "Reset password", edit_password_reset_url(@user.reset_token, email: @user.email) %>
|
||||
|
||||
<p>This link will expire in two hours.</p>
|
||||
|
||||
<p>
|
||||
If you did not request your password to be reset, please ignore this email and
|
||||
your password will stay as it is.
|
||||
</p>
|
||||
8
app/views/user_mailer/password_reset.text.erb
Normal file
8
app/views/user_mailer/password_reset.text.erb
Normal file
@@ -0,0 +1,8 @@
|
||||
To reset your password click the link below:
|
||||
|
||||
<%= edit_password_reset_url(@user.reset_token, email: @user.email) %>
|
||||
|
||||
This link will expire in two hours.
|
||||
|
||||
If you did not request your password to be reset, please ignore this email and
|
||||
your password will stay as it is.
|
||||
38
app/views/users/edit.html.erb
Normal file
38
app/views/users/edit.html.erb
Normal file
@@ -0,0 +1,38 @@
|
||||
<h1>Edit profile</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<%= form_with(model: @user, local: true) do |f| %>
|
||||
<% if @user.errors.any? %>
|
||||
<div class="error_explanation">
|
||||
<div class="alert alert-danger">
|
||||
The form contains <%= pluralize(@user.errors.count, "error") %>.
|
||||
</div>
|
||||
<ul>
|
||||
<% @user.errors.full_messages.each do |msg| %>
|
||||
<li><%= msg %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label :email %>
|
||||
<%= f.email_field :email, class: 'form-control' %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label :password %>
|
||||
<%= f.password_field :password, class: 'form-control' %>
|
||||
<small class="text-muted">Leave blank if you don't want to change it</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label :password_confirmation, "Confirmation" %>
|
||||
<%= f.password_field :password_confirmation, class: 'form-control' %>
|
||||
</div>
|
||||
|
||||
<%= f.submit "Save changes", class: "btn btn-primary" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
39
app/views/users/new.html.erb
Normal file
39
app/views/users/new.html.erb
Normal file
@@ -0,0 +1,39 @@
|
||||
<h1>Sign up</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<%= form_with(model: @user, url: signup_path, local: true) do |f| %>
|
||||
<% if @user.errors.any? %>
|
||||
<div class="error_explanation">
|
||||
<div class="alert alert-danger">
|
||||
The form contains <%= pluralize(@user.errors.count, "error") %>.
|
||||
</div>
|
||||
<ul>
|
||||
<% @user.errors.full_messages.each do |msg| %>
|
||||
<li><%= msg %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label :email %>
|
||||
<%= f.email_field :email, class: 'form-control' %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label :password %>
|
||||
<%= f.password_field :password, class: 'form-control' %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label :password_confirmation, "Confirmation" %>
|
||||
<%= f.password_field :password_confirmation, class: 'form-control' %>
|
||||
</div>
|
||||
|
||||
<%= f.submit "Create account", class: "btn btn-primary" %>
|
||||
<% end %>
|
||||
|
||||
<p>Already have an account? <%= link_to "Log in", login_path %></p>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user