├── log └── .keep ├── storage └── .keep ├── tmp └── .keep ├── vendor └── .keep ├── lib ├── assets │ └── .keep └── tasks │ ├── .keep │ ├── reset_participant_counter_cache.rake │ ├── pilot_init_csv.rake │ ├── export_user_info.rake │ ├── assign_league_promotions.rake │ ├── set_match_winner_type.rake │ ├── redo_bcp_matches.rake │ ├── export_winners.rake │ ├── generate_league_seeding_data.rake │ ├── set_legacy_league_promotion_status.rake │ ├── load_matches_from_lj.rake │ ├── generate_season_seven_matches.rake │ ├── generate_season_seven_seeding_data.rake │ ├── load_participants_from_list_juggler.rake │ ├── calculate_league_scores.rake │ ├── generate_league_matches_s1100.rake │ ├── generate_league_matches_s1000.rake │ ├── update_xwing_data.rake │ └── generate_league_matches.rake ├── test ├── helpers │ └── .keep ├── mailers │ └── .keep ├── models │ ├── .keep │ ├── match_test.rb │ ├── pilot_test.rb │ ├── round_test.rb │ ├── ship_test.rb │ ├── user_test.rb │ ├── address_test.rb │ ├── division_test.rb │ ├── faction_test.rb │ ├── format_test.rb │ ├── season_test.rb │ ├── upgrade_test.rb │ ├── version_test.rb │ ├── league_user_test.rb │ ├── roundtype_test.rb │ ├── tournament_test.rb │ ├── league_match_test.rb │ ├── league_signup_test.rb │ ├── participant_test.rb │ ├── tournament_type_test.rb │ ├── league_match_state_test.rb │ ├── league_participant_test.rb │ └── season_seven_survey_test.rb ├── system │ ├── .keep │ ├── tournaments_test.rb │ ├── participants_test.rb │ ├── league_signups_test.rb │ └── season_seven_surveys_test.rb ├── controllers │ ├── .keep │ ├── me_controller_test.rb │ ├── home_controller_test.rb │ ├── seasons_controller_test.rb │ ├── league_participant_controller_test.rb │ ├── tournaments_controller_test.rb │ ├── participants_controller_test.rb │ ├── league_signups_controller_test.rb │ └── season_seven_surveys_controller_test.rb ├── fixtures │ ├── .keep │ ├── files │ │ └── .keep │ ├── roundtypes.yml │ ├── rounds.yml │ ├── users.yml │ ├── matches.yml │ ├── pilots.yml │ ├── ships.yml │ ├── addresses.yml │ ├── divisions.yml │ ├── factions.yml │ ├── formats.yml │ ├── seasons.yml │ ├── tournaments.yml │ ├── upgrades.yml │ ├── versions.yml │ ├── league_matches.yml │ ├── league_signups.yml │ ├── tournament_types.yml │ ├── league_match_states.yml │ ├── league_participants.yml │ ├── season_seven_surveys.yml │ └── participants.yml ├── integration │ └── .keep ├── application_system_test_case.rb └── test_helper.rb ├── .ruby-version ├── app ├── assets │ ├── images │ │ ├── .keep │ │ └── logo-xw-lrg.png │ ├── javascripts │ │ ├── channels │ │ │ └── .keep │ │ ├── home.coffee │ │ ├── me.coffee │ │ ├── seasons.coffee │ │ ├── league_signups.coffee │ │ ├── participants.coffee │ │ ├── league_participant.coffee │ │ ├── season_seven_surveys.coffee │ │ ├── google_analytics.js.erb │ │ ├── cable.js │ │ └── application.js │ ├── config │ │ └── manifest.js │ └── stylesheets │ │ ├── me.scss │ │ ├── home.scss │ │ ├── seasons.scss │ │ ├── tournaments.scss │ │ ├── participants.scss │ │ ├── league_signups.scss │ │ ├── league_participant.scss │ │ ├── season_seven_surveys.scss │ │ ├── application.scss │ │ ├── fonts │ │ └── LICENSE.txt │ │ └── scaffolds.scss ├── models │ ├── concerns │ │ └── .keep │ ├── upgrade.rb │ ├── roundtype.rb │ ├── league_match.rb │ ├── league_match_state.rb │ ├── address.rb │ ├── faction.rb │ ├── version.rb │ ├── pilot.rb │ ├── tournament_type.rb │ ├── application_record.rb │ ├── ship.rb │ ├── season_seven_survey.rb │ ├── league_signup.rb │ ├── identity.rb │ ├── format.rb │ ├── division.rb │ ├── tournaments │ │ └── forms.rb │ ├── league_participant.rb │ ├── user.rb │ ├── round.rb │ ├── match.rb │ └── season.rb ├── controllers │ ├── concerns │ │ └── .keep │ ├── home_controller.rb │ ├── divisions_controller.rb │ ├── api │ │ └── v1 │ │ │ ├── seasons_controller.rb │ │ │ ├── base_controller.rb │ │ │ └── tournaments_controller.rb │ ├── league_participant_controller.rb │ ├── application_controller.rb │ ├── seasons_controller.rb │ ├── me_controller.rb │ ├── sessions_controller.rb │ └── league_controller.rb ├── helpers │ ├── me_helper.rb │ ├── home_helper.rb │ ├── seasons_helper.rb │ ├── participants_helper.rb │ ├── tournaments_helper.rb │ ├── league_signups_helper.rb │ ├── league_participant_helper.rb │ ├── season_seven_surveys_helper.rb │ └── application_helper.rb ├── views │ ├── home │ │ ├── show.html.erb │ │ └── about.html.erb │ ├── layouts │ │ ├── mailer.text.erb │ │ ├── mailer.html.erb │ │ ├── _google_analytics.html.erb │ │ ├── _navbar.html.erb │ │ └── application.html.erb │ ├── rounds │ │ ├── show.json.jbuilder │ │ ├── index.json.jbuilder │ │ ├── _round.json.jbuilder │ │ ├── edit.html.erb │ │ ├── new.html.erb │ │ ├── index.html.erb │ │ ├── _form.html.erb │ │ └── show.html.erb │ ├── matches │ │ ├── show.json.jbuilder │ │ ├── index.json.jbuilder │ │ ├── _match.json.jbuilder │ │ ├── new.html.erb │ │ ├── show.html.erb │ │ ├── edit.html.erb │ │ ├── index.html.erb │ │ ├── _form.html.erb │ │ └── _leagueform.erb │ ├── tournaments │ │ ├── show.json.jbuilder │ │ ├── index.json.jbuilder │ │ ├── _tournament.json.jbuilder │ │ ├── new.html.erb │ │ ├── edit.html.erb │ │ ├── feed.builder │ │ ├── index.html.erb │ │ ├── _filter.html.erb │ │ └── _form.html.erb │ ├── participants │ │ ├── show.json.jbuilder │ │ ├── index.json.jbuilder │ │ ├── show.html.erb │ │ ├── edit.html.erb │ │ ├── new.html.erb │ │ ├── _participant.json.jbuilder │ │ ├── index.html.erb │ │ └── _form.html.erb │ ├── league_signups │ │ ├── show.json.jbuilder │ │ ├── index.json.jbuilder │ │ ├── new.html.erb │ │ ├── _league_signup.json.jbuilder │ │ ├── show.html.erb │ │ ├── edit.html.erb │ │ ├── index.html.erb │ │ └── _form.html.erb │ ├── season_seven_surveys │ │ ├── show.json.jbuilder │ │ ├── index.json.jbuilder │ │ ├── show.html.erb │ │ ├── _season_seven_survey.json.jbuilder │ │ ├── new.html.erb │ │ ├── edit.html.erb │ │ ├── index.html.erb │ │ └── _form.html.erb │ ├── me │ │ ├── home.html.erb │ │ └── _address_form.html.erb │ ├── league │ │ ├── register.html.erb │ │ └── interdivisional.html.erb │ ├── seasons │ │ ├── index.html.erb │ │ └── show.html.erb │ └── divisions │ │ └── show.html.erb ├── jobs │ └── application_job.rb ├── channels │ └── application_cable │ │ ├── channel.rb │ │ └── connection.rb ├── mailers │ └── application_mailer.rb └── serializers │ └── api │ └── v1 │ ├── season_serializer.rb │ ├── league_participant_serializer.rb │ ├── season_details_serializer.rb │ ├── division_serializer.rb │ ├── base_serializer.rb │ ├── match_serializer.rb │ ├── tournament_serializer.rb │ ├── participant_serializer.rb │ ├── round_serializer.rb │ ├── tournament_details_serializer.rb │ └── error_serializer.rb ├── .gitattributes ├── public ├── apple-touch-icon-precomposed.png ├── favicon.ico ├── favicon-16x16.png ├── favicon-32x32.png ├── logo-xw-lrg.png ├── mstile-150x150.png ├── apple-touch-icon.png ├── robots.txt ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── fonts │ ├── xwing-miniatures.ttf │ ├── xwing-miniatures-ships.ttf │ └── LICENSE.txt ├── browserconfig.xml ├── site.webmanifest ├── s12.csv ├── 500.html ├── 422.html └── 404.html ├── Procfile ├── bin ├── rake ├── bundle ├── rails ├── yarn ├── update └── setup ├── .gitmodules ├── package.json ├── config ├── environment.rb ├── initializers │ ├── cors.rb │ ├── mime_types.rb │ ├── application_controller_renderer.rb │ ├── cookies_serializer.rb │ ├── filter_parameter_logging.rb │ ├── omniauth.rb │ ├── permissions_policy.rb │ ├── wrap_parameters.rb │ ├── backtrace_silencers.rb │ ├── assets.rb │ ├── inflections.rb │ └── content_security_policy.rb ├── boot.rb ├── cable.yml ├── credentials.yml.enc ├── database.yml ├── application.rb ├── application.yml.sample ├── locales │ └── en.yml ├── storage.yml ├── puma.rb ├── routes.rb └── environments │ └── test.rb ├── db └── migrate │ ├── 20190203012013_change_ship_xws.rb │ ├── 20220309013410_add_sort_to_format.rb │ ├── 20190327185131_add_loss_on_league_participants.rb │ ├── 20181007004220_create_versions.rb │ ├── 20181007004236_create_formats.rb │ ├── 20181121020916_add_participant_counter_cache.rb │ ├── 20190217023821_add_promotion_tracker_to_league_participants.rb │ ├── 20190825180651_add_user_to_addresses.rb │ ├── 20190307214001_add_mov_to_l_participants.rb │ ├── 20181007031555_create_tournament_types.rb │ ├── 20181006204755_create_factions.rb │ ├── 20181207035750_create_league_match_states.rb │ ├── 20181109003516_create_divisions.rb │ ├── 20190227125129_add_division_letter.rb │ ├── 20190108185935_create_roundtypes.rb │ ├── 20190109233824_create_rounds.rb │ ├── 20190106202527_create_identities.rb │ ├── 20181010002750_create_ships.rb │ ├── 20181004023419_create_users.rb │ ├── 20181109003508_create_seasons.rb │ ├── 20190616195742_create_league_signups.rb │ ├── 20181108184836_create_league_participants.rb │ ├── 20181113014608_change_user_table.rb │ ├── 20220404204413_add_items_to_tournaments.rb │ ├── 20181010003159_create_upgrades.rb │ ├── 20181009234406_create_pilots.rb │ ├── 20181108030503_create_addresses.rb │ ├── 20181002190843_create_tournaments.rb │ ├── 20181221025059_create_season_seven_surveys.rb │ ├── 20181005004307_create_participants.rb │ ├── 20210321231956_create_active_storage_variant_records.active_storage.rb │ ├── 20181204013957_create_league_matches.rb │ ├── 20210321231955_add_service_name_to_active_storage_blobs.active_storage.rb │ ├── 20190111224922_create_matches.rb │ └── 20190218190306_create_active_storage_tables.active_storage.rb ├── config.ru ├── Rakefile ├── .rubocop.yml ├── .gitignore ├── LICENSE.txt └── README.md /log/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /storage/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tmp/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/helpers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/mailers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/models/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/system/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 3.1.3 2 | -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/controllers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/integration/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/files/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/javascripts/channels/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/helpers/me_helper.rb: -------------------------------------------------------------------------------- 1 | module MeHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/views/home/show.html.erb: -------------------------------------------------------------------------------- 1 | Welcome 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /app/helpers/home_helper.rb: -------------------------------------------------------------------------------- 1 | module HomeHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/seasons_helper.rb: -------------------------------------------------------------------------------- 1 | module SeasonsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/models/upgrade.rb: -------------------------------------------------------------------------------- 1 | class Upgrade < ApplicationRecord 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/participants_helper.rb: -------------------------------------------------------------------------------- 1 | module ParticipantsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/tournaments_helper.rb: -------------------------------------------------------------------------------- 1 | module TournamentsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/models/roundtype.rb: -------------------------------------------------------------------------------- 1 | class Roundtype < ApplicationRecord 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/league_signups_helper.rb: -------------------------------------------------------------------------------- 1 | module LeagueSignupsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | end 3 | -------------------------------------------------------------------------------- /app/models/league_match.rb: -------------------------------------------------------------------------------- 1 | class LeagueMatch < ApplicationRecord 2 | end 3 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: bundle exec puma -t 5:5 -p ${PORT:-3000} -e ${RACK_ENV:-development} -------------------------------------------------------------------------------- /app/helpers/league_participant_helper.rb: -------------------------------------------------------------------------------- 1 | module LeagueParticipantHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/views/rounds/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! "rounds/round", round: @round 2 | -------------------------------------------------------------------------------- /app/helpers/season_seven_surveys_helper.rb: -------------------------------------------------------------------------------- 1 | module SeasonSevenSurveysHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/models/league_match_state.rb: -------------------------------------------------------------------------------- 1 | class LeagueMatchState < ApplicationRecord 2 | end 3 | -------------------------------------------------------------------------------- /app/views/matches/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! "matches/match", match: @match 2 | -------------------------------------------------------------------------------- /app/models/address.rb: -------------------------------------------------------------------------------- 1 | class Address < ApplicationRecord 2 | belongs_to :user 3 | end 4 | -------------------------------------------------------------------------------- /app/models/faction.rb: -------------------------------------------------------------------------------- 1 | class Faction < ApplicationRecord 2 | has_many :ships 3 | end 4 | -------------------------------------------------------------------------------- /app/models/version.rb: -------------------------------------------------------------------------------- 1 | class Version < ApplicationRecord 2 | has_many :tournaments 3 | end 4 | -------------------------------------------------------------------------------- /app/views/rounds/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @rounds, partial: 'rounds/round', as: :round 2 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexRaubach/ListFortress/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /app/models/pilot.rb: -------------------------------------------------------------------------------- 1 | class Pilot < ApplicationRecord 2 | belongs_to :ships, optional: true 3 | end 4 | -------------------------------------------------------------------------------- /app/views/matches/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @matches, partial: 'matches/match', as: :match 2 | -------------------------------------------------------------------------------- /app/views/tournaments/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! "tournaments/tournament", tournament: @tournament 2 | -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexRaubach/ListFortress/HEAD/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexRaubach/ListFortress/HEAD/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/logo-xw-lrg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexRaubach/ListFortress/HEAD/public/logo-xw-lrg.png -------------------------------------------------------------------------------- /app/models/tournament_type.rb: -------------------------------------------------------------------------------- 1 | class TournamentType < ApplicationRecord 2 | has_many :tournaments 3 | end 4 | -------------------------------------------------------------------------------- /app/views/participants/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! "participants/participant", participant: @participant 2 | -------------------------------------------------------------------------------- /public/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexRaubach/ListFortress/HEAD/public/mstile-150x150.png -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative "../config/boot" 3 | require "rake" 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexRaubach/ListFortress/HEAD/public/apple-touch-icon.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "xwing-data2"] 2 | path = xwing-data2 3 | url = https://github.com/guidokessels/xwing-data2 4 | -------------------------------------------------------------------------------- /app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /app/views/league_signups/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! "league_signups/league_signup", league_signup: @league_signup 2 | -------------------------------------------------------------------------------- /app/views/tournaments/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @tournaments, partial: 'tournaments/tournament', as: :tournament 2 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /app/assets/images/logo-xw-lrg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexRaubach/ListFortress/HEAD/app/assets/images/logo-xw-lrg.png -------------------------------------------------------------------------------- /app/models/ship.rb: -------------------------------------------------------------------------------- 1 | class Ship < ApplicationRecord 2 | has_many :pilots 3 | belongs_to :factions, optional: true 4 | end 5 | -------------------------------------------------------------------------------- /app/views/participants/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @participants, partial: 'participants/participant', as: :participant 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "listfortress", 3 | "private": true, 4 | "dependencies": {}, 5 | "license": "MIT" 6 | } 7 | -------------------------------------------------------------------------------- /public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexRaubach/ListFortress/HEAD/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexRaubach/ListFortress/HEAD/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/fonts/xwing-miniatures.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexRaubach/ListFortress/HEAD/public/fonts/xwing-miniatures.ttf -------------------------------------------------------------------------------- /app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/views/league_signups/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @league_signups, partial: "league_signups/league_signup", as: :league_signup 2 | -------------------------------------------------------------------------------- /app/views/matches/_match.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! match, :id, :created_at, :updated_at 2 | json.url match_url(match, format: :json) 3 | -------------------------------------------------------------------------------- /app/views/rounds/_round.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! round, :id, :created_at, :updated_at 2 | json.url round_url(round, format: :json) 3 | -------------------------------------------------------------------------------- /public/fonts/xwing-miniatures-ships.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexRaubach/ListFortress/HEAD/public/fonts/xwing-miniatures-ships.ttf -------------------------------------------------------------------------------- /app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../javascripts .js 3 | //= link_directory ../stylesheets .css 4 | -------------------------------------------------------------------------------- /app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | class HomeController < ApplicationController 2 | def show 3 | end 4 | 5 | def about 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: 'from@example.com' 3 | layout 'mailer' 4 | end 5 | -------------------------------------------------------------------------------- /app/views/participants/show.html.erb: -------------------------------------------------------------------------------- 1 | 2 | <%= link_to 'Edit', edit_participant_path(@participant) %> | 3 | <%= link_to 'Back', participants_path %> 4 | -------------------------------------------------------------------------------- /app/views/season_seven_surveys/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! "season_seven_surveys/season_seven_survey", season_seven_survey: @season_seven_survey 2 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby.exe 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /app/models/season_seven_survey.rb: -------------------------------------------------------------------------------- 1 | class SeasonSevenSurvey < ApplicationRecord 2 | belongs_to :user 3 | validates :user_id, uniqueness: true 4 | end 5 | -------------------------------------------------------------------------------- /app/models/league_signup.rb: -------------------------------------------------------------------------------- 1 | class LeagueSignup < ApplicationRecord 2 | belongs_to :user 3 | validates_uniqueness_of :user, scope: :season_number 4 | end 5 | -------------------------------------------------------------------------------- /app/views/tournaments/_tournament.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! tournament, :id, :created_at, :updated_at 2 | json.url tournament_url(tournament, format: :json) 3 | -------------------------------------------------------------------------------- /app/views/league_signups/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

New League Signup

3 | 4 | <%= render 'form', league_signup: @league_signup %> 5 | 6 |
-------------------------------------------------------------------------------- /app/views/rounds/edit.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Edit a Round

3 | <%= render 'form', participant: @round %> 4 |
5 | -------------------------------------------------------------------------------- /app/views/season_seven_surveys/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @season_seven_surveys, partial: 'season_seven_surveys/season_seven_survey', as: :season_seven_survey 2 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path('../config/application', __dir__) 3 | require_relative "../config/boot" 4 | require "rails/commands" 5 | -------------------------------------------------------------------------------- /app/views/matches/new.html.erb: -------------------------------------------------------------------------------- 1 |

New Match

2 |
3 | <%= render 'form', match: @match %> 4 |
5 | <%= link_to 'Back', matches_path %> 6 | -------------------------------------------------------------------------------- /app/views/rounds/new.html.erb: -------------------------------------------------------------------------------- 1 |

New Round

2 |
3 | <%= render 'form', round: @round %> 4 |
5 | <%= link_to 'Back', round_path %> 6 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative "application" 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /test/models/match_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class MatchTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/pilot_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class PilotTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/round_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RoundTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/ship_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ShipTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/user_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class UserTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /app/views/league_signups/_league_signup.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! league_signup, :id, :created_at, :updated_at 2 | json.url league_signup_url(league_signup, format: :json) 3 | -------------------------------------------------------------------------------- /db/migrate/20190203012013_change_ship_xws.rb: -------------------------------------------------------------------------------- 1 | class ChangeShipXws < ActiveRecord::Migration[5.2] 2 | def change 3 | change_column :ships, :xws, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /test/models/address_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class AddressTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/division_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class DivisionTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/faction_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class FactionTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/format_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class FormatTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/season_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SeasonTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/upgrade_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class UpgradeTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/version_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class VersionTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /app/serializers/api/v1/season_serializer.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::SeasonSerializer < ActiveModel::Serializer 2 | attributes :id, :name, :season_number, :created_at, :updated_at 3 | end 4 | -------------------------------------------------------------------------------- /app/views/participants/edit.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Edit a Participant

3 | <%= render 'form', participant: @participant %> 4 |
5 | -------------------------------------------------------------------------------- /app/views/season_seven_surveys/show.html.erb: -------------------------------------------------------------------------------- 1 | 2 | <%= link_to 'Edit', edit_season_seven_survey_path(@season_seven_survey) %> | 3 | <%= link_to 'Back', season_seven_surveys_path %> 4 | -------------------------------------------------------------------------------- /test/models/league_user_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class LeagueUserTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/roundtype_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RoundtypeTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/tournament_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class TournamentTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /db/migrate/20220309013410_add_sort_to_format.rb: -------------------------------------------------------------------------------- 1 | class AddSortToFormat < ActiveRecord::Migration[6.1] 2 | def change 3 | add_column :formats, :sort, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /test/models/league_match_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class LeageMatchTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/league_signup_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class LeagueSignupTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/participant_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ParticipantTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /app/views/me/home.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Update User Information

3 | 4 | <%= render 'address_form', address: @address %> 5 | 6 |
7 | -------------------------------------------------------------------------------- /app/views/tournaments/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Submitting A New Tournament


3 | <%= render 'form', tournament: @tournament %> 4 |
5 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative "config/environment" 4 | 5 | run Rails.application 6 | Rails.application.load_server 7 | -------------------------------------------------------------------------------- /test/fixtures/roundtypes.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | one: 4 | name: MyString 5 | 6 | two: 7 | name: MyString 8 | -------------------------------------------------------------------------------- /test/models/tournament_type_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class TournamentTypeTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /app/views/league_signups/show.html.erb: -------------------------------------------------------------------------------- 1 |

<%= notice %>

2 | 3 | <%= link_to 'Edit', edit_league_signup_path(@league_signup) %> | 4 | <%= link_to 'Back', league_signups_path %> 5 | -------------------------------------------------------------------------------- /test/models/league_match_state_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class LeagueMatchStateTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/league_participant_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class LeagueParticipantTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/season_seven_survey_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SeasonSevenSurveyTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /app/views/matches/show.html.erb: -------------------------------------------------------------------------------- 1 | <%= link_to('Player 1', @match.player1) + ' | ' + link_to('Player 2', @match.player2) %> 2 | 3 |
4 | <%= link_to 'Edit', edit_match_path(@match) %> 5 | 6 | -------------------------------------------------------------------------------- /app/views/participants/new.html.erb: -------------------------------------------------------------------------------- 1 |

New Participant

2 |
3 | <%= render 'form', participant: @participant %> 4 |
5 | <%= link_to 'Back', participants_path %> 6 | -------------------------------------------------------------------------------- /test/controllers/me_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class MeControllerTest < ActionDispatch::IntegrationTest 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /app/views/season_seven_surveys/_season_seven_survey.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! season_seven_survey, :id, :created_at, :updated_at 2 | json.url season_seven_survey_url(season_seven_survey, format: :json) 3 | -------------------------------------------------------------------------------- /config/initializers/cors.rb: -------------------------------------------------------------------------------- 1 | Rails.application.config.middleware.insert_before 0, Rack::Cors do 2 | allow do 3 | origins '*' 4 | resource '/api/*', headers: :any, methods: [:get] 5 | end 6 | end -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /test/controllers/home_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class HomeControllerTest < ActionDispatch::IntegrationTest 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/application_system_test_case.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class ApplicationSystemTestCase < ActionDispatch::SystemTestCase 4 | driven_by :selenium, using: :chrome, screen_size: [1400, 1400] 5 | end 6 | -------------------------------------------------------------------------------- /app/assets/stylesheets/me.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the Me controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/views/tournaments/edit.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Editing Tournament

3 | <%= render 'form', tournament: @tournament %> 4 | <%= link_to 'Show', @tournament %> | 5 |
6 | -------------------------------------------------------------------------------- /app/assets/stylesheets/home.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the Home controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /db/migrate/20190327185131_add_loss_on_league_participants.rb: -------------------------------------------------------------------------------- 1 | class AddLossOnLeagueParticipants < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :league_participants, :losses, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/assets/stylesheets/seasons.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the Seasons controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/tournaments.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the Tournaments controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/views/league_signups/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing League Signup

2 | 3 | <%= render 'form', league_signup: @league_signup %> 4 | 5 | <%= link_to 'Show', @league_signup %> | 6 | <%= link_to 'Back', league_signups_path %> 7 | -------------------------------------------------------------------------------- /app/assets/stylesheets/participants.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the Participants controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 2 | 3 | require "bundler/setup" # Set up gems listed in the Gemfile. 4 | require "bootsnap/setup" # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /lib/tasks/reset_participant_counter_cache.rake: -------------------------------------------------------------------------------- 1 | desc 'Reset Participant counter cache' 2 | task reset_participants: :environment do 3 | Tournament.find_each { |tournament| Tournament.reset_counters(tournament.id, :participants) } 4 | end -------------------------------------------------------------------------------- /app/assets/stylesheets/league_signups.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the league_signups controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/league_participant.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the LeagueParticipant controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/views/season_seven_surveys/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

New Season Seven Survey

3 | 4 | <%= render 'form', season_seven_survey: @season_seven_survey %> 5 | 6 | <%= link_to 'Back', season_seven_surveys_path %> 7 |
-------------------------------------------------------------------------------- /db/migrate/20181007004220_create_versions.rb: -------------------------------------------------------------------------------- 1 | class CreateVersions < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :versions do |t| 4 | t.string :name 5 | 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20181007004236_create_formats.rb: -------------------------------------------------------------------------------- 1 | class CreateFormats < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :formats do |t| 4 | t.string :name 5 | 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/assets/stylesheets/season_seven_surveys.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the season_seven_surveys controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /db/migrate/20181121020916_add_participant_counter_cache.rb: -------------------------------------------------------------------------------- 1 | class AddParticipantCounterCache < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :tournaments, :participants_count, :integer, null: false, default: 0 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20190217023821_add_promotion_tracker_to_league_participants.rb: -------------------------------------------------------------------------------- 1 | class AddPromotionTrackerToLeagueParticipants < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :league_participants, :promotion, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/assets/javascripts/home.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/me.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative 'config/application' 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /app/assets/javascripts/seasons.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/serializers/api/v1/league_participant_serializer.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::LeagueParticipantSerializer < ActiveModel::Serializer 2 | attributes :id, :division_id, :created_at, :updated_at, :list_juggler_id, :list_juggler_name, :mov, :score, :losses 3 | end 4 | -------------------------------------------------------------------------------- /config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: test 6 | 7 | production: 8 | adapter: redis 9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 10 | channel_prefix: list_fortress_production 11 | -------------------------------------------------------------------------------- /db/migrate/20190825180651_add_user_to_addresses.rb: -------------------------------------------------------------------------------- 1 | class AddUserToAddresses < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :addresses, :user_id, :integer 4 | add_column :addresses, :prize_level, :integer, default: 0 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/assets/javascripts/league_signups.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/participants.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /db/migrate/20190307214001_add_mov_to_l_participants.rb: -------------------------------------------------------------------------------- 1 | class AddMovToLParticipants < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :league_participants, :mov, :integer 4 | add_column :league_participants, :score, :integer 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/assets/javascripts/league_participant.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/season_seven_surveys.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/serializers/api/v1/season_details_serializer.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::SeasonDetailsSerializer < ActiveModel::Serializer 2 | attributes :id, :name, :season_number, :created_at, :updated_at 3 | 4 | has_many :divisions, serializer: Api::V1::DivisionSerializer 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20181007031555_create_tournament_types.rb: -------------------------------------------------------------------------------- 1 | class CreateTournamentTypes < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :tournament_types do |t| 4 | t.string :name 5 | 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/assets/javascripts/google_analytics.js.erb: -------------------------------------------------------------------------------- 1 | document.addEventListener('turbolinks:load', function(event) { 2 | if (typeof gtag === 'function') { 3 | gtag('config', '<%= ENV['google_analytic_tag'] %>', { 4 | 'page_location': event.data.url 5 | }) 6 | } 7 | }) -------------------------------------------------------------------------------- /app/views/participants/_participant.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! participant, :id, :created_at, :updated_at, :name, :swiss_rank, :top_cut_rank, :score, :mov, :sos, :dropped, :list_json, :squad_url, :mission_points, :event_points 2 | json.url participant_url(participant, format: :json) 3 | -------------------------------------------------------------------------------- /app/serializers/api/v1/division_serializer.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::DivisionSerializer < ActiveModel::Serializer 2 | attributes :id, :name, :season_id, :tier, :letter, :created_at, :updated_at 3 | 4 | has_many :league_participants, serializer: Api::V1::LeagueParticipantSerializer 5 | end 6 | -------------------------------------------------------------------------------- /app/views/matches/edit.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Edit a Match

3 | <% if @match.league_match%> 4 | <%= render 'leagueform', participant: @match%> 5 | <% else %> 6 | <%= render 'form', participant: @match %> 7 | <% end %> 8 |
9 | -------------------------------------------------------------------------------- /app/controllers/divisions_controller.rb: -------------------------------------------------------------------------------- 1 | class DivisionsController < ApplicationController 2 | def show 3 | @division = Division.includes(:season).find(params['id']) 4 | @players = @division.league_participants.includes(:user).order(score: :desc, mov: :desc, id: :asc) 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/views/season_seven_surveys/edit.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Editing Season Seven Survey

3 | 4 | <%= render 'form', season_seven_survey: @season_seven_survey %> 5 | 6 | <%= link_to 'Show', @season_seven_survey %> | 7 | <%= link_to 'Back', season_seven_surveys_path %> 8 |
-------------------------------------------------------------------------------- /config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ActiveSupport::Reloader.to_prepare do 4 | # ApplicationController.renderer.defaults.merge!( 5 | # http_host: 'example.org', 6 | # https: false 7 | # ) 8 | # end 9 | -------------------------------------------------------------------------------- /db/migrate/20181006204755_create_factions.rb: -------------------------------------------------------------------------------- 1 | class CreateFactions < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :factions do |t| 4 | t.string :name 5 | t.string :xws 6 | t.integer :ffg 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /test/fixtures/rounds.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | one: 4 | round_type: MyString 5 | round_number: 1 6 | tournament: one 7 | 8 | two: 9 | round_type: MyString 10 | round_number: 1 11 | tournament: two 12 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /db/migrate/20181207035750_create_league_match_states.rb: -------------------------------------------------------------------------------- 1 | class CreateLeagueMatchStates < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :league_match_states do |t| 4 | t.string :name 5 | t.boolean :active 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /public/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #2d89ef 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /db/migrate/20181109003516_create_divisions.rb: -------------------------------------------------------------------------------- 1 | class CreateDivisions < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :divisions do |t| 4 | t.string :name 5 | t.integer :season_id 6 | t.integer :tier 7 | 8 | 9 | t.timestamps 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/views/layouts/mailer.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [ 5 | :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn 6 | ] 7 | -------------------------------------------------------------------------------- /lib/tasks/pilot_init_csv.rake: -------------------------------------------------------------------------------- 1 | desc 'Creates a csv with all pilot inits' 2 | task generate_pilot_skill_csv: :environment do 3 | file = "#{Rails.root}/tmp/pilots.csv" 4 | 5 | CSV.open(file, 'w') do |csv| 6 | Pilot.all.each do |pilot| 7 | csv << [pilot.xws, pilot.initiative] 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/models/identity.rb: -------------------------------------------------------------------------------- 1 | class Identity < ApplicationRecord 2 | belongs_to :user 3 | 4 | def self.find_with_omniauth(auth) 5 | find_by(uid: auth['uid'], provider: auth['provider']) 6 | end 7 | 8 | def self.create_with_omniauth(auth) 9 | create(uid: auth['uid'], provider: auth['provider']) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20190227125129_add_division_letter.rb: -------------------------------------------------------------------------------- 1 | class AddDivisionLetter < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :matches, :league_match, :boolean 4 | add_column :matches, :player1_url, :string 5 | add_column :matches, :player2_url, :string 6 | add_column :divisions, :letter, :string 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /lib/tasks/export_user_info.rake: -------------------------------------------------------------------------------- 1 | desc 'Creates a csv with all winners from a season' 2 | task export_users: :environment do 3 | file = "#{Rails.root}/tmp/users.csv" 4 | CSV.open(file, 'w') do |csv| 5 | User.all.each do |user| 6 | csv << [user.id, user.name, user.display_name, user.email] 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | def flash_class(level) 3 | case level 4 | when 'notice' then "alert alert-info" 5 | when 'success' then "alert alert-success" 6 | when 'error' then "alert alert-danger" 7 | when 'alert' then "alert alert-warning" 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20190108185935_create_roundtypes.rb: -------------------------------------------------------------------------------- 1 | class CreateRoundtypes < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :roundtypes do |t| 4 | t.string :name 5 | 6 | t.timestamps 7 | end 8 | 9 | Roundtype.create(name:'swiss') 10 | Roundtype.create(name:'elimination') 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /db/migrate/20190109233824_create_rounds.rb: -------------------------------------------------------------------------------- 1 | class CreateRounds < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :rounds do |t| 4 | t.references :roundtype, foreign_key: true 5 | t.integer :round_number 6 | t.references :tournament, foreign_key: true 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV['RAILS_ENV'] ||= 'test' 2 | require_relative '../config/environment' 3 | require 'rails/test_help' 4 | 5 | class ActiveSupport::TestCase 6 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. 7 | fixtures :all 8 | 9 | # Add more helper methods to be used by all tests here... 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20190106202527_create_identities.rb: -------------------------------------------------------------------------------- 1 | class CreateIdentities < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :identities do |t| 4 | t.string :uid 5 | t.string :provider 6 | t.references :user 7 | end 8 | 9 | change_table :users do |t| 10 | t.string :display_name 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /db/migrate/20181010002750_create_ships.rb: -------------------------------------------------------------------------------- 1 | class CreateShips < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :ships do |t| 4 | t.string :name 5 | t.integer :ffg 6 | t.string :size 7 | t.integer :xws 8 | t.integer :faction_id 9 | t.index :xws 10 | 11 | t.timestamps 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /config/initializers/omniauth.rb: -------------------------------------------------------------------------------- 1 | require 'omniauth-slack' 2 | Rails.application.config.middleware.use OmniAuth::Builder do 3 | #provider :google_oauth2, ENV['google_client_id'], ENV['gooogle_client_secret'] 4 | provider :slack, ENV['slack_client_id'], ENV['slack_client_secret'], scope: 'identity.basic identity.email identity.team identity.avatar', team: 'T2FCSKL3Z' 5 | end 6 | -------------------------------------------------------------------------------- /test/controllers/seasons_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SeasonsControllerTest < ActionDispatch::IntegrationTest 4 | test "should get index" do 5 | get seasons_index_url 6 | assert_response :success 7 | end 8 | 9 | test "should get show" do 10 | get seasons_show_url 11 | assert_response :success 12 | end 13 | 14 | end 15 | -------------------------------------------------------------------------------- /db/migrate/20181004023419_create_users.rb: -------------------------------------------------------------------------------- 1 | class CreateUsers < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :users do |t| 4 | t.string :provider 5 | t.string :uid 6 | t.string :email 7 | t.string :first_name 8 | t.string :last_name 9 | t.index :uid 10 | 11 | t.timestamps 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /db/migrate/20181109003508_create_seasons.rb: -------------------------------------------------------------------------------- 1 | class CreateSeasons < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :seasons do |t| 4 | t.string :name 5 | t.integer :season_number, unique: true 6 | t.boolean :active 7 | t.boolean :sign_up_active 8 | t.boolean :locked 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /db/migrate/20190616195742_create_league_signups.rb: -------------------------------------------------------------------------------- 1 | class CreateLeagueSignups < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :league_signups do |t| 4 | t.integer :season_number 5 | t.integer :user_id 6 | t.string :time_zone 7 | t.integer :time 8 | t.string :other 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /db/migrate/20181108184836_create_league_participants.rb: -------------------------------------------------------------------------------- 1 | class CreateLeagueParticipants < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :league_participants do |t| 4 | t.integer :user_id 5 | t.integer :division_id 6 | t.integer :list_juggler_id 7 | t.string :list_juggler_name 8 | 9 | t.timestamps 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /test/fixtures/users.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | one: 4 | provider: MyString 5 | uid: MyString 6 | email: MyString 7 | first_name: MyString 8 | last_name: MyString 9 | 10 | two: 11 | provider: MyString 12 | uid: MyString 13 | email: MyString 14 | first_name: MyString 15 | last_name: MyString 16 | -------------------------------------------------------------------------------- /db/migrate/20181113014608_change_user_table.rb: -------------------------------------------------------------------------------- 1 | class ChangeUserTable < ActiveRecord::Migration[5.2] 2 | def change 3 | change_table :users do |t| 4 | t.string :slack_id 5 | t.boolean :league_eligible 6 | t.string :name 7 | t.string :slack_avatar 8 | t.boolean :admin 9 | t.remove :provider 10 | t.remove :uid 11 | 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /app/serializers/api/v1/base_serializer.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::BaseSerializer < ActiveModel::Serializer 2 | include Rails.application.routes.url_helpers 3 | 4 | def created_at 5 | object.created_at.to_datetime.in_time_zone('UTC').iso8601 if object.created_at 6 | end 7 | 8 | def updated_at 9 | object.updated_at.to_datetime.in_time_zone('UTC').iso8601 if object.updated_at 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /test/fixtures/matches.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | one: 4 | player1: one 5 | player1_points: 1 6 | player2: one 7 | player2_points: 1 8 | round: one 9 | result: MyString 10 | 11 | two: 12 | player1: two 13 | player1_points: 1 14 | player2: two 15 | player2_points: 1 16 | round: two 17 | result: MyString 18 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | TargetRubyVersion: 2.7.1 3 | NewCops: enable 4 | Exclude: 5 | - 'db/**/*' 6 | - 'config/**/*' 7 | - 'script/**/*' 8 | - 'bin/{rails,rake}' 9 | - !ruby/regexp /old_and_unused\.rb$/ 10 | - '**/*.erb' 11 | 12 | Style/HashEachMethods: 13 | Enabled: true 14 | 15 | Style/HashTransformKeys: 16 | Enabled: true 17 | 18 | Style/HashTransformValues: 19 | Enabled: true -------------------------------------------------------------------------------- /test/controllers/league_participant_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class LeagueParticipantControllerTest < ActionDispatch::IntegrationTest 4 | test "should get show" do 5 | get league_participant_show_url 6 | assert_response :success 7 | end 8 | 9 | test "should get index" do 10 | get league_participant_index_url 11 | assert_response :success 12 | end 13 | 14 | end 15 | -------------------------------------------------------------------------------- /app/controllers/api/v1/seasons_controller.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::SeasonsController < ActionController::API 2 | def index 3 | seasons = Season.all.order(:season_number) 4 | 5 | render json: seasons, each_serializer: Api::V1::SeasonSerializer 6 | end 7 | 8 | def show 9 | season = Season.find(params[:id]) 10 | 11 | render json: season, serializer: Api::V1::SeasonDetailsSerializer 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/serializers/api/v1/match_serializer.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::MatchSerializer < ActiveModel::Serializer 2 | # attributes(*Match.attribute_names.map(&:to_sym)) 3 | attribute :id 4 | attribute :player1_id 5 | attribute :player1_points 6 | attribute :player2_id 7 | attribute :player2_points 8 | attribute :result 9 | attribute :winner_id 10 | attribute :rounds_played 11 | attribute :went_to_time 12 | end 13 | -------------------------------------------------------------------------------- /db/migrate/20220404204413_add_items_to_tournaments.rb: -------------------------------------------------------------------------------- 1 | class AddItemsToTournaments < ActiveRecord::Migration[6.1] 2 | def change 3 | add_column :participants, :event_points, :integer 4 | add_column :participants, :mission_points, :integer 5 | add_column :matches, :rounds_played, :integer 6 | add_column :matches, :went_to_time, :boolean 7 | add_column :rounds, :scenario, :string 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /test/fixtures/pilots.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/ships.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/addresses.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/divisions.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/factions.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/formats.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/seasons.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/tournaments.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/upgrades.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/versions.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /app/models/format.rb: -------------------------------------------------------------------------------- 1 | class Format < ApplicationRecord 2 | has_many :tournaments 3 | # This class holds tournament formats 4 | # The sort field both controls the order they're sorted in but also allows them to be depricated. 5 | # if sort = null, you can't select them in the tournament create form but can still filter by the format 6 | # Note that the nulls last sort in app/views/tournaments/_filter.html.erb is postgres only 7 | end 8 | -------------------------------------------------------------------------------- /db/migrate/20181010003159_create_upgrades.rb: -------------------------------------------------------------------------------- 1 | class CreateUpgrades < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :upgrades do |t| 4 | t.string :name 5 | t.string :xws 6 | t.integer :ffg 7 | t.string :upgrade_type 8 | t.boolean :limited 9 | t.string :image 10 | t.integer :cost 11 | t.index :xws 12 | 13 | t.timestamps 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /test/fixtures/league_matches.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/league_signups.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/tournament_types.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/league_match_states.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/league_participants.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/season_seven_surveys.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /app/assets/javascripts/cable.js: -------------------------------------------------------------------------------- 1 | // Action Cable provides the framework to deal with WebSockets in Rails. 2 | // You can generate new channels where WebSocket features live using the `rails generate channel` command. 3 | // 4 | //= require action_cable 5 | //= require_self 6 | //= require_tree ./channels 7 | 8 | (function() { 9 | this.App || (this.App = {}); 10 | 11 | App.cable = ActionCable.createConsumer(); 12 | 13 | }).call(this); 14 | -------------------------------------------------------------------------------- /app/serializers/api/v1/tournament_serializer.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::TournamentSerializer < ActiveModel::Serializer 2 | # attributes(*Tournament.attribute_names.map(&:to_sym)) 3 | attribute :id 4 | attribute :name 5 | attribute :location 6 | attribute :state 7 | attribute :country 8 | attribute :date 9 | attribute :format_id 10 | attribute :version_id 11 | attribute :tournament_type_id 12 | attribute :created_at 13 | attribute :updated_at 14 | end 15 | -------------------------------------------------------------------------------- /config/initializers/permissions_policy.rb: -------------------------------------------------------------------------------- 1 | # Define an application-wide HTTP permissions policy. For further 2 | # information see https://developers.google.com/web/updates/2018/06/feature-policy 3 | # 4 | # Rails.application.config.permissions_policy do |f| 5 | # f.camera :none 6 | # f.gyroscope :none 7 | # f.microphone :none 8 | # f.usb :none 9 | # f.fullscreen :self 10 | # f.payment :self, "https://secure.example.com" 11 | # end 12 | -------------------------------------------------------------------------------- /app/views/layouts/_google_analytics.html.erb: -------------------------------------------------------------------------------- 1 | <% if Rails.env.production? %> 2 | 3 | 4 | 11 | <% end %> -------------------------------------------------------------------------------- /config/credentials.yml.enc: -------------------------------------------------------------------------------- 1 | 9DsuXcZzZMYv6ISKxc2T/ofCs0552ins1JUDLXfXXEoDMBHGP7QWCw/c269mV57KB36Dl+aeGyttN/3lhQlwQg0e+WEAd67HDxahldUVdbrZ8BWNGkW3mzMzZsHsax+8g/9rRMnF6sv8fyjryycKyxPjBmKi3xwYBDQInm/plJjEMxrPoxHS9vuK7u4Fib0bj6FQVFktIyLOt9RHQyVOQz2V6uJmHhDxr6lDnEt/m42G7UN8PcJbO5chAP4ohHLMNj3drrHak7Ra3LN54M7YaNUgeS9KnCL6kbTlRuqf/fDO0aJbe8f2/gU+hNY3ZmWdGoBQl/LXPHhCzEpgjTWFtcd7d+KdE7YncAZQ7GJSlcSsUzl+u/RJ1DpRia1bkzD2HlN21tekuia1l00f2//S0BeBwSNDE6bdjifx--owCJlKgIZfZ3+QG9--dK9v8Qk2UllDMq4qfYtTiw== -------------------------------------------------------------------------------- /db/migrate/20181009234406_create_pilots.rb: -------------------------------------------------------------------------------- 1 | class CreatePilots < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :pilots do |t| 4 | t.string :name 5 | t.string :caption 6 | t.integer :initiative 7 | t.boolean :limited 8 | t.integer :cost 9 | t.string :xws 10 | t.integer :ffg 11 | t.integer :ship_id 12 | t.string :image 13 | t.string :ability 14 | t.index :xws 15 | 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /db/migrate/20181108030503_create_addresses.rb: -------------------------------------------------------------------------------- 1 | class CreateAddresses < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :addresses do |t| 4 | t.integer :league_player_id 5 | t.string :first_line 6 | t.string :second_line 7 | t.string :city 8 | t.string :county_province 9 | t.string :zip_or_postcode 10 | t.string :country 11 | t.boolean :use_other 12 | t.string :other 13 | 14 | t.timestamps 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/views/league/register.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

3 | To register, you must first have a Vassal League Slack account. 4 | link_to('To request an invite, visit this link.', https://xwingvassalleagueslack.herokuapp.com/) 5 |

6 |

7 | Then, simply sign into List Fortress with your Vassal League Slack account by clicking the sign in with Slack Button. 8 | If you are prompted to select a workspace, enter xwvl 9 | Using a different workspace will result in an error 10 |

11 |
-------------------------------------------------------------------------------- /db/migrate/20181002190843_create_tournaments.rb: -------------------------------------------------------------------------------- 1 | class CreateTournaments < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :tournaments do |t| 4 | t.string :name 5 | t.integer :organizer_id 6 | t.string :location 7 | t.string :state 8 | t.string :country 9 | t.date :date 10 | t.integer :format_id 11 | t.integer :version_id 12 | t.integer :tournament_type_id 13 | t.boolean :locked 14 | 15 | t.timestamps 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /app/serializers/api/v1/participant_serializer.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::ParticipantSerializer < ActiveModel::Serializer 2 | # attributes(*Participant.attribute_names.map(&:to_sym)) 3 | 4 | attribute :id 5 | attribute :name 6 | attribute :tournament_id 7 | attribute :score 8 | attribute :swiss_rank 9 | attribute :top_cut_rank 10 | attribute :mov 11 | attribute :sos 12 | attribute :dropped 13 | attribute :list_points 14 | attribute :list_json 15 | attribute :event_points 16 | attribute :mission_points 17 | end 18 | -------------------------------------------------------------------------------- /public/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "short_name": "", 4 | "icons": [ 5 | { 6 | "src": "/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "theme_color": "#ffffff", 17 | "background_color": "#ffffff", 18 | "display": "standalone" 19 | } 20 | -------------------------------------------------------------------------------- /db/migrate/20181221025059_create_season_seven_surveys.rb: -------------------------------------------------------------------------------- 1 | class CreateSeasonSevenSurveys < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :season_seven_surveys do |t| 4 | t.integer :user_id 5 | t.string :full_name 6 | t.string :display_name 7 | t.string :time_zone 8 | t.integer :time 9 | 10 | t.integer :s1_id 11 | t.integer :s2_id 12 | t.integer :s3_id 13 | t.integer :s4_id 14 | t.integer :s5_id 15 | t.integer :s6_id 16 | 17 | t.timestamps 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /app/views/rounds/index.html.erb: -------------------------------------------------------------------------------- 1 | 2 |

Rounds

3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | <% @rounds.each do |round| %> 13 | 14 | 15 | 16 | 17 | 18 | <% end %> 19 | 20 |
<%= link_to 'Show', round %><%= link_to 'Edit', edit_round_path(round) %><%= link_to 'Destroy', round, method: :delete, data: { confirm: 'Are you sure?' } %>
21 | 22 |
23 | 24 | <%= link_to 'New Round', new_round_path %> 25 | -------------------------------------------------------------------------------- /app/views/matches/index.html.erb: -------------------------------------------------------------------------------- 1 | 2 |

Matches

3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | <% @matches.each do |match| %> 13 | 14 | 15 | 16 | 17 | 18 | <% end %> 19 | 20 |
<%= link_to 'Show', match %><%= link_to 'Edit', edit_match_path(match) %><%= link_to 'Destroy', match, method: :delete, data: { confirm: 'Are you sure?' } %>
21 | 22 |
23 | 24 | <%= link_to 'New Match', new_participant_path %> 25 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code 7 | # by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'". 8 | Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"] 9 | -------------------------------------------------------------------------------- /public/s12.csv: -------------------------------------------------------------------------------- 1 | 87,1,A 2 | 126,1,A 3 | 345,1,A 4 | 41,1,A 5 | 29,1,A 6 | 23,1,A 7 | 73,1,A 8 | 220,1,A 9 | 78,1,A 10 | 71,1,A 11 | 652,2,B 12 | 355,2,A 13 | 607,2,A 14 | 644,2,A 15 | 563,2,A 16 | 373,2,A 17 | 221,2,A 18 | 57,2,A 19 | 196,2,A 20 | 164,2,B 21 | 651,2,B 22 | 10,2,B 23 | 82,2,B 24 | 6,2,B 25 | 648,2,B 26 | 647,2,B 27 | 567,2,B 28 | 697,3,A 29 | 600,3,A 30 | 42,3,A 31 | 117,3,A 32 | 256,3,A 33 | 72,3,A 34 | 659,3,A 35 | 566,3,A 36 | 695,3,B 37 | 696,3,B 38 | 68,3,B 39 | 290,3,B 40 | 692,3,B 41 | 102,3,B 42 | 578,3,B 43 | 124,3,C 44 | 698,3,C 45 | 140,3,C 46 | 334,3,C 47 | 110,3,C 48 | 188,3,B -------------------------------------------------------------------------------- /app/models/division.rb: -------------------------------------------------------------------------------- 1 | class Division < ApplicationRecord 2 | belongs_to :season 3 | has_many :league_participants 4 | 5 | def add_participant(participant) 6 | division_members = LeagueParticipant.where(division_id: id) 7 | 8 | if division_members.length.positive? 9 | division_members.each do |division_member| 10 | Match.create( 11 | player1: participant, 12 | player2: division_member, 13 | league_match: true 14 | ) 15 | end 16 | end 17 | 18 | participant.division_id = id 19 | participant.save 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /db/migrate/20181005004307_create_participants.rb: -------------------------------------------------------------------------------- 1 | class CreateParticipants < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :participants do |t| 4 | t.integer :tournament_id 5 | t.string :name 6 | t.integer :player_id 7 | t.integer :score 8 | t.integer :swiss_rank 9 | t.integer :top_cut_rank 10 | t.integer :mov 11 | t.decimal :sos 12 | t.boolean :dropped 13 | t.integer :list_points 14 | 15 | t.index :tournament_id 16 | t.column :list_json, 'jsonb' 17 | 18 | t.timestamps 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /bin/yarn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_ROOT = File.expand_path('..', __dir__) 3 | Dir.chdir(APP_ROOT) do 4 | yarn = ENV["PATH"].split(File::PATH_SEPARATOR). 5 | select { |dir| File.expand_path(dir) != __dir__ }. 6 | product(["yarn", "yarn.cmd", "yarn.ps1"]). 7 | map { |dir, file| File.expand_path(file, dir) }. 8 | find { |file| File.executable?(file) } 9 | 10 | if yarn 11 | exec yarn, *ARGV 12 | else 13 | $stderr.puts "Yarn executable was not detected in the system." 14 | $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" 15 | exit 1 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/views/seasons/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

All Vassal League Seasons

3 | 4 | 5 | <% @seasons.each do |season| %> 6 | 7 | 8 | 10 | <% end %> 11 |
<%= season.season_number%><%= link_to season.name, season_path(season_number: season.season_number) %> 9 |
12 | 13 | 18 | 19 |
-------------------------------------------------------------------------------- /app/models/tournaments/forms.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Tournaments 4 | class Forms 5 | ORDER = { 6 | # simple name for key, then array with sql string and the display text 7 | # each sort needs to be completely unique. If you have ties in the order, the pagination can hide some tournaments 8 | 'date_desc' => ['date desc, id desc', 'Newest'], 9 | 'date_asc' => ['date asc, id desc', 'Oldest'], 10 | 'size_desc' => ['participants_count desc, id desc', 'Largest'], 11 | 'size_asc' => ['participants_count asc, id desc', 'Smallest'] 12 | }.freeze 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /db/migrate/20210321231956_create_active_storage_variant_records.active_storage.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from active_storage (originally 20191206030411) 2 | class CreateActiveStorageVariantRecords < ActiveRecord::Migration[6.0] 3 | def change 4 | create_table :active_storage_variant_records do |t| 5 | t.belongs_to :blob, null: false, index: false 6 | t.string :variation_digest, null: false 7 | 8 | t.index %i[ blob_id variation_digest ], name: "index_active_storage_variant_records_uniqueness", unique: true 9 | t.foreign_key :active_storage_blobs, column: :blob_id 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /test/fixtures/participants.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | one: 4 | name: MyString 5 | player_id: MyString 6 | score: MyString 7 | swiss_rank: MyString 8 | top_cut_rank: MyString 9 | mov: MyString 10 | sos: MyString 11 | dropped: MyString 12 | list_json: MyString 13 | list_points: MyString 14 | 15 | two: 16 | name: MyString 17 | player_id: MyString 18 | score: MyString 19 | swiss_rank: MyString 20 | top_cut_rank: MyString 21 | mov: MyString 22 | sos: MyString 23 | dropped: MyString 24 | list_json: MyString 25 | list_points: MyString 26 | -------------------------------------------------------------------------------- /app/views/participants/index.html.erb: -------------------------------------------------------------------------------- 1 | 2 |

Participants

3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | <% @participants.each do |participant| %> 13 | 14 | 15 | 16 | 17 | 18 | <% end %> 19 | 20 |
<%= link_to 'Show', participant %><%= link_to 'Edit', edit_participant_path(participant) %><%= link_to 'Destroy', participant, method: :delete, data: { confirm: 'Are you sure?' } %>
21 | 22 |
23 | 24 | <%= link_to 'New Participant', new_participant_path %> 25 | -------------------------------------------------------------------------------- /app/controllers/league_participant_controller.rb: -------------------------------------------------------------------------------- 1 | class LeagueParticipantController < ApplicationController 2 | def show 3 | @league_participant = LeagueParticipant.find(params[:id]) 4 | @matches = @league_participant.matches 5 | .includes({ player1: :user }, { player2: :user }) 6 | .with_attached_log_file 7 | .order(winner_id: :asc, id: :asc) 8 | 9 | @authorized = @league_participant&.division&.season&.active || current_user&.admin 10 | end 11 | 12 | private 13 | 14 | def match_params 15 | params.permit(:id) 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/serializers/api/v1/round_serializer.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::RoundSerializer < ActiveModel::Serializer 2 | # attributes(*Round.attribute_names.map(&:to_sym)) 3 | attribute :id 4 | attribute :tournament_id 5 | attribute :roundtype_id 6 | attribute :round_number 7 | attribute :scenario 8 | 9 | has_many :matches, serializer: Api::V1::MatchSerializer do 10 | include_data(true) 11 | link(:related) {api_v1_matches_path(round_id: object.id)} 12 | end 13 | # has_many :rounds, serializer: Api::V1::RoundSerializer do 14 | # include_data(true) 15 | # link(:related) {api_v1_rounds_path(tournament_id: object.id)} 16 | # end 17 | end 18 | -------------------------------------------------------------------------------- /db/migrate/20181204013957_create_league_matches.rb: -------------------------------------------------------------------------------- 1 | class CreateLeagueMatches < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :leage_matches do |t| 4 | t.integer :p1_id 5 | t.column :p1_list_json, 'jsonb' 6 | t.string :p1_lj_list_string 7 | t.string :p1_list_url 8 | 9 | t.integer :p2_id 10 | t.column :p2_list_json, 'jsonb' 11 | t.string :p2_lj_list_string 12 | t.string :p2_list_url 13 | 14 | t.integer :division_id 15 | t.integer :match_state_id 16 | t.integer :legacy_match_id 17 | t.date :scheduled_time 18 | 19 | 20 | 21 | t.timestamps 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /app/views/league_signups/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

<%= notice %>

3 | 4 |

League Signups

5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | <% @league_signups.each_with_index do |league_signup, i| %> 17 | 18 | 20 | 21 | 22 | <% end %> 23 | 24 |
Signup number NameID
<%= i + 1 %> 19 | <%= league_signup.user&.display_name %><%= league_signup.id %>
25 | 26 |
-------------------------------------------------------------------------------- /app/views/tournaments/feed.builder: -------------------------------------------------------------------------------- 1 | xml.instruct! :xml, :version => "1.0" 2 | xml.rss :version => "2.0" do 3 | xml.channel do 4 | xml.title "ListFortress " 5 | xml.description "Crowdsourced X-Wing tournaments in order of upload" 6 | xml.link root_url 7 | 8 | @tournaments.each do |tournament| 9 | 10 | xml.item do 11 | xml.title tournament.name 12 | xml.description "#{tournament.participants_count} players battled at #{tournament.location}" 13 | xml.pubDate tournament.created_at.to_s(:rfc822) 14 | xml.link tournament_url(tournament) 15 | xml.guid tournament_url(tournament) 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery with: :exception 3 | helper_method :current_user 4 | 5 | def authenticate 6 | redirect_to '/league', notice: 'You have to sign in with slack to do that' unless user_signed_in? 7 | end 8 | 9 | def current_user 10 | @current_user ||= User.find(session[:user_id]) if session[:user_id] 11 | end 12 | 13 | def user_signed_in? 14 | # converts current_user to a boolean by negating the negation 15 | !!current_user 16 | end 17 | 18 | def current_user=(user) 19 | session[:user_id] = user&.id 20 | @current_user = user 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Add additional assets to the asset load path. 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | # Add Yarn node_modules folder to the asset load path. 9 | Rails.application.config.assets.paths << Rails.root.join('node_modules') 10 | 11 | # Precompile additional assets. 12 | # application.js, application.css, and all non-JS/CSS in the app/assets 13 | # folder are already added. 14 | # Rails.application.config.assets.precompile += %w( admin.js admin.css ) 15 | -------------------------------------------------------------------------------- /app/views/season_seven_surveys/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 | 3 |

Season Seven Signups

4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | <% @season_seven_surveys.each do |season_seven_survey| %> 16 | 17 | 18 | 19 | 20 | 21 | <% end %> 22 | 23 |
Signup number Name
<%= season_seven_survey.id %><%= season_seven_survey.user.display_name %>
24 | 25 |
26 | 27 | <%= link_to 'Back to League Home', '/league' %> 28 |
-------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /db/migrate/20210321231955_add_service_name_to_active_storage_blobs.active_storage.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from active_storage (originally 20190112182829) 2 | class AddServiceNameToActiveStorageBlobs < ActiveRecord::Migration[6.0] 3 | def up 4 | unless column_exists?(:active_storage_blobs, :service_name) 5 | add_column :active_storage_blobs, :service_name, :string 6 | 7 | if configured_service = ActiveStorage::Blob.service.name 8 | ActiveStorage::Blob.unscoped.update_all(service_name: configured_service) 9 | end 10 | 11 | change_column :active_storage_blobs, :service_name, :string, null: false 12 | end 13 | end 14 | 15 | def down 16 | remove_column :active_storage_blobs, :service_name 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | # 7 | default: &default 8 | host: 127.0.0.1 9 | adapter: postgresql 10 | pool: 5 11 | timeout: 5000 12 | user: <%= ENV["db_username"] %> 13 | password: <%= ENV["db_password"] %> 14 | 15 | 16 | development: 17 | <<: *default 18 | database: listfortress_development 19 | 20 | # Warning: The database defined as "test" will be erased and 21 | # re-generated from your development database when you run "rake". 22 | # Do not set this db to the same as development or production. 23 | test: 24 | <<: *default 25 | database: listfortress_test 26 | 27 | production: 28 | <<: *default 29 | database: listfortress_production -------------------------------------------------------------------------------- /app/views/layouts/_navbar.html.erb: -------------------------------------------------------------------------------- 1 | 22 | -------------------------------------------------------------------------------- /db/migrate/20190111224922_create_matches.rb: -------------------------------------------------------------------------------- 1 | class CreateMatches < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :matches do |t| 4 | t.references :player1, polymorphic: true, index: true 5 | t.integer :player1_points 6 | t.column :player1_xws, 'jsonb' 7 | 8 | t.references :player2, polymorphic: true, index: true 9 | t.integer :player2_points 10 | t.column :player2_xws, 'jsonb' 11 | 12 | t.references :winner, polymorphic: true, index: true 13 | t.references :round, foreign_key: true 14 | 15 | t.string :result 16 | t.string :logfile_url 17 | t.integer :match_state 18 | t.datetime :scheduled_time 19 | t.boolean :extended 20 | t.boolean :locked 21 | 22 | t.timestamps 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /app/models/league_participant.rb: -------------------------------------------------------------------------------- 1 | class LeagueParticipant < ApplicationRecord 2 | belongs_to :user, optional: true 3 | belongs_to :division, optional: true 4 | has_one :season, through: :division 5 | has_many :wins, as: :winner, class_name: 'Match' 6 | 7 | def matches 8 | Match.where( 9 | '(player1_id = :id AND player1_type = :type) OR (player2_id = :id AND player2_type = :type)', 10 | id: id, type: 'LeagueParticipant' 11 | ).includes(:player1, :player2) 12 | end 13 | 14 | def name 15 | return user.display_name if user 16 | 17 | return list_juggler_name if list_juggler_name 18 | 19 | id.to_s 20 | end 21 | 22 | def promote 23 | self.promotion = 1 24 | save 25 | end 26 | 27 | def demote 28 | self.promotion = -1 29 | save 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative "boot" 2 | 3 | require "rails/all" 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module ListFortress 10 | class Application < Rails::Application 11 | # Initialize configuration defaults for originally generated Rails version. 12 | config.load_defaults 5.2 13 | 14 | # Configuration for the application, engines, and railties goes here. 15 | # 16 | # These settings can be overridden in specific environments using the files 17 | # in config/environments, which are processed later. 18 | # 19 | # config.time_zone = "Central Time (US & Canada)" 20 | # config.eager_load_paths << Rails.root.join("extras") 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /app/views/rounds/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= bootstrap_form_for(@round) do |form| %> 2 | 3 |

4 |

5 |
6 | <%= form.collection_select(:roundtype_id, Roundtype.all, :id, :name, label: 'Round Type:') %> 7 |
8 |
9 | <%= form.number_field(:round_number, required: true, label: 'Round #:')%> 10 |
11 |
12 | <%= form.number_field(:match_number, value: @round.matches.size, required: true, label: '# of Matches:')%> 13 |
14 |
15 |

16 |

17 |

18 | <%= form.submit('Submit', class: 'btn btn-success') %> 19 | <%= link_to 'Back to Tournament', @round.tournament, {class: 'btn btn-danger'} %> 20 |
21 |

22 | <% end %> 23 | -------------------------------------------------------------------------------- /app/serializers/api/v1/tournament_details_serializer.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::TournamentDetailsSerializer < ActiveModel::Serializer 2 | #attributes(*Tournament.attribute_names.map(&:to_sym)) 3 | attribute :id 4 | attribute :name 5 | attribute :location 6 | attribute :state 7 | attribute :country 8 | attribute :date 9 | attribute :format_id 10 | attribute :version_id 11 | attribute :tournament_type_id 12 | attribute :created_at 13 | attribute :updated_at 14 | 15 | has_many :participants, serializer: Api::V1::ParticipantSerializer do 16 | include_data(true) 17 | link(:related) {api_v1_participants_path(tournament_id: object.id)} 18 | end 19 | has_many :rounds, serializer: Api::V1::RoundSerializer do 20 | include_data(true) 21 | link(:related) {api_v1_rounds_path(tournament_id: object.id)} 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's 5 | // vendor/assets/javascripts directory can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // compiled file. JavaScript code in this file should be added after the last require_* statement. 9 | // 10 | // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | //= require rails-ujs 14 | //= require activestorage 15 | //= require turbolinks 16 | //= require jquery3 17 | //= require popper 18 | //= require bootstrap-sprockets 19 | //= require_tree . -------------------------------------------------------------------------------- /app/assets/stylesheets/application.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's 6 | * vendor/assets/stylesheets directory can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS 10 | * files in this directory. Styles in this file should be added after the last require_* statement. 11 | * It is generally better to create a new file per style scope. 12 | * 13 | */ 14 | @import "bootstrap"; 15 | @import "rails_bootstrap_forms"; 16 | @import "font-awesome-sprockets"; 17 | @import "font-awesome"; 18 | @import 'fonts/xwing-miniatures'; -------------------------------------------------------------------------------- /config/application.yml.sample: -------------------------------------------------------------------------------- 1 | # Create a copy of this file named application.yml and add secrets inside the '' as needed. 2 | # The db credentials are the only set you have to fill out, the rest are optional 3 | 4 | db_username: '' 5 | db_password: '' 6 | 7 | # Used for user auth for the league 8 | slack_client_id: '' 9 | slack_client_secret: '' 10 | slack_signing_secret: '' 11 | 12 | #currently unused but could be an alternitive auth provider 13 | google_client_id: '' 14 | gooogle_client_secret: '' 15 | 16 | # used for league log file storage via ActiveStorage 17 | aws_access_key_id: '' 18 | aws_secret_access_key: '' 19 | aws_bucket: '' 20 | aws_region: '' 21 | 22 | # helpful env variables you might want. Just uncomment in your application.yml file to enable 23 | 24 | # used to disable rails checks that prevent you from dropping your local db. 25 | # DISABLE_DATABASE_ENVIRONMENT_CHECK: '1' 26 | 27 | # OMNIAUTH_SLACK_DEBUG: 'true' 28 | -------------------------------------------------------------------------------- /lib/tasks/assign_league_promotions.rake: -------------------------------------------------------------------------------- 1 | desc 'Assign all promotions and demotions' 2 | task assign_league_promotions: :environment do 3 | season = Season.find_by(season_number: 11) 4 | # the number of players to promote per tier. 5 | # First item nil since divisions start at tier 1 6 | promote = [nil, 0, 3, 2, 2] 7 | demote = [nil, 6, 3, 2, 0] # same with demotions 8 | 9 | season.divisions.each do |division| 10 | puts 'assigning promotions for division ' + division.name 11 | 12 | participants = division.league_participants.order( 13 | score: :desc, mov: :desc, id: :desc 14 | ) 15 | next if participants.blank? 16 | 17 | promote_number = promote[division.tier] 18 | demote_number = demote[division.tier] 19 | 20 | promote_number.times do |i| 21 | participants[i].promote 22 | end 23 | 24 | demote_number.times do |i| 25 | participants[-1 - i].demote 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | /db/*.sqlite3-journal 13 | 14 | # Ignore all logfiles and tempfiles. 15 | /log/* 16 | /tmp/* 17 | !/log/.keep 18 | !/tmp/.keep 19 | 20 | # Ignore uploaded files in development 21 | /storage/* 22 | !/storage/.keep 23 | 24 | /node_modules 25 | /yarn-error.log 26 | 27 | /public/assets 28 | .byebug_history 29 | 30 | # Ignore master key for decrypting credentials and more. 31 | /config/master.key 32 | 33 | # Ignore application configuration 34 | /config/application.yml 35 | 36 | # Ignore vscode debugger files 37 | /.vscode -------------------------------------------------------------------------------- /bin/update: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby.exe 2 | require 'fileutils' 3 | include FileUtils 4 | 5 | # path to your application root. 6 | APP_ROOT = File.expand_path('..', __dir__) 7 | 8 | def system!(*args) 9 | system(*args) || abort("\n== Command #{args} failed ==") 10 | end 11 | 12 | chdir APP_ROOT do 13 | # This script is a way to update your development environment automatically. 14 | # Add necessary update steps to this file. 15 | 16 | puts '== Installing dependencies ==' 17 | system! 'gem install bundler --conservative' 18 | system('bundle check') || system!('bundle install') 19 | 20 | # Install JavaScript dependencies if using Yarn 21 | # system('bin/yarn') 22 | 23 | puts "\n== Updating database ==" 24 | system! 'bin/rails db:migrate' 25 | 26 | puts "\n== Removing old logs and tempfiles ==" 27 | system! 'bin/rails log:clear tmp:clear' 28 | 29 | puts "\n== Restarting application server ==" 30 | system! 'bin/rails restart' 31 | end 32 | -------------------------------------------------------------------------------- /app/views/league/interdivisional.html.erb: -------------------------------------------------------------------------------- 1 |
2 | 3 |

Create an Interdivisional Match

4 |
5 |

6 | Interdivisional games are for when you have trouble scheduling games with the members of your division.

7 | You can only schedule games with players of other divisions that are in the same tier.

8 | To find a game, please join your tier’s channel in slack e.g. #4_outerrim and post your request or find an active player in your tier and send a dm. 9 | Please schedule the game before using this form to create the match. 10 |

11 |
12 | 13 | <% if @participants.present? %> 14 | 15 | <%= bootstrap_form_tag url: '/league/interdivisional' do |f| %> 16 | <%= f.select :player2_id, @participants.collect{|p| [p.name, p.id]}, label: 'Opponent:' %> 17 | <%= f.submit %> 18 | <% end %> 19 | 20 | <% else %> 21 |

<%="Something went wrong, please try reloading the page"%>

22 | <% end %> 23 | 24 | 25 |
-------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # The following keys must be escaped otherwise they will not be retrieved by 20 | # the default I18n backend: 21 | # 22 | # true, false, on, off, yes, no 23 | # 24 | # Instead, surround them with single quotes. 25 | # 26 | # en: 27 | # 'true': 'foo' 28 | # 29 | # To learn more, please read the Rails Internationalization guide 30 | # available at https://guides.rubyonrails.org/i18n.html. 31 | 32 | en: 33 | hello: "Hello world" 34 | -------------------------------------------------------------------------------- /lib/tasks/set_match_winner_type.rake: -------------------------------------------------------------------------------- 1 | # Matches were made polymorphic after some work on them was done and many were saved 2 | # before I noticed that the type wasn't also being set. This task is to fix that issue 3 | desc 'Fix Matches that are missing a playerX_type or winner_type' 4 | task set_match_winner_type: :environment do 5 | league_matches = Match.where( 6 | 'league_match is true and winner_type is null and winner_id is not null' 7 | ) 8 | puts "Fixing #{league_matches.size} league matches" 9 | league_matches.each do |match| 10 | match.winner_type = 'LeagueParticipant' 11 | match.save 12 | end 13 | 14 | normal_matches = Match.where('league_match is null and player1_type is null') 15 | puts "Fixing #{normal_matches.size} normal matches" 16 | 17 | normal_matches.each do |match| 18 | match.player1_type = 'Participant' 19 | match.player2_type = 'Participant' 20 | match.winner_type = 'Participant' if match.winner_id.present? 21 | 22 | match.save 23 | end 24 | 25 | end -------------------------------------------------------------------------------- /app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ApplicationRecord 2 | has_many :identities 3 | has_many :league_participants 4 | has_one :season_seven_survey 5 | has_many :league_signups 6 | has_one :address 7 | 8 | def self.find_with_omniauth(auth) 9 | find_by(uid: auth['uid'], provider: auth['provider']) 10 | end 11 | 12 | # TODO: handle future seasons better 13 | def current_league_participant 14 | LeagueParticipant 15 | .joins(:season) 16 | .where('user_id = ? AND seasons.season_number = ?', id, Season::CURRENT_SEASON) 17 | .order(:created_at) 18 | .first 19 | end 20 | 21 | def self.create_with_omniauth(auth) 22 | user = User.create( 23 | name: auth&.info&.name, 24 | email: auth&.info&.email, 25 | display_name: auth&.info&.nickname 26 | ) 27 | 28 | if auth['provider'] == 'slack' 29 | user.slack_avatar = auth&.info&.image 30 | user.league_eligible = true 31 | user.slack_id = auth&.info&.user_id 32 | end 33 | 34 | user.save 35 | user 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /db/migrate/20190218190306_create_active_storage_tables.active_storage.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from active_storage (originally 20170806125915) 2 | class CreateActiveStorageTables < ActiveRecord::Migration[5.2] 3 | def change 4 | create_table :active_storage_blobs do |t| 5 | t.string :key, null: false 6 | t.string :filename, null: false 7 | t.string :content_type 8 | t.text :metadata 9 | t.bigint :byte_size, null: false 10 | t.string :checksum, null: false 11 | t.datetime :created_at, null: false 12 | 13 | t.index [ :key ], unique: true 14 | end 15 | 16 | create_table :active_storage_attachments do |t| 17 | t.string :name, null: false 18 | t.references :record, null: false, polymorphic: true, index: false 19 | t.references :blob, null: false 20 | 21 | t.datetime :created_at, null: false 22 | 23 | t.index [ :record_type, :record_id, :name, :blob_id ], name: "index_active_storage_attachments_uniqueness", unique: true 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /test/system/tournaments_test.rb: -------------------------------------------------------------------------------- 1 | require "application_system_test_case" 2 | 3 | class TournamentsTest < ApplicationSystemTestCase 4 | setup do 5 | @tournament = tournaments(:one) 6 | end 7 | 8 | test "visiting the index" do 9 | visit tournaments_url 10 | assert_selector "h1", text: "Tournaments" 11 | end 12 | 13 | test "creating a Tournament" do 14 | visit tournaments_url 15 | click_on "New Tournament" 16 | 17 | click_on "Create Tournament" 18 | 19 | assert_text "Tournament was successfully created" 20 | click_on "Back" 21 | end 22 | 23 | test "updating a Tournament" do 24 | visit tournaments_url 25 | click_on "Edit", match: :first 26 | 27 | click_on "Update Tournament" 28 | 29 | assert_text "Tournament was successfully updated" 30 | click_on "Back" 31 | end 32 | 33 | test "destroying a Tournament" do 34 | visit tournaments_url 35 | page.accept_confirm do 36 | click_on "Destroy", match: :first 37 | end 38 | 39 | assert_text "Tournament was successfully destroyed" 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /test/system/participants_test.rb: -------------------------------------------------------------------------------- 1 | require "application_system_test_case" 2 | 3 | class ParticipantsTest < ApplicationSystemTestCase 4 | setup do 5 | @participant = participants(:one) 6 | end 7 | 8 | test "visiting the index" do 9 | visit participants_url 10 | assert_selector "h1", text: "Participants" 11 | end 12 | 13 | test "creating a Participant" do 14 | visit participants_url 15 | click_on "New Participant" 16 | 17 | click_on "Create Participant" 18 | 19 | assert_text "Participant was successfully created" 20 | click_on "Back" 21 | end 22 | 23 | test "updating a Participant" do 24 | visit participants_url 25 | click_on "Edit", match: :first 26 | 27 | click_on "Update Participant" 28 | 29 | assert_text "Participant was successfully updated" 30 | click_on "Back" 31 | end 32 | 33 | test "destroying a Participant" do 34 | visit participants_url 35 | page.accept_confirm do 36 | click_on "Destroy", match: :first 37 | end 38 | 39 | assert_text "Participant was successfully destroyed" 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /app/controllers/api/v1/base_controller.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::BaseController < ActionController::API 2 | 3 | rescue_from ActiveRecord::RecordNotFound, with: :not_found 4 | 5 | def not_found 6 | api_error(status: 404, errors: 'Not found') 7 | end 8 | 9 | protected 10 | def paginate(resource) 11 | # p params[:page] 12 | # p params[:per_page] 13 | resource = resource.page(params[:page] || 1) 14 | if params[:per_page] 15 | resource = resource.per_page(params[:per_page]) 16 | end 17 | 18 | resource 19 | end 20 | 21 | # expects paginated resource! 22 | def meta_attributes(object) 23 | { 24 | current_page: object.current_page, 25 | next_page: object.next_page, 26 | prev_page: object.previous_page, 27 | total_pages: object.total_pages, 28 | total_count: object.total_entries 29 | } 30 | end 31 | 32 | def api_error(status: 500, errors: []) 33 | puts errors.full_messages if errors.respond_to?(:full_messages) 34 | 35 | render json: Api::V1::ErrorSerializer.new(status, errors).as_json, status: status 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /app/controllers/seasons_controller.rb: -------------------------------------------------------------------------------- 1 | class SeasonsController < ApplicationController 2 | before_action :set_season, only: :show 3 | 4 | def index 5 | @seasons = Season.all.order(:season_number) 6 | end 7 | 8 | def show 9 | respond_to do |format| 10 | format.html 11 | format.csv { 12 | send_data @season.to_csv, 13 | filename: "vassal_league_season_#{@season.season_number}_#{Time.new.strftime('%Y-%m-%d')}.csv" 14 | } 15 | end 16 | end 17 | 18 | private 19 | 20 | def set_season 21 | @season = Season.includes(:divisions).find_by(season_number: params['season_number']) 22 | rescue ActiveRecord::RecordNotFound 23 | render(file: File.join(Rails.root, 'public/404.html'), status: 404, layout: false) 24 | # handle not found error 25 | rescue ActiveRecord::ActiveRecordError 26 | render(file: File.join(Rails.root, 'public/404.html'), status: 404, layout: false) 27 | # handle other ActiveRecord errors 28 | rescue StandardError 29 | render(file: File.join(Rails.root, 'public/404.html'), status: 404, layout: false) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /test/system/league_signups_test.rb: -------------------------------------------------------------------------------- 1 | require "application_system_test_case" 2 | 3 | class LeagueSignupsTest < ApplicationSystemTestCase 4 | setup do 5 | @league_signup = league_signups(:one) 6 | end 7 | 8 | test "visiting the index" do 9 | visit league_signups_url 10 | assert_selector "h1", text: "League Signups" 11 | end 12 | 13 | test "creating a League signup" do 14 | visit league_signups_url 15 | click_on "New League Signup" 16 | 17 | click_on "Create League signup" 18 | 19 | assert_text "League signup was successfully created" 20 | click_on "Back" 21 | end 22 | 23 | test "updating a League signup" do 24 | visit league_signups_url 25 | click_on "Edit", match: :first 26 | 27 | click_on "Update League signup" 28 | 29 | assert_text "League signup was successfully updated" 30 | click_on "Back" 31 | end 32 | 33 | test "destroying a League signup" do 34 | visit league_signups_url 35 | page.accept_confirm do 36 | click_on "Destroy", match: :first 37 | end 38 | 39 | assert_text "League signup was successfully destroyed" 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lib/tasks/redo_bcp_matches.rake: -------------------------------------------------------------------------------- 1 | desc 'Fix BCP Matches that have the wrong participants' 2 | task redo_bcp_matches: :environment do 3 | # There was a bug in the BCP importer that matched Participants 4 | # by just name instead of name and tournament 5 | # This rake task is designed to go back and fix those matches 6 | affected_tournaments = [495, 505, 510, 568, 583, 648, 690, 717].freeze 7 | 8 | def fix_match(match, tournament_id) 9 | player1_name = match&.player1&.name 10 | player2_name = match&.player2&.name 11 | winner_name = match&.winner&.name 12 | 13 | match.player1 = Participant.find_by(name: player1_name, tournament_id: tournament_id) 14 | match.player2 = Participant.find_by(name: player2_name, tournament_id: tournament_id) 15 | match.winner = Participant.find_by(name: winner_name, tournament_id: tournament_id) 16 | 17 | match.save 18 | end 19 | 20 | affected_tournaments.each do |tournament_id| 21 | Tournament.find(tournament_id).rounds.each do |round| 22 | round.matches.each do |match| 23 | fix_match(match, tournament_id) 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Alex Raubach 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ListFortress 5 | <%= csrf_meta_tags %> 6 | <%= csp_meta_tag %> 7 | 8 | <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> 9 | <%= render 'layouts/google_analytics' %> 10 | <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | <%= render 'layouts/navbar'%> 22 | <% flash.each do |key, value| %> 23 |
24 | <%= value %> 25 |
26 | <% end %> 27 | <%= yield %> 28 | 29 | 30 | -------------------------------------------------------------------------------- /config/storage.yml: -------------------------------------------------------------------------------- 1 | test: 2 | service: Disk 3 | root: <%= Rails.root.join("tmp/storage") %> 4 | 5 | local: 6 | service: Disk 7 | root: <%= Rails.root.join("storage") %> 8 | 9 | # Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) 10 | amazon: 11 | service: S3 12 | access_key_id: <%= ENV['aws_access_key_id'] %> 13 | secret_access_key: <%= ENV['aws_secret_access_key'] %> 14 | region: <%= ENV['aws_region'] %> 15 | bucket: <%= ENV['aws_bucket'] %> 16 | 17 | # Remember not to checkin your GCS keyfile to a repository 18 | # google: 19 | # service: GCS 20 | # project: your_project 21 | # credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> 22 | # bucket: your_own_bucket 23 | 24 | # Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) 25 | # microsoft: 26 | # service: AzureStorage 27 | # storage_account_name: your_account_name 28 | # storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> 29 | # container: your_container_name 30 | 31 | # mirror: 32 | # service: Mirror 33 | # primary: local 34 | # mirrors: [ amazon, google, microsoft ] 35 | -------------------------------------------------------------------------------- /app/models/round.rb: -------------------------------------------------------------------------------- 1 | class Round < ApplicationRecord 2 | belongs_to :tournament 3 | belongs_to :roundtype 4 | has_many :matches, dependent: :destroy 5 | attr_accessor :match_number 6 | 7 | def create_matches 8 | return if :match_number.zero? 9 | 10 | :match_number.times do |i| 11 | Match.new(round_id: id).save 12 | end 13 | end 14 | 15 | def sort_value 16 | # if swiss sort asc 17 | if roundtype_id == 1 18 | round_number 19 | # If top cut sort desc and make them come after the swiss rounds 20 | else 21 | 100 - round_number 22 | end 23 | end 24 | 25 | def serializable_hash(options={}) 26 | super({:only => [:id,:tournament_id,:roundtype_id,:round_number],:include => [:matches]}.merge(options||{})) 27 | end 28 | 29 | def update_from_json(round_data) 30 | if round_data['match_number'].present? 31 | matchnum = round_data['match_number'].to_i 32 | matchsize = matches.present? ? matches.size : 0 33 | if matchnum > matchsize 34 | (matchnum-matchsize).times do |i| 35 | Match.new(round_id:id).save 36 | end 37 | end 38 | end 39 | 40 | update(round_data) 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "fileutils" 3 | 4 | # path to your application root. 5 | APP_ROOT = File.expand_path('..', __dir__) 6 | 7 | def system!(*args) 8 | system(*args) || abort("\n== Command #{args} failed ==") 9 | end 10 | 11 | FileUtils.chdir APP_ROOT do 12 | # This script is a way to set up or update your development environment automatically. 13 | # This script is idempotent, so that you can run it at any time and get an expectable outcome. 14 | # Add necessary setup steps to this file. 15 | 16 | puts '== Installing dependencies ==' 17 | system! 'gem install bundler --conservative' 18 | system('bundle check') || system!('bundle install') 19 | 20 | # Install JavaScript dependencies 21 | system! 'bin/yarn' 22 | 23 | # puts "\n== Copying sample files ==" 24 | # unless File.exist?('config/database.yml') 25 | # FileUtils.cp 'config/database.yml.sample', 'config/database.yml' 26 | # end 27 | 28 | puts "\n== Preparing database ==" 29 | system! 'bin/rails db:prepare' 30 | 31 | puts "\n== Removing old logs and tempfiles ==" 32 | system! 'bin/rails log:clear tmp:clear' 33 | 34 | puts "\n== Restarting application server ==" 35 | system! 'bin/rails restart' 36 | end 37 | -------------------------------------------------------------------------------- /public/fonts/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2017 Geordan Rosario, Josh Derksen, and https://github.com/Hinny 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /test/system/season_seven_surveys_test.rb: -------------------------------------------------------------------------------- 1 | require "application_system_test_case" 2 | 3 | class SeasonSevenSurveysTest < ApplicationSystemTestCase 4 | setup do 5 | @season_seven_survey = season_seven_surveys(:one) 6 | end 7 | 8 | test "visiting the index" do 9 | visit season_seven_surveys_url 10 | assert_selector "h1", text: "Season Seven Surveys" 11 | end 12 | 13 | test "creating a Season seven survey" do 14 | visit season_seven_surveys_url 15 | click_on "New Season Seven Survey" 16 | 17 | click_on "Create Season seven survey" 18 | 19 | assert_text "Season seven survey was successfully created" 20 | click_on "Back" 21 | end 22 | 23 | test "updating a Season seven survey" do 24 | visit season_seven_surveys_url 25 | click_on "Edit", match: :first 26 | 27 | click_on "Update Season seven survey" 28 | 29 | assert_text "Season seven survey was successfully updated" 30 | click_on "Back" 31 | end 32 | 33 | test "destroying a Season seven survey" do 34 | visit season_seven_surveys_url 35 | page.accept_confirm do 36 | click_on "Destroy", match: :first 37 | end 38 | 39 | assert_text "Season seven survey was successfully destroyed" 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /app/assets/stylesheets/fonts/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2017 Geordan Rosario, Josh Derksen, and https://github.com/Hinny 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/views/seasons/show.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

3 | Overview for Vassal League Season <%= @season.season_number %> 4 |

5 | 6 | 12 | 13 | 14 | <% @season.divisions.each do |division| %> 15 | 16 | 17 | 18 | 19 | 20 | <% end %> 21 |
<%= division.letter %><%= division.tier %><%= link_to division.name, division_path(division) %>
22 | 23 | 29 | 30 |
31 | <%= link_to 'Export as CSV', season_path(season_number: @season.season_number, format: :csv), { class: "btn btn-primary" }%> 32 |
33 |
-------------------------------------------------------------------------------- /test/controllers/tournaments_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class TournamentsControllerTest < ActionDispatch::IntegrationTest 4 | setup do 5 | @tournament = tournaments(:one) 6 | end 7 | 8 | test "should get index" do 9 | get tournaments_url 10 | assert_response :success 11 | end 12 | 13 | test "should get new" do 14 | get new_tournament_url 15 | assert_response :success 16 | end 17 | 18 | test "should create tournament" do 19 | assert_difference('Tournament.count') do 20 | post tournaments_url, params: { tournament: { } } 21 | end 22 | 23 | assert_redirected_to tournament_url(Tournament.last) 24 | end 25 | 26 | test "should show tournament" do 27 | get tournament_url(@tournament) 28 | assert_response :success 29 | end 30 | 31 | test "should get edit" do 32 | get edit_tournament_url(@tournament) 33 | assert_response :success 34 | end 35 | 36 | test "should update tournament" do 37 | patch tournament_url(@tournament), params: { tournament: { } } 38 | assert_redirected_to tournament_url(@tournament) 39 | end 40 | 41 | test "should destroy tournament" do 42 | assert_difference('Tournament.count', -1) do 43 | delete tournament_url(@tournament) 44 | end 45 | 46 | assert_redirected_to tournaments_url 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /lib/tasks/export_winners.rake: -------------------------------------------------------------------------------- 1 | desc 'Creates a csv with all winners from a season' 2 | task export_winners: :environment do 3 | file = "#{Rails.root}/tmp/prizes.csv" 4 | 5 | winners = [] 6 | 7 | 8 | Season.where('season_number in (?)', [7, 8, 9]).each do |season| 9 | season.divisions.each do |div| 10 | if div.tier == 1 11 | div.league_participants.each { |lp| winners << lp } 12 | else 13 | div.league_participants 14 | .order(score: :desc, mov: :desc, id: :asc) 15 | .limit(1).each { |lp| winners << lp } 16 | end 17 | end 18 | end 19 | 20 | CSV.open(file, 'w') do |csv| 21 | csv << [ 22 | 'user_id', 'lp id', 'Public Name', 'Div tier', 23 | 'Div Letter', 'Season Number', 'Full Name', 24 | 'Email', 'street 1', 'street 2', 'city', 25 | 'province/state', 'zip', 'country' 26 | ] 27 | winners.each do |lp| 28 | csv << [ 29 | lp&.user&.id, lp.id, lp.name, lp.division.tier, lp.division.letter, 30 | lp.division.season.season_number, lp.user.name, lp.user.email, 31 | lp&.user&.address&.first_line, 32 | lp&.user&.address&.second_line, lp&.user&.address&.city, 33 | lp&.user&.address&.county_province, lp&.user&.address&.zip_or_postcode, 34 | lp&.user&.address&.country 35 | ] 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /app/models/match.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # The Match class holds an individual game/match. This class is used for both a 4 | # Tournament match where it belongs to Participants and a Round (which belongs to a tournament) 5 | # and the League match where match.league_match will be true and the players+winner will be LeagueParticipants 6 | class Match < ApplicationRecord 7 | belongs_to :round, optional: true 8 | belongs_to :player1, polymorphic: true, optional: true 9 | belongs_to :player2, polymorphic: true, optional: true 10 | belongs_to :winner, polymorphic: true, optional: true 11 | has_one_attached :log_file 12 | attr_accessor :player1_url_temp, :player2_url_temp 13 | 14 | def serializable_hash(options={}) 15 | super({ only: %I[id player1_id player1_points player2_id player2_points result winner_id] }.merge(options || {})) 16 | end 17 | 18 | def self.duplicate_exists?(first_id, second_id, league_match_bool) 19 | Match.where("league_match = :league_match_status AND ( 20 | (player1_id = :firstID and player2_id = :secondID) 21 | OR 22 | (player1_id = :secondID and player2_id = :firstID) 23 | )", 24 | firstID: first_id, secondID: second_id, 25 | league_match_status: league_match_bool) 26 | .exists? 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /test/controllers/participants_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ParticipantsControllerTest < ActionDispatch::IntegrationTest 4 | setup do 5 | @participant = participants(:one) 6 | end 7 | 8 | test "should get index" do 9 | get participants_url 10 | assert_response :success 11 | end 12 | 13 | test "should get new" do 14 | get new_participant_url 15 | assert_response :success 16 | end 17 | 18 | test "should create participant" do 19 | assert_difference('Participant.count') do 20 | post participants_url, params: { participant: { } } 21 | end 22 | 23 | assert_redirected_to participant_url(Participant.last) 24 | end 25 | 26 | test "should show participant" do 27 | get participant_url(@participant) 28 | assert_response :success 29 | end 30 | 31 | test "should get edit" do 32 | get edit_participant_url(@participant) 33 | assert_response :success 34 | end 35 | 36 | test "should update participant" do 37 | patch participant_url(@participant), params: { participant: { } } 38 | assert_redirected_to participant_url(@participant) 39 | end 40 | 41 | test "should destroy participant" do 42 | assert_difference('Participant.count', -1) do 43 | delete participant_url(@participant) 44 | end 45 | 46 | assert_redirected_to participants_url 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /app/views/rounds/show.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

3 |

4 | Round Number: <%= @round.round_number %> 5 | Round Type: <%= @round.roundtype_id.present? ? Roundtype.find_by(id:@round.roundtype_id).name : "" %> 6 | Matches: <%= @round.matches.size %> 7 |

8 |

9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | <% @round.matches.order(:id).each do |match| %> 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | <% end%> 34 |
Player1Player1 PointsPlayer2Player2 PointsResultWinner
<%=Participant.find_by(id:match.player1_id).present? ? Participant.find_by(id:match.player1_id).name : nil %><%=match.player1_points %><%=Participant.find_by(id:match.player2_id).present? ? Participant.find_by(id:match.player2_id).name : nil %><%=match.player2_points %><%=match.result %><%=Participant.find_by(id:match.winner_id).present? ? Participant.find_by(id:match.winner_id).name : nil %><%= link_to 'Edit', edit_match_path(match) %>
35 | 36 | <%= link_to 'Edit', edit_round_path(@round) %> | 37 | <%= link_to 'Back', tournament_path(@round.tournament_id) %> 38 | -------------------------------------------------------------------------------- /lib/tasks/generate_league_seeding_data.rake: -------------------------------------------------------------------------------- 1 | desc 'Creates a csv with all the data needed to seed S9' 2 | task generate_league_seeding_data: :environment do 3 | file = "#{Rails.root}/public/season10_signup_export.csv" 4 | 5 | CSV.open(file, 'w') do |csv| 6 | csv << ['user_id', 'user_name', 'time_zone_offset', 'desired_start_time', 7 | 'adjusted_start_time', 'other_info', 8 | 'Tier', 'promotion', 'wins', 'losses', 'mov', 'Season number'] 9 | 10 | LeagueSignup.all.where(season_number: 11).each do |signup| 11 | csv_data = [] 12 | 13 | csv_data << signup.user_id 14 | csv_data << signup.user.display_name 15 | offset = (ActiveSupport::TimeZone.new(signup.time_zone).utc_offset / 3600) 16 | csv_data << offset.to_s 17 | csv_data << signup.time 18 | csv_data << (signup.time - offset) % 24 19 | csv_data << signup.other 20 | 21 | lp = signup&.user&.league_participants&.order(id: :desc)&.first 22 | # this is faster and easier than sorting by season 23 | if lp 24 | csv_data << lp.division.tier 25 | csv_data << lp.promotion 26 | csv_data << lp.score 27 | csv_data << lp.losses 28 | csv_data << lp.mov 29 | csv_data << lp.season.season_number 30 | else 31 | csv_data << 'new player?' 32 | end 33 | 34 | csv << csv_data 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/tasks/set_legacy_league_promotion_status.rake: -------------------------------------------------------------------------------- 1 | desc 'Load historical league promotion status from List Juggler' 2 | task load_promotion_status_from_lj: :environment do 3 | SEASON_IDS = [2, 3, 5, 6, 7, 8].freeze 4 | BASE_URL = 'http://lists.starwarsclubhouse.com/api/v1/vassal_league_ranking/' 5 | 6 | SEASON_IDS.each do |season_number| 7 | 35.times do |i| 8 | url = BASE_URL + season_number.to_s + '/tier/' + i.to_s 9 | 10 | response = HTTParty.get(url) 11 | next unless response.code == 200 12 | 13 | division_rankings = response.parsed_response 14 | next if division_rankings.empty? 15 | 16 | puts 'Parsing Season ' + season_number.to_s + ' tier ' + i.to_s 17 | division_rankings['division_ranking'].each do |division| 18 | count = division['rankings'].count 19 | next if count.zero? 20 | 21 | division['rankings'].each do |rank_hash| 22 | if [0, 1].include?(rank_hash['rank']) 23 | player = LeagueParticipant.find_by(list_juggler_id: rank_hash['id']) 24 | player.promotion = 1 25 | player.save 26 | elsif rank_hash['rank'] == count || rank_hash['rank'] == count - 1 27 | player = LeagueParticipant.find_by(list_juggler_id: rank_hash['id']) 28 | player.promotion = -1 29 | player.save 30 | end 31 | end 32 | end 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /test/controllers/league_signups_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class LeagueSignupsControllerTest < ActionDispatch::IntegrationTest 4 | setup do 5 | @league_signup = league_signups(:one) 6 | end 7 | 8 | test "should get index" do 9 | get league_signups_url 10 | assert_response :success 11 | end 12 | 13 | test "should get new" do 14 | get new_league_signup_url 15 | assert_response :success 16 | end 17 | 18 | test "should create league_signup" do 19 | assert_difference('LeagueSignup.count') do 20 | post league_signups_url, params: { league_signup: { } } 21 | end 22 | 23 | assert_redirected_to league_signup_url(LeagueSignup.last) 24 | end 25 | 26 | test "should show league_signup" do 27 | get league_signup_url(@league_signup) 28 | assert_response :success 29 | end 30 | 31 | test "should get edit" do 32 | get edit_league_signup_url(@league_signup) 33 | assert_response :success 34 | end 35 | 36 | test "should update league_signup" do 37 | patch league_signup_url(@league_signup), params: { league_signup: { } } 38 | assert_redirected_to league_signup_url(@league_signup) 39 | end 40 | 41 | test "should destroy league_signup" do 42 | assert_difference('LeagueSignup.count', -1) do 43 | delete league_signup_url(@league_signup) 44 | end 45 | 46 | assert_redirected_to league_signups_url 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /app/views/matches/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= bootstrap_form_for(@match) do |form| %> 2 | 3 | 4 |
5 |
6 | <%= form.collection_select(:player1_id, Tournament.find_by(id:Round.find_by(id:@match.round_id).tournament_id).participants, :id, :name, label: 'Player1:', :include_blank => true) %> 7 |
8 |
9 | <%= form.number_field(:player1_points, label: 'Player 1 points:')%> 10 |
11 |
12 | 13 |
14 |
15 | <%= form.collection_select(:player2_id, Tournament.find_by(id:Round.find_by(id:@match.round_id).tournament_id).participants, :id, :name, label: 'Player2:', :include_blank => true) %> 16 |
17 |
18 | <%= form.number_field(:player2_points, label: 'Player 2 points:')%> 19 |
20 |
21 | 22 |
23 |
24 | <%= form.text_field(:result, label: 'Result') %> 25 |
26 |
27 | 28 | 29 |
30 |
31 | <%= form.collection_select(:winner_id, Tournament.find_by(id:Round.find_by(id:@match.round_id).tournament_id).participants, :id, :name, label: 'Winner:', include_blank: true) %> 32 |
33 |
34 | 35 |
36 | <%= form.submit('Submit', class: 'btn btn-success') %> 37 |
38 | <% end %> 39 | -------------------------------------------------------------------------------- /app/assets/stylesheets/scaffolds.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #fff; 3 | color: #333; 4 | margin: 33px; 5 | font-family: verdana, arial, helvetica, sans-serif; 6 | font-size: 13px; 7 | line-height: 18px; 8 | } 9 | 10 | p, ol, ul, td { 11 | font-family: verdana, arial, helvetica, sans-serif; 12 | font-size: 13px; 13 | line-height: 18px; 14 | } 15 | 16 | pre { 17 | background-color: #eee; 18 | padding: 10px; 19 | font-size: 11px; 20 | } 21 | 22 | a { 23 | color: #000; 24 | 25 | &:visited { 26 | color: #666; 27 | } 28 | 29 | &:hover { 30 | color: #fff; 31 | background-color: #000; 32 | } 33 | } 34 | 35 | th { 36 | padding-bottom: 5px; 37 | } 38 | 39 | td { 40 | padding: 0 5px 7px; 41 | } 42 | 43 | div { 44 | &.field, &.actions { 45 | margin-bottom: 10px; 46 | } 47 | } 48 | 49 | #notice { 50 | color: green; 51 | } 52 | 53 | .field_with_errors { 54 | padding: 2px; 55 | background-color: red; 56 | display: table; 57 | } 58 | 59 | #error_explanation { 60 | width: 450px; 61 | border: 2px solid red; 62 | padding: 7px 7px 0; 63 | margin-bottom: 20px; 64 | background-color: #f0f0f0; 65 | 66 | h2 { 67 | text-align: left; 68 | font-weight: bold; 69 | padding: 5px 5px 5px 15px; 70 | font-size: 12px; 71 | margin: -7px -7px 0; 72 | background-color: #c00; 73 | color: #fff; 74 | } 75 | 76 | ul li { 77 | font-size: 12px; 78 | list-style: square; 79 | } 80 | } 81 | 82 | label { 83 | display: block; 84 | } 85 | -------------------------------------------------------------------------------- /app/controllers/me_controller.rb: -------------------------------------------------------------------------------- 1 | class MeController < ApplicationController 2 | before_action :authenticate 3 | def home 4 | @address = set_address 5 | end 6 | 7 | def update 8 | current_user.display_name = params['display_name'] 9 | current_user.name = params['full_name'] 10 | 11 | @address = set_address 12 | update_address 13 | 14 | if current_user.save && @address.save 15 | respond_to do |format| 16 | format.html { redirect_to '/me', notice: 'User info was updated.' } 17 | end 18 | else 19 | respond_to do |format| 20 | format.html { redirect_to '/me', error: 'There was an error. Try again?' } 21 | end 22 | end 23 | end 24 | 25 | private 26 | 27 | def set_address 28 | return current_user.address if current_user.address.present? 29 | 30 | Address.new(user_id: current_user&.id) 31 | end 32 | 33 | def update_address 34 | @address.first_line = params['first_line'] 35 | @address.second_line = params['second_line'] 36 | @address.city = params['city'] 37 | @address.county_province = params['county_province'] 38 | @address.zip_or_postcode = params['zip_or_postcode'] 39 | @address.country = params['country'] 40 | @address.prize_level = params['prize_level'] 41 | end 42 | 43 | def match_params 44 | params.permit( 45 | :full_name, :display_name, 46 | :first_line, :second_line, :city, :county_province, 47 | :zip_or_postcode, :country, :prize_level 48 | ) 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /config/initializers/content_security_policy.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Define an application-wide content security policy 4 | # For further information see the following documentation 5 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy 6 | 7 | # Rails.application.config.content_security_policy do |policy| 8 | # policy.default_src :self, :https 9 | # policy.font_src :self, :https, :data 10 | # policy.img_src :self, :https, :data 11 | # policy.object_src :none 12 | # policy.script_src :self, :https 13 | # policy.style_src :self, :https 14 | # # If you are using webpack-dev-server then specify webpack-dev-server host 15 | # policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development? 16 | 17 | # # Specify URI for violation reports 18 | # # policy.report_uri "/csp-violation-report-endpoint" 19 | # end 20 | 21 | # If you are using UJS then enable automatic nonce generation 22 | # Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } 23 | 24 | # Set the nonce only to specific directives 25 | # Rails.application.config.content_security_policy_nonce_directives = %w(script-src) 26 | 27 | # Report CSP violations to a specified URI 28 | # For further information see the following documentation: 29 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only 30 | # Rails.application.config.content_security_policy_report_only = true 31 | -------------------------------------------------------------------------------- /test/controllers/season_seven_surveys_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SeasonSevenSurveysControllerTest < ActionDispatch::IntegrationTest 4 | setup do 5 | @season_seven_survey = season_seven_surveys(:one) 6 | end 7 | 8 | test "should get index" do 9 | get season_seven_surveys_url 10 | assert_response :success 11 | end 12 | 13 | test "should get new" do 14 | get new_season_seven_survey_url 15 | assert_response :success 16 | end 17 | 18 | test "should create season_seven_survey" do 19 | assert_difference('SeasonSevenSurvey.count') do 20 | post season_seven_surveys_url, params: { season_seven_survey: { } } 21 | end 22 | 23 | assert_redirected_to season_seven_survey_url(SeasonSevenSurvey.last) 24 | end 25 | 26 | test "should show season_seven_survey" do 27 | get season_seven_survey_url(@season_seven_survey) 28 | assert_response :success 29 | end 30 | 31 | test "should get edit" do 32 | get edit_season_seven_survey_url(@season_seven_survey) 33 | assert_response :success 34 | end 35 | 36 | test "should update season_seven_survey" do 37 | patch season_seven_survey_url(@season_seven_survey), params: { season_seven_survey: { } } 38 | assert_redirected_to season_seven_survey_url(@season_seven_survey) 39 | end 40 | 41 | test "should destroy season_seven_survey" do 42 | assert_difference('SeasonSevenSurvey.count', -1) do 43 | delete season_seven_survey_url(@season_seven_survey) 44 | end 45 | 46 | assert_redirected_to season_seven_surveys_url 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /app/models/season.rb: -------------------------------------------------------------------------------- 1 | class Season < ApplicationRecord 2 | has_many :divisions 3 | has_many :league_participants, through: :divisions 4 | validates_uniqueness_of :season_number 5 | 6 | CURRENT_SEASON = 12 # used for user.current_league_participant 7 | CURRENT_SIGNUP_NUMBER = 12 # used in league signup logic i.e. league_signups_controller and league home page 8 | SIGNUPS_OPEN = false 9 | INTERDIVISIONAL_ALLOWED = true 10 | 11 | def self.add_participant(season_number, user_id, div_tier, div_letter) 12 | season = Season.find_by(season_number: season_number) 13 | division = Division.find_by(tier: div_tier, letter: div_letter, season_id: season.id) 14 | 15 | if division.nil? 16 | puts "Nil division #{div_tier} #{div_letter}" 17 | return 18 | end 19 | 20 | league_participant = LeagueParticipant.create(user_id: user_id) 21 | division.add_participant(league_participant) 22 | end 23 | 24 | def to_param 25 | season_number 26 | end 27 | 28 | def to_csv 29 | header = %w[user_id id name score losses 30 | mov division_id division_name 31 | division_tier division_letter] 32 | 33 | CSV.generate(headers: true) do |csv| 34 | csv << header 35 | 36 | divisions.each do |division| 37 | division.league_participants.each do |player| 38 | output = [player.user.id, player.id, player.name, player.score, player.losses, 39 | player.mov, division.id, division.name, 40 | division.tier, division.letter] 41 | csv << output 42 | end 43 | end 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /lib/tasks/load_matches_from_lj.rake: -------------------------------------------------------------------------------- 1 | desc 'Load historical league matches from List Juggler' 2 | task load_matches_from_lj: :environment do 3 | SEASON_IDS = [2, 3, 5, 6, 7, 8].freeze 4 | BASE_URL = 'http://lists.starwarsclubhouse.com/api/v1/vassal_league_matches/'.freeze 5 | 6 | SEASON_IDS.each do |season_number| 7 | url = BASE_URL + season_number.to_s 8 | response = HTTParty.get(url) 9 | next unless response.code == 200 10 | 11 | season_matches = response.parsed_response 12 | 13 | season_matches['matches'].each do |match_json| 14 | match = Match.new 15 | match.locked = true 16 | match.logfile_url = match_json['logfile_url'] 17 | match.scheduled_time = match_json['scheduled_datetime'] 18 | 19 | match.player1 = LeagueParticipant.find_by(list_juggler_id: match_json.dig('player1', 'id')) 20 | match.player1_xws = match_json.dig('player1', 'xws') 21 | match.player1_points = match_json.dig('player1', 'score') 22 | 23 | match.player2 = LeagueParticipant.find_by(list_juggler_id: match_json.dig('player2', 'id')) 24 | match.player2_xws = match_json.dig('player2', 'xws') 25 | match.player2_points = match_json.dig('player2', 'score') 26 | 27 | if match_json['state'] == 'complete' && match.player2_points && match.player1_points 28 | if match.player2_points > match.player1_points 29 | match.winner = match.player2 30 | elsif match.player1_points > match.player2_points 31 | match.winner = match.player1 32 | end 33 | end 34 | 35 | match.save 36 | p match unless match.valid? 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /app/views/participants/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= bootstrap_form_for(@participant) do |form| %> 2 | 3 | 4 |
5 |
6 | <%= form.text_field(:name, label: 'Player Name') %> 7 |
8 |
9 | <%= form.number_field(:swiss_rank, required: true, label: 'Rank during Swiss')%> 10 |
11 |
12 | <%= form.number_field(:top_cut_rank, label: 'Top Cut Rank')%> 13 |
14 |
15 | 16 |
17 |
18 | <%= form.number_field(:score, max: 100, label: 'Number of Wins in Swiss')%> 19 |
20 |
21 | <%= form.number_field(:mov, label: 'Total Margin of Victory')%> 22 |
23 |
24 | <%= form.text_field(:sos, label: 'Strength of Schedule')%> 25 |
26 |
27 | 28 |
29 |
30 | <%= form.check_box(:dropped, label: 'Did this player drop?') %> 31 |
32 |
33 | <%= form.text_field(:squad_url, label: 'Optional Squad URL. Yet Another Squad Builder or Launch Bay Next only', placeholder: "https://yasb.app") %> 34 |
35 |
36 | 37 | <%= form.text_area(:list_json, readonly: true, label: 'Raw XWS. Adding a squad url will overwrite existing xws')%> 38 | 39 |
40 | <%= form.submit('Submit', class: 'btn btn-success') %> 41 | <%= link_to 'Back to Tournament', @participant.tournament, {class: 'btn btn-danger'} %> 42 |
43 | <% end %> 44 | -------------------------------------------------------------------------------- /lib/tasks/generate_season_seven_matches.rake: -------------------------------------------------------------------------------- 1 | desc 'Creates S7 and all the divisions and matches' 2 | task generate_season_seven_matches: :environment do 3 | DIVISION_NAMES = [ 4 | ['Coruscant'], 5 | ['Alderaan', 'Corellia', 'Kuat'], 6 | ['Chardaan', 'Kashyyyk', 'Myrkr', 'Nal Hutta', 'Manaan'], 7 | ['Bespin', 'Dagobah', 'Tatooine', 8 | 'Endor', 'Dantooine', 'Hoth', 9 | 'Yavin', 'Kamino', 'Mon Calamari', 'Mandalore'], 10 | ['Jakku', 'Nkllon', 'Csilla', 11 | 'Celwiss', 'Ilum', 'Plunder Moon', 12 | 'Bakura', 'The Redoubt', 'Nirauan', 13 | 'kariek', 'Lwhekk'] 14 | ].freeze 15 | 16 | season = Season.create(season_number: 7) 17 | 18 | DIVISION_NAMES.each_with_index do |tier_data, tier_number| 19 | tier_data.each_with_index do |tier_name, division_number| 20 | Division.create( 21 | season_id: season.id, 22 | tier: tier_number + 1, 23 | name: tier_name, 24 | letter: (division_number + 65).chr 25 | ) 26 | end 27 | end 28 | 29 | csv_text = File.open("#{Rails.root}/public/s7_divisions.csv") 30 | csv = CSV.parse(csv_text) 31 | csv.each do |user_info| 32 | user_id = user_info[0] 33 | # name = user_info[1] 34 | division_tier = user_info[2] 35 | division_letter = user_info[3] 36 | 37 | league_participant = LeagueParticipant.create(user_id: user_id) 38 | 39 | division = Division.find_by( 40 | tier: division_tier, 41 | letter: division_letter, 42 | season_id: season.id 43 | ) 44 | 45 | if division.nil? 46 | puts "Nil division " + division_tier + division_letter 47 | next 48 | end 49 | 50 | division.add_participant(league_participant) 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /lib/tasks/generate_season_seven_seeding_data.rake: -------------------------------------------------------------------------------- 1 | desc 'Creates a csv with all the data needed to seed S7' 2 | task generate_season_seven_seeding_data: :environment do 3 | file = "#{Rails.root}/season8.csv" 4 | CSV.open(file, 'w') do |csv| 5 | csv << ['id', 'name', 'time_zone_offset', 'desired_start_time', 'adjusted_start_time', 'provisional_tier', 'lj_name', 'wins in last season'] 6 | 7 | SeasonSevenSurvey.all.each do |record| 8 | csv_data = [] 9 | csv_data << record.user_id 10 | csv_data << record.display_name 11 | offset = (ActiveSupport::TimeZone.new(record.time_zone).utc_offset / 3600) 12 | csv_data << offset.to_s 13 | csv_data << record.time 14 | csv_data << (record.time + offset) % 24 15 | 16 | participant_ids = [record.s1_id, record.s2_id, record.s3_id, record.s4_id, record.s5_id, record.s6_id].compact 17 | provisional_ranking = 7 18 | last_name = '' 19 | last_season_wins = 0 20 | last_season_matches = 0 21 | if participant_ids.present? 22 | last_id = participant_ids[-1] 23 | participant = LeagueParticipant.find(last_id) 24 | provisional_ranking = participant.division.tier 25 | provisional_ranking -= participant.promotion if participant.promotion 26 | last_name = participant.list_juggler_name 27 | last_season_wins = Match.where(winner_id: last_id).count 28 | last_season_matches = Match.where(player1_id: last_id).count + Match.where(player2_id: last_id).count 29 | end 30 | csv_data << provisional_ranking 31 | csv_data << last_name 32 | csv_data << last_season_wins 33 | csv_data << last_season_matches - last_season_wins 34 | 35 | csv << csv_data 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /app/views/league_signups/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= bootstrap_form_with(model: league_signup, local: true) do |form| %> 2 | <% if league_signup.errors.any? %> 3 |
4 |

<%= pluralize(league_signup.errors.count, "error") %> prohibited this league_signup from being saved:

5 | 6 | 11 |
12 | <% end %> 13 | 14 |
15 | <%= form.text_field(:full_name, label: 'First and last name (not displayed publicly) *', value: current_user&.name) %> 16 |
17 |
18 | <%= form.text_field(:display_name, label: 'Name you want publicly displayed *', required: true, value: current_user&.display_name) %> 19 |
20 | 21 |
22 | <%= form.time_zone_select(:time_zone, nil, default: 'Eastern Time (US & Canada)') %> 23 |
24 |
25 | <%= form.number_field(:time, label: "Select your prefered match start hour. 20 = 8pm in your selected time zone. This will be used to roughly group people by prefered start time", max: 24, min: 0, required: true)%> 26 |
27 | 28 |
29 | <%# form.text_field(:email, label: "Email Address. This may have been imported from slack, please remove, change or keep it as you see fit.", value: current_user&.email) %> 30 |
31 | 32 |
33 | <%# form.text_field(:other, label: "If you missed season 7 but played in an earlier season AND you should be seeded Tier 4 or higher, please provide a link to your last division and say what tier you should be in.") %> 34 |
35 | 36 |
37 | <%= form.submit %> 38 |
39 | <% end %> 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # List Fortress 2 | 3 | 4 | List Fortress is a website for collecting and viewing tournament results for X-Wing Miniatures Second Edition. 5 | 6 | The collected data is used in [Pink Brain Matter](https://pinksquadron.dk/pbm/), [MetaWing](https://meta.listfortress.com/) and [Advanced Targeting Computer](http://advancedtargeting.computer/). 7 | 8 | Contributions are welcome. Feel free to make a pull request or send me a message if you'd like to coordinate a change. 9 | 10 | 11 | # Setup 12 | 13 | When building a new pc, I tried to document how I ended up installing and configuring everything. 14 | [Check out the more detailed write up](Setup.md) 15 | 16 | * Install [the version of Ruby found here](.ruby-version), a recent version of Node and Postgres. 17 | 18 | * Fork and download the repo: `git clone --recurse-submodules ` + the repo url 19 | 20 | * Check that the submodule files are present. If you didn't use `--recurse-submodules` then run `git submodule init` + `git submodule update` 21 | 22 | * Create an config file by running `cp config/application.yml.sample config/application.yml` and then provide the db username and password. 23 | Slack, Google and AWS keys are optional unless you want to use SSO and log file cloud storage. 24 | 25 | * Install the required gems: `bundle install` 26 | 27 | * Set up the database: `rails db:create db:migrate db:seed` 28 | 29 | * Run the task to import xwing_data2 from the submodule: `rails update_xwing_data` 30 | 31 | * Start the server: `rails server` or `rails s` 32 | 33 | 34 | # API 35 | 36 | List Fortress also offers an API for easily exporting tournament data. 37 | 38 | You can find a list of tournaments at `https://listfortress.com/api/v1/tournaments/ `. Just append a tournament's id to get the participant names, squads and match information if available. -------------------------------------------------------------------------------- /lib/tasks/load_participants_from_list_juggler.rake: -------------------------------------------------------------------------------- 1 | desc 'Load historical tournament data from List Juggler' 2 | task load_participants_from_lj: :environment do 3 | SEASON_IDS = [2, 3, 5, 6, 7, 8].freeze 4 | BASE_URL = 'http://lists.starwarsclubhouse.com/api/v1/vassal_league/'.freeze 5 | 6 | SEASON_IDS.each_with_index do |season_number, i| 7 | url = BASE_URL + season_number.to_s 8 | response = HTTParty.get(url) 9 | return false unless response.code == 200 10 | 11 | season_json = response.parsed_response 12 | 13 | season = Season.create( 14 | active: false, 15 | sign_up_active: false, 16 | locked: true, 17 | season_number: i + 1, 18 | name: season_json['name'] 19 | ) 20 | 21 | season_json['tiers'].each do |tier| 22 | tier['divisions'].each do |division_hash| 23 | case tier['tier_name'] 24 | when 'deepcore', 'deepcore' + (i + 1).to_s 25 | tier_number = 1 26 | when 'coreworlds', 'coreworlds' + (i + 1).to_s 27 | tier_number = 2 28 | when 'innerrim', 'innerrim' + (i + 1).to_s 29 | tier_number = 3 30 | when 'outerrim', 'outerrim' + (i + 1).to_s 31 | tier_number = 4 32 | when 'unknownreaches', 'unknownreaches' + (i + 1).to_s 33 | tier_number = 5 34 | end 35 | 36 | division = Division.create( 37 | name: division_hash['name'], 38 | season_id: season.id, 39 | tier: tier_number 40 | ) 41 | 42 | division_hash['players'].each do |player_hash| 43 | LeagueParticipant.create( 44 | list_juggler_name: player_hash['name'], 45 | list_juggler_id: player_hash['player_id'], 46 | division_id: division.id 47 | ) 48 | end 49 | end 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /app/views/divisions/show.html.erb: -------------------------------------------------------------------------------- 1 |
2 | 3 |

4 | <%= @division.name %> Division 5 |

6 | 7 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | <% @players.each_with_index do |participant, index| %> 27 | 28 | <%# @display_name = participant.user ? participant.user&.display_name : participant.list_juggler_name %> 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | <% end %> 37 |
Divisional RankPlayer NameWinsLossesMoV
<%= index + 1 %> <%= link_to(participant.name, league_participant_path(participant)) %><%= participant.score ? participant.score : '?' %><%= participant.losses ? participant.losses : '?' %><%= participant.mov ? participant.mov : '?' %>
38 | 39 | 48 | 49 |
-------------------------------------------------------------------------------- /lib/tasks/calculate_league_scores.rake: -------------------------------------------------------------------------------- 1 | desc 'Update all League Participant Scores and MoV for the current season' 2 | task calculate_league_scores: :environment do 3 | Season.where(active: true).each do |current_season| 4 | current_season.divisions.each do |division| 5 | # Coruscant players should play 2 additional games 6 | maximum_matches = division.tier == 1 ? 10 : 8 7 | puts 'Calculating scores for division ' + division.name 8 | 9 | division.league_participants.each do |player| 10 | mov = 0 11 | score = 0 12 | 13 | matches = Match 14 | .order(:updated_at) 15 | .limit(maximum_matches) 16 | .where( 17 | 'winner_id is not null and 18 | ((player1_id = :id AND player1_type = :type) 19 | OR (player2_id = :id AND player2_type = :type))', 20 | id: player.id, type: 'LeagueParticipant' 21 | ) 22 | 23 | matches.each do |match| 24 | score += 1 if match.winner_id == player.id 25 | 26 | next if match.player1_points.nil? || match.player2_points.nil? 27 | 28 | player_points_killed = 0 29 | opponent_points_killed = 0 30 | 31 | if match.player1 == player 32 | player_points_killed = match.player1_points 33 | opponent_points_killed = match.player2_points 34 | else 35 | player_points_killed = match.player2_points 36 | opponent_points_killed = match.player1_points 37 | end 38 | mov += 200 + player_points_killed - opponent_points_killed 39 | end 40 | 41 | player.score = score 42 | player.losses = matches.size - score 43 | player.mov = mov 44 | player.save 45 | end 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /lib/tasks/generate_league_matches_s1100.rake: -------------------------------------------------------------------------------- 1 | desc 'Creates S1100 and all the divisions and matches' 2 | task generate_league_matches_s1100: :environment do 3 | DIVISION_NAMES = [ 4 | ['Red Squadron', 'Blade Squadron', 'Warden Squadron', 'Green Squadron'] 5 | ].freeze 6 | 7 | season = Season.create(season_number: 1100, name: 'Nordic Vassal League Season One') 8 | 9 | DIVISION_NAMES.each_with_index do |tier_data, tier_number| 10 | tier_data.each_with_index do |tier_name, division_number| 11 | Division.create( 12 | season_id: season.id, 13 | tier: tier_number + 1, 14 | name: tier_name, 15 | letter: (division_number + 65).chr 16 | ) 17 | end 18 | end 19 | 20 | csv_text = File.open("#{Rails.root}/public/s1100.csv") 21 | csv = CSV.parse(csv_text) 22 | csv.each do |user_info| 23 | name = user_info[0] 24 | # name = user_info[1] 25 | division_tier = user_info[1] 26 | division_letter = user_info[2] 27 | 28 | league_participant = LeagueParticipant.create(list_juggler_name: name) 29 | 30 | division = Division.find_by( 31 | tier: division_tier, 32 | letter: division_letter, 33 | season_id: season.id 34 | ) 35 | 36 | if division.nil? 37 | puts 'Nil division ' + division_tier.to_s + division_letter.to_s 38 | next 39 | end 40 | 41 | division.add_participant(league_participant) 42 | end 43 | end 44 | 45 | def add_to_league(season_number, user_id, div_tier, div_letter) 46 | season = Season.find_by(season_number: season_number) 47 | 48 | division = Division.find_by( 49 | tier: div_tier, 50 | letter: div_letter, 51 | season_id: season.id 52 | ) 53 | 54 | puts 'Nil division ' + div_tier.to_S + div_letter.to_s if division.nil? 55 | 56 | league_participant = LeagueParticipant.create(user_id: user_id) 57 | 58 | division.add_participant(league_participant) 59 | end 60 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

If you are the application owner check the logs for more information.

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /lib/tasks/generate_league_matches_s1000.rake: -------------------------------------------------------------------------------- 1 | desc 'Creates S1001 and all the divisions and matches' 2 | task generate_league_matches_s1000: :environment do 3 | DIVISION_NAMES = [ 4 | ['Black Sun', 'Crimson Dawn'] 5 | ].freeze 6 | 7 | season = Season.create(season_number: 1002, name: 'X-Wing Hungarian Vassal League Season Three', active: true) 8 | 9 | DIVISION_NAMES.each_with_index do |tier_data, tier_number| 10 | tier_data.each_with_index do |tier_name, division_number| 11 | Division.create( 12 | season_id: season.id, 13 | tier: tier_number + 1, 14 | name: tier_name, 15 | letter: (division_number + 65).chr 16 | ) 17 | end 18 | end 19 | 20 | csv_text = File.open("#{Rails.root}/public/HVL_1002.csv") 21 | csv = CSV.parse(csv_text) 22 | csv.each do |user_info| 23 | name = user_info[0] 24 | # name = user_info[1] 25 | division_tier = user_info[1] 26 | division_letter = user_info[2] 27 | 28 | next if name.nil? 29 | 30 | league_participant = LeagueParticipant.create(list_juggler_name: name) 31 | 32 | division = Division.find_by( 33 | tier: division_tier, 34 | letter: division_letter, 35 | season_id: season.id 36 | ) 37 | 38 | if division.nil? 39 | puts 'Nil division ' + division_tier.to_s + division_letter.to_s 40 | next 41 | end 42 | 43 | division.add_participant(league_participant) 44 | end 45 | end 46 | 47 | def add_to_league(season_number, name, div_tier, div_letter) 48 | season = Season.find_by(season_number: season_number) 49 | 50 | division = Division.find_by( 51 | tier: div_tier, 52 | letter: div_letter, 53 | season_id: season.id 54 | ) 55 | 56 | puts 'Nil division ' + div_tier.to_S + div_letter.to_s if division.nil? 57 | 58 | league_participant = LeagueParticipant.create(list_juggler_name: name) 59 | 60 | division.add_participant(league_participant) 61 | end 62 | -------------------------------------------------------------------------------- /app/serializers/api/v1/error_serializer.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::ErrorSerializer 2 | UNKNOWN_ERROR = 'Something went wrong, no more info is available unforunately!'.freeze 3 | DEFAULT_POINTER = 'data'.freeze 4 | 5 | def initialize(status, errors) 6 | @status = status 7 | if errors.is_a? ActiveModel::Errors 8 | @errors = parse_am_errors(errors) 9 | else #it's an array or a string 10 | @errors = [errors].flatten 11 | end 12 | end 13 | 14 | def as_json 15 | { 16 | errors: errors 17 | } 18 | end 19 | 20 | def to_json 21 | as_json.to_json 22 | end 23 | 24 | private 25 | 26 | def parse_am_errors(errors) 27 | error_messages = errors.full_messages 28 | 29 | errors.map.with_index do |(k, v), i| 30 | ErrorDecorator.new(k, v, error_messages[i]) 31 | end 32 | end 33 | 34 | def errors 35 | @errors.map do |error| 36 | { 37 | status: @status, 38 | title: normalize_title(error), 39 | detail: normalize_error(error), 40 | source: { 41 | pointer: error_pointer(error) 42 | } 43 | } 44 | end 45 | end 46 | 47 | def normalize_title(error) 48 | error.try(:title) || error.try(:to_s) || UNKNOWN_ERROR 49 | end 50 | 51 | def normalize_error(error) 52 | error.try(:details) || error.try(:to_s) || UNKNOWN_ERROR 53 | end 54 | 55 | def error_pointer(error) 56 | if error.respond_to?(:pointer) 57 | error.pointer 58 | else 59 | DEFAULT_POINTER 60 | end 61 | end 62 | 63 | class ErrorDecorator 64 | def initialize(key, value, message) 65 | @key, @value, @message = key, value, message 66 | end 67 | 68 | def title 69 | @value 70 | end 71 | 72 | def details 73 | @value 74 | end 75 | 76 | def to_s 77 | @message 78 | end 79 | 80 | def pointer 81 | "data/attributes/#{@key.to_s}" 82 | end 83 | end 84 | end 85 | -------------------------------------------------------------------------------- /config/puma.rb: -------------------------------------------------------------------------------- 1 | # Puma can serve each request in a thread from an internal thread pool. 2 | # The `threads` method setting takes two numbers: a minimum and maximum. 3 | # Any libraries that use thread pools should be configured to match 4 | # the maximum value specified for Puma. Default is set to 5 threads for minimum 5 | # and maximum; this matches the default thread size of Active Record. 6 | # 7 | max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } 8 | min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } 9 | threads min_threads_count, max_threads_count 10 | 11 | # Specifies the `worker_timeout` threshold that Puma will use to wait before 12 | # terminating a worker in development environments. 13 | # 14 | worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" 15 | 16 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000. 17 | # 18 | port ENV.fetch("PORT") { 3000 } 19 | 20 | # Specifies the `environment` that Puma will run in. 21 | # 22 | environment ENV.fetch("RAILS_ENV") { "development" } 23 | 24 | # Specifies the `pidfile` that Puma will use. 25 | pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } 26 | 27 | # Specifies the number of `workers` to boot in clustered mode. 28 | # Workers are forked web server processes. If using threads and workers together 29 | # the concurrency of the application would be max `threads` * `workers`. 30 | # Workers do not work on JRuby or Windows (both of which do not support 31 | # processes). 32 | # 33 | # workers ENV.fetch("WEB_CONCURRENCY") { 2 } 34 | 35 | # Use the `preload_app!` method when specifying a `workers` number. 36 | # This directive tells Puma to first boot the application and load code 37 | # before forking the application. This takes advantage of Copy On Write 38 | # process behavior so workers use less memory. 39 | # 40 | # preload_app! 41 | 42 | # Allow puma to be restarted by `rails restart` command. 43 | plugin :tmp_restart 44 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | # redirect www traffic to regular domain 3 | match "(*any)", 4 | to: redirect(subdomain: ""), 5 | via: :all, 6 | constraints: { subdomain: "www" } 7 | 8 | resources :league_signups 9 | get 'league_participant/:id', to: 'league_participant#show', as: 'league_participant' 10 | get 'tournaments/feed', to: 'tournaments#feed', as: 'tournament_feed' 11 | resources :seasons, only: [:index, :show], param: :season_number 12 | resources :divisions, only: [:show] 13 | resources :season_seven_surveys 14 | resources :participants 15 | resources :tournaments 16 | resources :rounds 17 | resources :matches 18 | 19 | # get 'login', to: redirect('/auth/slack'), as: 'login' 20 | get 'logout', to: 'sessions#destroy', as: 'logout' 21 | get 'auth/failure', to: 'sessions#failure' 22 | match '/auth/:provider/callback', to: 'sessions#create', via: [:get, :post] 23 | get 'auth/:provider/callback', to: 'sessions#create' 24 | match '/logout', to: 'sessions#destroy', via: [:get, :post] 25 | 26 | # get 'home', to: 'home#show' 27 | get 'about', to: 'home#about' 28 | 29 | get 'league/interdivisional', to: 'league#interdivisional', as: 'interdivisional' 30 | post 'league/interdivisional', to: 'league#create_interdivisional' 31 | get 'league', to: 'league#index', as: 'league' 32 | get 'me', to: 'me#home' 33 | post 'me', to: 'me#update' 34 | 35 | root to: 'tournaments#index' 36 | 37 | # api 38 | namespace :api do 39 | namespace :v1 do 40 | resources :tournaments, only: [:index, :show] do 41 | resources :participants, only: [:show] 42 | resources :rounds, only: [:show] do 43 | resources :matches, only: [:show] 44 | end 45 | end 46 | 47 | resources :seasons, only: [:index, :show] 48 | 49 | end 50 | end 51 | 52 | # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html 53 | end 54 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

Maybe you tried to change something you didn't have access to.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /app/controllers/api/v1/tournaments_controller.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::TournamentsController < Api::V1::BaseController 2 | before_action :load_resource 3 | 4 | def index 5 | tournaments = @users 6 | 7 | render json: tournaments, each_serializer: Api::V1::TournamentSerializer 8 | end 9 | 10 | def show 11 | tournament = Tournament.find(params[:id]) 12 | 13 | render json: tournament, include: ['participants', 'rounds', 'rounds.matches'], serializer: Api::V1::TournamentDetailsSerializer 14 | end 15 | 16 | private 17 | def load_resource 18 | validate_params 19 | case params[:action].to_sym 20 | when :index 21 | @users = Tournament.all.updated_after(params[:updatedafter]) # paginate(Tournament.all) 22 | when :show 23 | @user = Tournament.find(params[:id]) 24 | end 25 | end 26 | 27 | def validate_params 28 | if params[:updatedafter].present? 29 | if !validate_updated_after(params[:updatedafter]) 30 | params[:updatedafter] = nil 31 | self.api_error(status:404, errors:['invalid updatedafter, requires UTC iso8601 timestamp']) 32 | end 33 | end 34 | end 35 | 36 | def validate_updated_after (updated_after) 37 | # p updated_after 38 | # raises ArgumentError if format invalid 39 | Time.iso8601(updated_after) 40 | true 41 | rescue ArgumentError => e 42 | # p e 43 | false 44 | end 45 | 46 | def create_params 47 | normalized_params.permit( 48 | :name, tournament: 49 | [ 50 | :id, :name, :participant_number, 51 | :type, :format_id, :country, 52 | :state, :organizer_id, :location, 53 | :patch_id, :tournament_type_id, :date, 54 | :tabletop_url, :cryodex_json, :round_number 55 | ] 56 | ) 57 | end 58 | 59 | def update_params 60 | create_params 61 | end 62 | 63 | def normalized_params 64 | ActionController::Parameters.new( 65 | ActiveModelSerializers::Deserialization.jsonapi_parse(params) 66 | ) 67 | end 68 | end 69 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

You may have mistyped the address or the page may have moved.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /app/views/tournaments/index.html.erb: -------------------------------------------------------------------------------- 1 |

Tournaments

2 |
3 | 4 |
5 | <%= will_paginate @tournaments, renderer: WillPaginate::ActionView::BootstrapLinkRenderer, 6 | list_classes: %w(pagination justify-content-center) %> 7 |
8 | 9 |
" > 10 | <%= render "filter" %> 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | <% @tournaments.order(date: :desc).each do |tournament| %> 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 42 | <% end %> 43 | 44 |
NameLocationStateCountryDateFormatTypePlayers
<%= link_to tournament.name, tournament %><%= tournament.location%><%= tournament.state%><%= tournament.country%><%= tournament.date.strftime('%y/%m/%d')%><%= tournament.format&.name%><%= tournament.tournament_type&.name%><%= tournament.participants.size%> 39 | 41 |
45 | 46 |
47 | <%= will_paginate @tournaments, renderer: WillPaginate::ActionView::BootstrapLinkRenderer, list_classes: %w(pagination justify-content-center) %> 48 |
49 | 50 |
51 | <%= link_to 'New Tournament', new_tournament_path %> 52 |
53 |
54 |
55 | -------------------------------------------------------------------------------- /app/views/matches/_leagueform.erb: -------------------------------------------------------------------------------- 1 | <%= bootstrap_form_for(@match) do |form| %> 2 | 3 | <%# Used to show which file was selected %> 4 | <%= javascript_tag do %> 5 | $(document).on('ready turbolinks:load', function() { 6 | $('.custom-file-input').change(function(){ 7 | $('.custom-file-label').text(this.value); 8 | }); 9 | }); 10 | <% end %> 11 | 12 |
13 |
14 | <%= form.number_field(:player1_points, max: 200, label: 'Points killed by Player 1 / ' + @match.player1&.name )%> 15 |
16 | 17 |
18 | <%= form.number_field(:player2_points, max: 200, label: 'Points killed by Player 2 / ' + @match.player2&.name)%> 19 |
20 |
21 | <%# form.datetime_select(:scheduled_time, label: 'Scheduled Match Time:')%> 22 | 23 |
24 |
25 | <%= form.text_field(:player1_url_temp, label: 'Player 1 List URL (YASB2/FFG)')%> 26 |
27 |
28 | <%= form.text_field(:player2_url_temp, label: 'Player 2 List URL (YASB2/FFG)')%> 29 |
30 |
31 | 32 |
33 |
34 | <%= form.select( 35 | :winner_id, 36 | [ 37 | [@match&.player1&.name, @match.player1_id], 38 | [@match&.player2&.name, @match.player2_id] 39 | ], 40 | label: 'Winner:', include_blank: true, required: true) %> 41 |
42 |
43 | <%= form.file_field :log_file, direct_upload: true %> 44 |
45 |
46 | 47 |
48 |
49 |
50 | <%= form.submit('Submit', class: 'btn btn-success') %> 51 |
52 |

It may take up to an hour for standings to update after you submit a match.

53 |
54 |
55 | 56 | 57 | 58 | 59 | <% end %> 60 | -------------------------------------------------------------------------------- /app/controllers/sessions_controller.rb: -------------------------------------------------------------------------------- 1 | class SessionsController < ApplicationController 2 | skip_before_action :verify_authenticity_token, only: :create 3 | 4 | def create 5 | auth = request.env['omniauth.auth'] 6 | # Find an identity here 7 | @identity = Identity.find_with_omniauth(auth) 8 | 9 | if @identity.nil? 10 | # If no identity was found, create a brand new one here 11 | @identity = Identity.create_with_omniauth(auth) 12 | end 13 | 14 | if user_signed_in? 15 | if @identity.user == current_user 16 | # User is signed in so they are trying to link an identity with their 17 | # account. But we found the identity and the user associated with it 18 | # is the current user. So the identity is already associated with 19 | # this user. So let's display an error message. 20 | redirect_to '/league', notice: "Already linked that account!" 21 | else 22 | # The identity is not associated with the current_user so lets 23 | # associate the identity 24 | @identity.user = current_user 25 | @identity.save 26 | redirect_to '/league', notice: "Successfully linked that account!" 27 | end 28 | else 29 | if @identity.user.present? 30 | # The identity we found had a user associated with it so let's 31 | # just log them in here 32 | self.current_user = @identity.user 33 | redirect_to '/league', notice: "Signed in!" 34 | else 35 | # No user associated with the identity so we need to create a new one 36 | @user = User.create_with_omniauth(auth) 37 | self.current_user = @user 38 | @identity.user = current_user 39 | @identity.save 40 | redirect_to '/league', notice: 'Thanks for registering' 41 | end 42 | end 43 | end 44 | 45 | def destroy 46 | session[:user_id] = nil 47 | flash[:alert] = 'You are now signed out' 48 | redirect_to '/league' 49 | end 50 | 51 | def failure 52 | flash[:alert] = 'There was an error when signing up. Use workspace "xwvl" or post in the league slack for help' 53 | redirect_to '/league' 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /app/views/home/about.html.erb: -------------------------------------------------------------------------------- 1 |
2 | 3 |

About List Fortress

4 | 5 |
6 |
7 |

What is it?

8 |

9 | X-Wing Miniatures Second Edition is a two player boardgame centered around building and dogfighting with a squad of starships from the Star Wars Universe. 10 |

11 |

12 | List Fortress is a website for crowdsourcing the collection and organization of X-Wing Miniatures tournament results. 13 | The resulting data set is publicly available via API and is used by third party sites like <%= link_to "PBM", "https://pinksquadron.dk/pbm/"%> 14 | 15 | List Fortress also serves as the online hub for the X-Wing Vassal League. 16 | The League plays X-Wing online via the Vassal Engine and uses List Fortress to track player standings and share replays. 17 |

18 |
19 | 20 |
21 |

Tech

22 | 23 |

24 | List Fortress is built with Ruby on Rails, PostgreSQL and Bootstrap. 25 |
26 |
27 | The source code is available at <%= link_to 'Github', 'https://github.com/AlexRaubach/ListFortress'%> under an MIT license. 28 |

29 | 30 |

Acknowledgements

31 | 32 |

33 |

    34 |
  • The Scum and Villainy Podcast <%= icon('fab', 'mandalorian') %>
  • 35 |
  • Sozin: For his advice and encouragement when planning the site
  • 36 |
  • Chris Allen: For all his tireless work
  • 37 |
  • Mwhited: For all the help setting up matches
  • 38 |
  • so_crates: For running the XWS conversion services
  • 39 |
  • Everyone who contributes to <%= link_to "X-Wing Data 2", "https://github.com/guidokessels/xwing-data2"%>: <%= icon('fas', 'heart') %>
  • 40 |
  • Everyone who helps enter data: This wouldn't be possible without you
  • 41 |
42 |

43 | 44 | 45 |
46 |
47 | 48 |
-------------------------------------------------------------------------------- /lib/tasks/update_xwing_data.rake: -------------------------------------------------------------------------------- 1 | desc 'Updates XWS from xwingdata2' 2 | task update_xwing_data: :environment do 3 | 4 | def parse_upgrades(file_name) 5 | json = get_json_from_file(file_name) 6 | 7 | json.each do |upgrade_data| 8 | upgrade = Upgrade.where(xws: upgrade_data['xws']).first_or_initialize 9 | upgrade.name = upgrade_data['name'] 10 | upgrade.limited = upgrade_data['limited'] 11 | upgrade.cost = upgrade_data.dig('cost', 'value') 12 | 13 | if upgrade_data['sides']&.length&.positive? 14 | upgrade.ffg = upgrade_data['sides'][0]['ffg'] 15 | upgrade.upgrade_type = upgrade_data['sides'][0]['type'] 16 | upgrade.image = upgrade_data['sides'][0]['image'] 17 | end 18 | 19 | upgrade.save 20 | end 21 | end 22 | 23 | def parse_ships_and_pilots(json_file) 24 | ship_json = get_json_from_file(json_file) 25 | 26 | ship = Ship.where(xws: ship_json['xws']).first_or_initialize 27 | ship.name = ship_json['name'] 28 | ship.size = ship_json['size'] 29 | ship.ffg = ship_json['ffg'] 30 | ship.save 31 | 32 | return if ship_json['pilots'].blank? 33 | 34 | ship_json['pilots'].each do |pilot_json| 35 | pilot = Pilot.where(xws: pilot_json['xws']).first_or_initialize 36 | 37 | pilot.name = pilot_json['name'] 38 | pilot.caption = pilot_json['caption'] 39 | pilot.initiative = pilot_json['initiative'] 40 | pilot.limited = pilot_json['limited'] 41 | pilot.cost = pilot_json['cost'] 42 | pilot.ffg = pilot_json['ffg'] 43 | pilot.ship_id = ship.id 44 | pilot.image = pilot_json['image'] 45 | pilot.ability = pilot_json['ability'] 46 | pilot.save 47 | end 48 | end 49 | 50 | def get_json_from_file(file_name) 51 | file = File.read(file_name) 52 | JSON.parse(file) 53 | end 54 | 55 | # system 'cd xwing-data2 && git checkout master && git pull && cd ..' 56 | 57 | upgrade_file_names = Dir.glob("#{Rails.root}/xwing-data2/data/upgrades/*.json") 58 | upgrade_file_names.each do |upgrade_file| 59 | parse_upgrades(upgrade_file) 60 | end 61 | 62 | pilot_file_names = Dir.glob("#{Rails.root}/xwing-data2/data/pilots/**/*.json") 63 | pilot_file_names.each do |pilot_file| 64 | parse_ships_and_pilots(pilot_file) 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /lib/tasks/generate_league_matches.rake: -------------------------------------------------------------------------------- 1 | desc 'Creates a league season, divisions and matches' 2 | task generate_league_matches: :environment do 3 | division_names = [ 4 | ['Coruscant'], 5 | [ 6 | 'Alderaan', 'Corellia' 7 | # , 'Kuat' 8 | ], 9 | [ # Tier 3 10 | 'Chardaan', 'Kashyyyk', 'Myrkr', 11 | # 'Nal Hutta', 'Manaan', 'Ord Mantell' 12 | ], 13 | # [ # Tier 4 14 | # 'Bespin', 'Dagobah', 'Tatooine', 15 | # 'Endor', 'Dantooine', 'Hoth' 16 | # # , 'Yavin' , 'Kamino', 'Mon Calamari', 'Mandalore' 17 | # ] 18 | # ,[ # Tier Five 19 | # 'Jakku', 'Nkllon', 'Csilla', 20 | # 'Celwiss', 'Ilum', 'Plunder Moon', 'Bakura' 21 | # # , 'The Redoubt', 'Nirauan', 22 | # # 'Kariek', 'Lwhekk' 23 | # ] 24 | ].freeze 25 | 26 | season = Season.create(season_number: 12, name: 'X-Wing Vassal League Season Twelve', active: true) 27 | 28 | division_names.each_with_index do |tier_data, tier_number| 29 | tier_data.each_with_index do |tier_name, division_number| 30 | Division.create( 31 | season_id: season.id, 32 | tier: tier_number + 1, 33 | name: tier_name, 34 | letter: (division_number + 65).chr 35 | ) 36 | end 37 | end 38 | 39 | csv_text = File.open("#{Rails.root}/public/s12.csv") 40 | csv = CSV.parse(csv_text) 41 | csv.each do |user_info| 42 | user_id = user_info[0] 43 | # name = user_info[1] 44 | division_tier = user_info[1] 45 | division_letter = user_info[2] 46 | 47 | league_participant = LeagueParticipant.create(user_id: user_id) 48 | 49 | division = Division.find_by( 50 | tier: division_tier, 51 | letter: division_letter, 52 | season_id: season.id 53 | ) 54 | 55 | if division.nil? 56 | puts "Nil division #{division_tier} #{division_letter}" 57 | next 58 | end 59 | 60 | division.add_participant(league_participant) 61 | end 62 | end 63 | 64 | # This is sample code used to add late signups without the batch process I use normally 65 | # you can fill in your new player array and then paste everything into the console. 66 | 67 | # new_players = [ 68 | # [110, 3, 'E'], 69 | # [655, 3, 'A'] 70 | # ] 71 | 72 | # current_season_number = 12 73 | 74 | # new_players.each do |p| 75 | # Season.add_participant(current_season_number, p[0], p[1], p[2]) 76 | # end 77 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | require "active_support/core_ext/integer/time" 2 | 3 | # The test environment is used exclusively to run your application's 4 | # test suite. You never need to work with it otherwise. Remember that 5 | # your test database is "scratch space" for the test suite and is wiped 6 | # and recreated between test runs. Don't rely on the data there! 7 | 8 | Rails.application.configure do 9 | # Settings specified here will take precedence over those in config/application.rb. 10 | 11 | config.cache_classes = true 12 | 13 | # Do not eager load code on boot. This avoids loading your whole application 14 | # just for the purpose of running a single test. If you are using a tool that 15 | # preloads Rails for running tests, you may have to set it to true. 16 | config.eager_load = false 17 | 18 | # Configure public file server for tests with Cache-Control for performance. 19 | config.public_file_server.enabled = true 20 | config.public_file_server.headers = { 21 | 'Cache-Control' => "public, max-age=#{1.hour.to_i}" 22 | } 23 | 24 | # Show full error reports and disable caching. 25 | config.consider_all_requests_local = true 26 | config.action_controller.perform_caching = false 27 | config.cache_store = :null_store 28 | 29 | # Raise exceptions instead of rendering exception templates. 30 | config.action_dispatch.show_exceptions = false 31 | 32 | # Disable request forgery protection in test environment. 33 | config.action_controller.allow_forgery_protection = false 34 | 35 | # Store uploaded files on the local file system in a temporary directory. 36 | config.active_storage.service = :test 37 | 38 | config.action_mailer.perform_caching = false 39 | 40 | # Tell Action Mailer not to deliver emails to the real world. 41 | # The :test delivery method accumulates sent emails in the 42 | # ActionMailer::Base.deliveries array. 43 | config.action_mailer.delivery_method = :test 44 | 45 | # Print deprecation notices to the stderr. 46 | config.active_support.deprecation = :stderr 47 | 48 | # Raise exceptions for disallowed deprecations. 49 | config.active_support.disallowed_deprecation = :raise 50 | 51 | # Tell Active Support which deprecation messages to disallow. 52 | config.active_support.disallowed_deprecation_warnings = [] 53 | 54 | # Raises error for missing translations. 55 | # config.i18n.raise_on_missing_translations = true 56 | 57 | # Annotate rendered view with file names. 58 | # config.action_view.annotate_rendered_view_with_filenames = true 59 | end 60 | -------------------------------------------------------------------------------- /app/views/tournaments/_filter.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

5 | Filters 6 |

7 | <%= bootstrap_form_tag(id: "tournament_filter_form", method: "get", enforce_utf8: false) do |form|%> 8 |
9 |
10 | <%= form.number_field :min_participants, label: "Min Player #", class: "filter-input"%> 11 |
12 |
13 | <%= form.number_field :max_participants, label: "Max Player #", class: "filter-input" %> 14 |
15 |
16 | <%= form.collection_select(:format_id, Format.all.order('sort desc nulls last, id'), :id, :name, 17 | {label: 'Format:', include_blank: true}, {class: "filter-input"}) 18 | %> 19 |
20 |
21 | <%= form.collection_select(:tournament_type_id, TournamentType.all, :id, :name, 22 | {label: 'Type:', include_blank: true}, {class: "filter-input"}) 23 | %> 24 |
25 |
26 | <%= label_tag(:country, 'Country')%> 27 | <%= form.country_select(:country, {priority_countries: ["US"], include_blank:true}, {class: 'form-control filter-input'}) %> 28 |
29 |
30 | 31 |
32 |
33 | <%= form.text_field(:name_search, label: 'Name:', class: "filter-input")%> 34 |
35 |
36 | <%= form.date_field(:played_after, label: 'Date ≥', class: "filter-input")%> 37 |
38 |
39 | <%= form.date_field(:played_before, label: '≤ Date', class: "filter-input")%> 40 |
41 |
42 | <% sort_array = Tournaments::Forms::ORDER.map { |k,v| [k, v[1]] } %> 43 | <%= form.collection_select( 44 | :sort_order, sort_array, :first, :last, {label: 'Order By:', include_blank: true}, {class: "filter-input"} 45 | )%> 46 |
47 |
48 | 49 |
50 |
51 | <%= form.submit "Filter", name: nil, class: "btn btn-secondary mr-3" %> 52 |
53 |
54 | <%= link_to 'Reset', request.env['PATH_INFO'], method: "get", class: 'btn btn-warning mr-3' %> 55 |
56 |
57 | 58 | <% end %> 59 | <%= javascript_tag "update_filter_with_query_string_params()" %> 60 |
61 |
62 |
-------------------------------------------------------------------------------- /app/views/tournaments/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= bootstrap_form_for(@tournament) do |form| %> 2 | 3 |
4 |
5 | <%= form.date_field(:date, label: 'Tournament Date', required: true)%> 6 |
7 |
8 | <%= form.text_field(:name, required: true, label: 'Tournament Name')%> 9 |
10 |
11 | 12 |
13 |
14 | <%= form.collection_select(:format_id, Format.all.where('sort is not null').order('sort desc, id'), 15 | :id, :name, label: 'Tournament Format:') %> 16 |
17 |
18 | <%= form.collection_select(:tournament_type_id, TournamentType.all, :id, :name, label: 'Tournament Type:') %> 19 |
20 |
21 | 22 |
23 |
24 | <%= form.text_field(:location, label: 'Store Name / Location')%> 25 |
26 |
27 | <%= form.text_field(:state, label: 'State/Province') %> 28 |
29 |
30 | <%= label_tag('tournament_country', 'Country')%> 31 | <%= form.country_select(:country, {priority_countries: ["US"], include_blank:true}, {class: 'form-control'}) %> 32 |
33 |
34 | 35 |

36 | <%= label_tag('', "You can load player and round data in three different ways. Only one can be used at a time.") %>
37 | 38 |

39 |
40 | <%= form.text_field(:tabletop_url, 41 | label: '1: You can link to a TableTop.TO or Best Coast Pairings event via url', 42 | placeholder: 'https://tabletop.to/url') 43 | %> 44 |
45 |
46 | 47 |
48 |
49 | <%= form.text_area(:cryodex_json, label: '2: Paste an export from RollBetter.gg', 50 | placeholder: '{"name": "YourTournament\'s json"... }', 51 | help: 'Copy the tournament data from RollBetter or Cryodex and paste it here' 52 | )%> 53 |
54 |
55 | 56 |
57 |
58 | <%= form.number_field(:participant_number, 59 | max: 999, min: 0, 60 | label: '3: Set the number of participants directly.', 61 | help: 'You will have to manually enter names and scores.') 62 | %> 63 |
64 |
65 |

66 | 67 | 68 |

69 |

70 |
71 | <%= form.submit %> 72 | <%= link_to 'Back', tournaments_path, {class: 'btn btn-danger'} %> 73 |
74 |
75 |

76 | 77 | <% end %> 78 | -------------------------------------------------------------------------------- /app/views/me/_address_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= bootstrap_form_with(url: '/me', local: true) do |form| %> 2 | 3 |
4 |
5 | <%= form.text_field(:full_name, label: 'First and last name. Not displayed, only for shipping *', value: current_user&.name) %> 6 |
7 |
8 | <%= form.text_field(:display_name, label: 'Name you want publicly displayed *', required: true, value: current_user&.display_name) %> 9 |
10 |
11 |
12 |
13 | <%= form.number_field(:prize_level, label: 'Number of League Acrylic Prizes', value: @address.prize_level) %> 14 |
15 |

16 | If you are in Tier 1 or win your division, you're eligible for a acrylic prize. 17 | Please put the number corresponding to the last prize you recieved. 18 |
0: No Rulers/Templates 19 |
1: Range 1 Ruler 20 |
2: Range 2 Ruler 21 |
3: Range 3 Ruler 22 |
4: 1 Speed Templates 23 |
5: 2 Speed Templates 24 |

25 |
26 |

27 | Please input your address correctly so we can get you your prize. 28 | If you're not in the US, believe you're going to recieve a prize, and don't know how to format your address, 29 | please reach out to Antigrapist on the league slack or post on #leaguehelp 30 |

31 |
32 |
33 | <%= form.text_field(:first_line, label: 'Street Line 1', value: @address.first_line) %> 34 |
35 |
36 |
37 |
38 | <%= form.text_field(:second_line, label: 'Street line 2 (if needed)', value: @address.second_line) %> 39 |
40 |
41 |
42 |
43 | <%= form.text_field(:city, label: 'City ', value: @address.city) %> 44 |
45 |
46 | <%= form.text_field(:county_province, label: 'State / Province ', value: @address.county_province) %> 47 |
48 |
49 | <%= form.text_field(:zip_or_postcode, label: 'ZIP / Postal Code', value: @address.zip_or_postcode ) %> 50 |
51 |
52 |
53 |
54 | <%= form.text_field(:country, label: 'Country Full Name (omit if in USA)', value: @address.country) %> 55 |
56 |
57 | 58 |
59 |
60 | <%= form.submit %> 61 |
62 |
63 | <%= link_to 'Back to League Home', league_path, :class => "btn btn-primary"%> 64 |
65 |
66 | <% end %> 67 | -------------------------------------------------------------------------------- /app/views/season_seven_surveys/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= bootstrap_form_for(@season_seven_survey) do |form| %> 2 | 3 | 4 | 5 | 6 |
7 | <%= form.text_field(:full_name, label: 'First and last name (not displayed publicly) *', value: current_user&.name) %> 8 |
9 |
10 | <%= form.text_field(:display_name, label: 'Name you want displayed *', required: true, value: current_user&.display_name) %> 11 |
12 | 13 | 14 |
15 | <%= form.time_zone_select(:time_zone, nil, default: 'Eastern Time (US & Canada)') %> 16 |
17 |
18 | <%= form.number_field(:time, label: "Select your prefered match start hour. 20 = 8pm in your selected time zone. This will be used to roughly group people by prefered start time", max: 24, min: 0, required: true)%> 19 |
20 | 21 |
22 |
23 | 24 | <%= form.select( 25 | :s1_id, 26 | LeagueParticipant.joins(division: :season).where(seasons: {season_number: 1}).order(list_juggler_name: :asc).collect{|p| [p.list_juggler_name, p.id]}, 27 | {label: 'Season 1 Name. Leave blank if you did not participate in S1', include_blank: true} 28 | ) 29 | %> 30 | 31 | <%= form.select( 32 | :s2_id, 33 | LeagueParticipant.joins(division: :season).where(seasons: {season_number: 2}).order(list_juggler_name: :asc).collect{|p| [p.list_juggler_name, p.id]}, 34 | {label: 'Season 2 Name. Leave blank if you did not participate in S2', include_blank: true} 35 | ) 36 | %> 37 | 38 | <%= form.select( 39 | :s3_id, 40 | LeagueParticipant.joins(division: :season).where(seasons: {season_number: 3}).order(list_juggler_name: :asc).collect{|p| [p.list_juggler_name, p.id]}, 41 | {label: 'Season 3 Name. Leave blank if you did not participate in S3', include_blank: true} 42 | ) 43 | %> 44 | 45 | <%= form.select( 46 | :s4_id, 47 | LeagueParticipant.joins(division: :season).where(seasons: {season_number: 4}).order(list_juggler_name: :asc).collect{|p| [p.list_juggler_name, p.id]}, 48 | {label: 'Season 4 Name. Leave blank if you did not participate in S4', include_blank: true} 49 | ) 50 | %> 51 | 52 | <%= form.select( 53 | :s5_id, 54 | LeagueParticipant.joins(division: :season).where(seasons: {season_number: 5}).order(list_juggler_name: :asc).collect{|p| [p.list_juggler_name, p.id]}, 55 | {label: 'Season 5 Name. Leave blank if you did not participate in S5', include_blank: true} 56 | ) 57 | %> 58 | 59 | <%= form.select( 60 | :s6_id, 61 | LeagueParticipant.joins(division: :season).where(seasons: {season_number: 6}).order(list_juggler_name: :asc).collect{|p| [p.list_juggler_name, p.id]}, 62 | {label: 'Season 6 Name. Leave blank if you did not participate in S6', include_blank: true} 63 | ) 64 | %> 65 | 66 | 67 |
68 |
69 | <%= form.primary %> 70 |
71 | <% end %> 72 | -------------------------------------------------------------------------------- /app/controllers/league_controller.rb: -------------------------------------------------------------------------------- 1 | class LeagueController < ApplicationController 2 | def index 3 | end 4 | 5 | def interdivisional 6 | tier = current_user&.current_league_participant&.division&.tier 7 | if Season::INTERDIVISIONAL_ALLOWED && tier 8 | if tier < 4 9 | @participants = LeagueParticipant 10 | .joins(:division, :season) 11 | .includes(:user) 12 | .where( 13 | 'divisions.season_id = ? 14 | AND divisions.tier = ? 15 | AND divisions.id != ?', 16 | current_user.current_league_participant.season.id, 17 | tier, 18 | current_user.current_league_participant.division.id 19 | ) 20 | .order('users.display_name asc') 21 | else 22 | @participants = LeagueParticipant 23 | .joins(:division, :season) 24 | .includes(:user) 25 | .where( 26 | 'divisions.season_id = ? 27 | AND (divisions.tier = ? OR divisions.tier = ?) 28 | AND divisions.id != ?', 29 | current_user.current_league_participant.season.id, 30 | 4, 31 | 5, 32 | current_user.current_league_participant.division.id 33 | ) 34 | .order('users.display_name asc') 35 | end 36 | elsif Season::INTERDIVISIONAL_ALLOWED 37 | redirect_to league_path, notice: 'You must be signed in and registered for the league to access that page' 38 | else 39 | redirect_to league_path, alert: 'Interdivisional play is currently disabled' 40 | end 41 | end 42 | 43 | def create_interdivisional 44 | match = Match.new( 45 | league_match: true, 46 | player1: current_user&.current_league_participant, 47 | player2: LeagueParticipant.find(params['player2_id']) 48 | ) 49 | 50 | # check for a current user to prevent saving a match with only one user due to log out after loading ID page 51 | if current_user&.current_league_participant&.blank? 52 | redirect_to interdivisional_path, alert: 'You must be signed in to create a match' 53 | elsif match.player2_id.nil? 54 | redirect_to interdivisional_path, alert: 'Invalid Player 2. Try again' 55 | elsif Match.duplicate_exists?(match.player1_id, match.player2_id, true) 56 | redirect_to interdivisional_path, alert: 'A match already exists between these two players' 57 | elsif match.save 58 | redirect_to league_participant_path(current_user.current_league_participant), 59 | notice: 'Interdivisional Match was successfully created.' 60 | else 61 | redirect_to interdivisional_path, alert: 'Match could not be saved' 62 | end 63 | end 64 | end 65 | --------------------------------------------------------------------------------