diff --git a/db/migrations/20140524160241_CreateEventSettings.sql b/db/migrations/20140524160241_CreateEventSettings.sql index 13dd40e..a0b806d 100644 --- a/db/migrations/20140524160241_CreateEventSettings.sql +++ b/db/migrations/20140524160241_CreateEventSettings.sql @@ -2,7 +2,6 @@ CREATE TABLE event_settings ( id INTEGER PRIMARY KEY, name VARCHAR(255), - code VARCHAR(16), displaybackgroundcolor VARCHAR(16), numelimalliances int, selectionround2order VARCHAR(1), diff --git a/field/access_point.go b/field/access_point.go index 635ebb1..b8c33b0 100644 --- a/field/access_point.go +++ b/field/access_point.go @@ -27,8 +27,6 @@ const ( blue3Vlan = 60 ) -var templatesPath = "." - type AccessPoint struct { address string port int @@ -101,7 +99,7 @@ func generateAccessPointConfig(red1, red2, red3, blue1, blue2, blue3 *model.Team } // Generate the config file to be uploaded to the AP. - template, err := template.ParseFiles(filepath.Join(templatesPath, "templates/access_point.cfg")) + template, err := template.ParseFiles(filepath.Join(model.BaseDir, "templates/access_point.cfg")) if err != nil { return "", err } diff --git a/field/access_point_test.go b/field/access_point_test.go index 18a6bb7..a9f9912 100644 --- a/field/access_point_test.go +++ b/field/access_point_test.go @@ -11,7 +11,7 @@ import ( ) func TestConfigureAccessPoint(t *testing.T) { - templatesPath = ".." + model.BaseDir = ".." radioRe := regexp.MustCompile("option device 'radio0'") ssidRe := regexp.MustCompile("option ssid '([-\\w ]+)'") diff --git a/field/test_helpers.go b/field/test_helpers.go index ee1f6a1..65bff00 100644 --- a/field/test_helpers.go +++ b/field/test_helpers.go @@ -15,14 +15,14 @@ import ( ) func SetupTestArena(t *testing.T, uniqueName string) *Arena { - dbPath := fmt.Sprintf("%s_test.db", uniqueName) - os.Remove(filepath.Join(model.BaseDir, dbPath)) + model.BaseDir = ".." + dbPath := filepath.Join(model.BaseDir, fmt.Sprintf("%s_test.db", uniqueName)) + os.Remove(dbPath) arena, err := NewArena(dbPath) assert.Nil(t, err) return arena } func setupTestArena(t *testing.T) *Arena { - model.BaseDir = ".." return SetupTestArena(t, "field") } diff --git a/main.go b/main.go index 3336a0e..2f40ed3 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ package main import ( "github.com/Team254/cheesy-arena/field" + "github.com/Team254/cheesy-arena/web" "log" "math/rand" "time" @@ -23,7 +24,7 @@ func main() { } // Start the web server in a separate goroutine. - web := NewWeb(arena) + web := web.NewWeb(arena) go web.ServeWebInterface(httpPort) // Run the arena state machine in the main thread. diff --git a/model/database.go b/model/database.go index ff5606c..f922d5e 100644 --- a/model/database.go +++ b/model/database.go @@ -25,7 +25,7 @@ const migrationsDir = "db/migrations" var BaseDir = "." // Mutable for testing type Database struct { - filename string + Path string db *sql.DB eventSettingsMap *modl.DbMap matchMap *modl.DbMap @@ -41,9 +41,9 @@ type Database struct { // migrations. func OpenDatabase(filename string) (*Database, error) { // Find and run the migrations using goose. This also auto-creates the DB. - database := Database{filename: filename} + database := Database{Path: filename} migrationsPath := filepath.Join(BaseDir, migrationsDir) - dbDriver := goose.DBDriver{"sqlite3", database.GetPath(), "github.com/mattn/go-sqlite3", &goose.Sqlite3Dialect{}} + dbDriver := goose.DBDriver{"sqlite3", database.Path, "github.com/mattn/go-sqlite3", &goose.Sqlite3Dialect{}} dbConf := goose.DBConf{MigrationsDir: migrationsPath, Env: "prod", Driver: dbDriver} target, err := goose.GetMostRecentDBVersion(migrationsPath) if err != nil { @@ -54,7 +54,7 @@ func OpenDatabase(filename string) (*Database, error) { return nil, err } - db, err := sql.Open("sqlite3", database.GetPath()) + db, err := sql.Open("sqlite3", database.Path) if err != nil { return nil, err } @@ -77,7 +77,7 @@ func (database *Database) Backup(eventName, reason string) error { } filename := fmt.Sprintf("%s/%s_%s_%s.db", backupsPath, strings.Replace(eventName, " ", "_", -1), time.Now().Format("20060102150405"), reason) - src, err := os.Open(database.GetPath()) + src, err := os.Open(database.Path) if err != nil { return err } @@ -93,10 +93,6 @@ func (database *Database) Backup(eventName, reason string) error { return nil } -func (database *Database) GetPath() string { - return filepath.Join(BaseDir, database.filename) -} - // Sets up table-object associations. func (database *Database) mapTables() { dialect := new(modl.SqliteDialect) diff --git a/model/event_settings.go b/model/event_settings.go index e5d6c03..33db7c8 100644 --- a/model/event_settings.go +++ b/model/event_settings.go @@ -8,7 +8,6 @@ package model type EventSettings struct { Id int Name string - Code string DisplayBackgroundColor string NumElimAlliances int SelectionRound2Order string @@ -39,7 +38,6 @@ func (database *Database) GetEventSettings() (*EventSettings, error) { if err != nil { // Database record doesn't exist yet; create it now. eventSettings.Name = "Untitled Event" - eventSettings.Code = "UE" eventSettings.DisplayBackgroundColor = "#00ff00" eventSettings.NumElimAlliances = 8 eventSettings.SelectionRound2Order = "L" diff --git a/model/event_settings_test.go b/model/event_settings_test.go index ccb4ee1..903abdf 100644 --- a/model/event_settings_test.go +++ b/model/event_settings_test.go @@ -13,12 +13,11 @@ func TestEventSettingsReadWrite(t *testing.T) { eventSettings, err := db.GetEventSettings() assert.Nil(t, err) - assert.Equal(t, EventSettings{Id: 0, Name: "Untitled Event", Code: "UE", DisplayBackgroundColor: "#00ff00", + assert.Equal(t, EventSettings{Id: 0, Name: "Untitled Event", DisplayBackgroundColor: "#00ff00", NumElimAlliances: 8, SelectionRound2Order: "L", SelectionRound3Order: "", TBADownloadEnabled: true}, *eventSettings) eventSettings.Name = "Chezy Champs" - eventSettings.Code = "cc" eventSettings.DisplayBackgroundColor = "#ff00ff" eventSettings.NumElimAlliances = 6 eventSettings.SelectionRound2Order = "F" diff --git a/model/test_helpers.go b/model/test_helpers.go index ce4ca60..96451f2 100644 --- a/model/test_helpers.go +++ b/model/test_helpers.go @@ -16,8 +16,8 @@ import ( func SetupTestDb(t *testing.T, uniqueName string) *Database { BaseDir = ".." - dbPath := fmt.Sprintf("%s_test.db", uniqueName) - os.Remove(filepath.Join(BaseDir, dbPath)) + dbPath := filepath.Join(BaseDir, fmt.Sprintf("%s_test.db", uniqueName)) + os.Remove(dbPath) database, err := OpenDatabase(dbPath) assert.Nil(t, err) return database diff --git a/templates/setup_settings.html b/templates/setup_settings.html index 1210898..581520e 100644 --- a/templates/setup_settings.html +++ b/templates/setup_settings.html @@ -24,12 +24,6 @@ -
- -
- -
-
diff --git a/test_helpers.go b/test_helpers.go deleted file mode 100644 index 540c8f2..0000000 --- a/test_helpers.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2017 Team 254. All Rights Reserved. -// Author: pat@patfairbank.com (Patrick Fairbank) -// -// Helper methods for use in tests in this package and others. - -package main - -import ( - "github.com/Team254/cheesy-arena/field" - "testing" -) - -func setupTestWeb(t *testing.T) *Web { - arena := field.SetupTestArena(t, "web") - return NewWeb(arena) -} diff --git a/tournament/schedule.go b/tournament/schedule.go index 4721b45..3cfc42e 100644 --- a/tournament/schedule.go +++ b/tournament/schedule.go @@ -12,13 +12,15 @@ import ( "math" "math/rand" "os" + "path/filepath" "strconv" "time" ) -var schedulesDir = "schedules" - -const TeamsPerMatch = 6 +const ( + schedulesDir = "schedules" + TeamsPerMatch = 6 +) type ScheduleBlock struct { StartTime time.Time @@ -36,7 +38,8 @@ func BuildRandomSchedule(teams []model.Team, scheduleBlocks []ScheduleBlock, mat // Adjust the number of matches to remove any excess from non-perfect block scheduling. numMatches = int(math.Ceil(float64(numTeams) * float64(matchesPerTeam) / TeamsPerMatch)) - file, err := os.Open(fmt.Sprintf("%s/%d_%d.csv", schedulesDir, numTeams, matchesPerTeam)) + file, err := os.Open(fmt.Sprintf("%s/%d_%d.csv", filepath.Join(model.BaseDir, schedulesDir), numTeams, + matchesPerTeam)) if err != nil { return nil, fmt.Errorf("No schedule template exists for %d teams and %d matches", numTeams, matchesPerTeam) } diff --git a/tournament/schedule_test.go b/tournament/schedule_test.go index 427b255..e8386ed 100644 --- a/tournament/schedule_test.go +++ b/tournament/schedule_test.go @@ -9,12 +9,12 @@ import ( "github.com/stretchr/testify/assert" "math/rand" "os" + "path/filepath" "testing" "time" ) func TestMain(m *testing.M) { - schedulesDir = "../schedules" os.Exit(m.Run()) } @@ -29,7 +29,7 @@ func TestNonExistentSchedule(t *testing.T) { } func TestMalformedSchedule(t *testing.T) { - filename := fmt.Sprintf("%s/6_1.csv", schedulesDir) + filename := fmt.Sprintf("%s/6_1.csv", filepath.Join(model.BaseDir, schedulesDir)) scheduleFile, _ := os.Create(filename) defer os.Remove(filename) scheduleFile.WriteString("1,0,2,0,3,0,4,0,5,0,6,0\n6,0,5,0,4,0,3,0,2,0,1,0\n") diff --git a/alliance_station_display.go b/web/alliance_station_display.go similarity index 97% rename from alliance_station_display.go rename to web/alliance_station_display.go index f05e1c0..a3d56e7 100644 --- a/alliance_station_display.go +++ b/web/alliance_station_display.go @@ -3,7 +3,7 @@ // // Web handlers for the alliance station display. -package main +package web import ( "fmt" @@ -13,7 +13,6 @@ import ( "log" "net/http" "strconv" - "text/template" ) // Renders the team number and status display shown above each alliance station. @@ -22,8 +21,7 @@ func (web *Web) allianceStationDisplayHandler(w http.ResponseWriter, r *http.Req return } - template := template.New("").Funcs(web.templateHelpers) - _, err := template.ParseFiles("templates/alliance_station_display.html") + template, err := web.parseFiles("templates/alliance_station_display.html") if err != nil { handleWebErr(w, err) return diff --git a/alliance_station_display_test.go b/web/alliance_station_display_test.go similarity index 99% rename from alliance_station_display_test.go rename to web/alliance_station_display_test.go index e23c316..238064e 100644 --- a/alliance_station_display_test.go +++ b/web/alliance_station_display_test.go @@ -1,7 +1,7 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( "github.com/gorilla/websocket" diff --git a/announcer_display.go b/web/announcer_display.go similarity index 97% rename from announcer_display.go rename to web/announcer_display.go index 94e320f..6bcdd5f 100644 --- a/announcer_display.go +++ b/web/announcer_display.go @@ -3,7 +3,7 @@ // // Web handlers for announcer display. -package main +package web import ( "fmt" @@ -12,7 +12,6 @@ import ( "io" "log" "net/http" - "text/template" ) // Renders the announcer display which shows team info and scores for the current match. @@ -21,8 +20,7 @@ func (web *Web) announcerDisplayHandler(w http.ResponseWriter, r *http.Request) return } - template := template.New("").Funcs(web.templateHelpers) - _, err := template.ParseFiles("templates/announcer_display.html", "templates/base.html") + template, err := web.parseFiles("templates/announcer_display.html", "templates/base.html") if err != nil { handleWebErr(w, err) return diff --git a/announcer_display_test.go b/web/announcer_display_test.go similarity index 99% rename from announcer_display_test.go rename to web/announcer_display_test.go index 6fac24a..6dc9b22 100644 --- a/announcer_display_test.go +++ b/web/announcer_display_test.go @@ -1,7 +1,7 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( "github.com/gorilla/websocket" diff --git a/api.go b/web/api.go similarity index 99% rename from api.go rename to web/api.go index ea377e8..ea70156 100644 --- a/api.go +++ b/web/api.go @@ -3,7 +3,7 @@ // // Web API for providing JSON-formatted event data. -package main +package web import ( "encoding/json" diff --git a/api_test.go b/web/api_test.go similarity index 99% rename from api_test.go rename to web/api_test.go index 05116c5..b3d3251 100644 --- a/api_test.go +++ b/web/api_test.go @@ -1,7 +1,7 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( "encoding/json" diff --git a/audience_display.go b/web/audience_display.go similarity index 97% rename from audience_display.go rename to web/audience_display.go index f21e004..7c19217 100644 --- a/audience_display.go +++ b/web/audience_display.go @@ -3,7 +3,7 @@ // // Web handlers for audience screen display. -package main +package web import ( "github.com/Team254/cheesy-arena/game" @@ -11,7 +11,6 @@ import ( "io" "log" "net/http" - "text/template" ) // Renders the audience display to be chroma keyed over the video feed. @@ -20,8 +19,7 @@ func (web *Web) audienceDisplayHandler(w http.ResponseWriter, r *http.Request) { return } - template := template.New("").Funcs(web.templateHelpers) - _, err := template.ParseFiles("templates/audience_display.html") + template, err := web.parseFiles("templates/audience_display.html") if err != nil { handleWebErr(w, err) return diff --git a/audience_display_test.go b/web/audience_display_test.go similarity index 99% rename from audience_display_test.go rename to web/audience_display_test.go index 1626f3b..fbe00f1 100644 --- a/audience_display_test.go +++ b/web/audience_display_test.go @@ -1,7 +1,7 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( "github.com/gorilla/websocket" diff --git a/fta_display.go b/web/fta_display.go similarity index 93% rename from fta_display.go rename to web/fta_display.go index 380bd48..af7c4bd 100644 --- a/fta_display.go +++ b/web/fta_display.go @@ -3,14 +3,13 @@ // // Web handlers for the FTA diagnostic display. -package main +package web import ( "github.com/Team254/cheesy-arena/model" "io" "log" "net/http" - "text/template" ) // Renders the FTA diagnostic display. @@ -19,8 +18,7 @@ func (web *Web) ftaDisplayHandler(w http.ResponseWriter, r *http.Request) { return } - template := template.New("").Funcs(web.templateHelpers) - _, err := template.ParseFiles("templates/fta_display.html", "templates/base.html") + template, err := web.parseFiles("templates/fta_display.html", "templates/base.html") if err != nil { handleWebErr(w, err) return diff --git a/fta_display_test.go b/web/fta_display_test.go similarity index 96% rename from fta_display_test.go rename to web/fta_display_test.go index cb667f3..9d54b1e 100644 --- a/fta_display_test.go +++ b/web/fta_display_test.go @@ -1,7 +1,7 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( "github.com/stretchr/testify/assert" diff --git a/match_play.go b/web/match_play.go similarity index 99% rename from match_play.go rename to web/match_play.go index be5ff03..c4ef69a 100644 --- a/match_play.go +++ b/web/match_play.go @@ -3,7 +3,7 @@ // // Web routes for controlling match play. -package main +package web import ( "fmt" @@ -17,7 +17,6 @@ import ( "net/http" "sort" "strconv" - "text/template" "time" ) @@ -61,8 +60,7 @@ func (web *Web) matchPlayHandler(w http.ResponseWriter, r *http.Request) { return } - template := template.New("").Funcs(web.templateHelpers) - _, err = template.ParseFiles("templates/match_play.html", "templates/base.html") + template, err := web.parseFiles("templates/match_play.html", "templates/base.html") if err != nil { handleWebErr(w, err) return diff --git a/match_play_test.go b/web/match_play_test.go similarity index 99% rename from match_play_test.go rename to web/match_play_test.go index f46ad91..d3a9001 100644 --- a/match_play_test.go +++ b/web/match_play_test.go @@ -1,7 +1,7 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( "bytes" diff --git a/match_review.go b/web/match_review.go similarity index 96% rename from match_review.go rename to web/match_review.go index 1b50f2d..8dd9596 100644 --- a/match_review.go +++ b/web/match_review.go @@ -3,7 +3,7 @@ // // Web routes for editing match results. -package main +package web import ( "fmt" @@ -11,7 +11,6 @@ import ( "github.com/gorilla/mux" "net/http" "strconv" - "text/template" ) type MatchReviewListItem struct { @@ -47,7 +46,7 @@ func (web *Web) matchReviewHandler(w http.ResponseWriter, r *http.Request) { return } - template, err := template.ParseFiles("templates/match_review.html", "templates/base.html") + template, err := web.parseFiles("templates/match_review.html", "templates/base.html") if err != nil { handleWebErr(w, err) return @@ -81,7 +80,7 @@ func (web *Web) matchReviewEditGetHandler(w http.ResponseWriter, r *http.Request return } - template, err := template.ParseFiles("templates/edit_match_result.html", "templates/base.html") + template, err := web.parseFiles("templates/edit_match_result.html", "templates/base.html") if err != nil { handleWebErr(w, err) return diff --git a/match_review_test.go b/web/match_review_test.go similarity index 99% rename from match_review_test.go rename to web/match_review_test.go index f657696..ae34b97 100644 --- a/match_review_test.go +++ b/web/match_review_test.go @@ -1,7 +1,7 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( "fmt" diff --git a/pit_display.go b/web/pit_display.go similarity index 92% rename from pit_display.go rename to web/pit_display.go index 684e754..46e18e3 100644 --- a/pit_display.go +++ b/web/pit_display.go @@ -3,14 +3,13 @@ // // Web handlers for the pit rankings display. -package main +package web import ( "github.com/Team254/cheesy-arena/model" "io" "log" "net/http" - "text/template" ) // Renders the pit display which shows scrolling rankings. @@ -19,7 +18,7 @@ func (web *Web) pitDisplayHandler(w http.ResponseWriter, r *http.Request) { return } - template, err := template.ParseFiles("templates/pit_display.html") + template, err := web.parseFiles("templates/pit_display.html") if err != nil { handleWebErr(w, err) return @@ -27,7 +26,7 @@ func (web *Web) pitDisplayHandler(w http.ResponseWriter, r *http.Request) { data := struct { *model.EventSettings }{web.arena.EventSettings} - err = template.Execute(w, data) + err = template.ExecuteTemplate(w, "pit_display.html", data) if err != nil { handleWebErr(w, err) return diff --git a/pit_display_test.go b/web/pit_display_test.go similarity index 98% rename from pit_display_test.go rename to web/pit_display_test.go index 935602c..20fee54 100644 --- a/pit_display_test.go +++ b/web/pit_display_test.go @@ -1,7 +1,7 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( "github.com/gorilla/websocket" diff --git a/referee_display.go b/web/referee_display.go similarity index 97% rename from referee_display.go rename to web/referee_display.go index 863f30b..f79f814 100644 --- a/referee_display.go +++ b/web/referee_display.go @@ -3,7 +3,7 @@ // // Web handlers for the referee interface. -package main +package web import ( "fmt" @@ -15,7 +15,6 @@ import ( "log" "net/http" "strconv" - "text/template" ) // Renders the referee interface for assigning fouls. @@ -24,8 +23,7 @@ func (web *Web) refereeDisplayHandler(w http.ResponseWriter, r *http.Request) { return } - template := template.New("").Funcs(web.templateHelpers) - _, err := template.ParseFiles("templates/referee_display.html") + template, err := web.parseFiles("templates/referee_display.html") if err != nil { handleWebErr(w, err) return diff --git a/referee_display_test.go b/web/referee_display_test.go similarity index 99% rename from referee_display_test.go rename to web/referee_display_test.go index 02127b1..5366d4a 100644 --- a/referee_display_test.go +++ b/web/referee_display_test.go @@ -1,7 +1,7 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( "github.com/Team254/cheesy-arena/field" diff --git a/reports.go b/web/reports.go similarity index 97% rename from reports.go rename to web/reports.go index 47d557a..9225fd0 100644 --- a/reports.go +++ b/web/reports.go @@ -3,7 +3,7 @@ // // Web handlers for generating CSV and PDF reports. -package main +package web import ( "fmt" @@ -12,7 +12,6 @@ import ( "github.com/jung-kurt/gofpdf" "net/http" "strconv" - "text/template" ) // Generates a CSV-formatted report of the qualification rankings. @@ -29,12 +28,12 @@ func (web *Web) rankingsCsvReportHandler(w http.ResponseWriter, r *http.Request) // Don't set the content type as "text/csv", as that will trigger an automatic download in the browser. w.Header().Set("Content-Type", "text/plain") - template, err := template.ParseFiles("templates/rankings.csv") + template, err := web.parseFiles("templates/rankings.csv") if err != nil { handleWebErr(w, err) return } - err = template.Execute(w, rankings) + err = template.ExecuteTemplate(w, "rankings.csv", rankings) if err != nil { handleWebErr(w, err) return @@ -118,12 +117,12 @@ func (web *Web) scheduleCsvReportHandler(w http.ResponseWriter, r *http.Request) // Don't set the content type as "text/csv", as that will trigger an automatic download in the browser. w.Header().Set("Content-Type", "text/plain") - template, err := template.ParseFiles("templates/schedule.csv") + template, err := web.parseFiles("templates/schedule.csv") if err != nil { handleWebErr(w, err) return } - err = template.Execute(w, matches) + err = template.ExecuteTemplate(w, "schedule.csv", matches) if err != nil { handleWebErr(w, err) return @@ -253,12 +252,12 @@ func (web *Web) teamsCsvReportHandler(w http.ResponseWriter, r *http.Request) { // Don't set the content type as "text/csv", as that will trigger an automatic download in the browser. w.Header().Set("Content-Type", "text/plain") - template, err := template.ParseFiles("templates/teams.csv") + template, err := web.parseFiles("templates/teams.csv") if err != nil { handleWebErr(w, err) return } - err = template.Execute(w, teams) + err = template.ExecuteTemplate(w, "teams.csv", teams) if err != nil { handleWebErr(w, err) return diff --git a/reports_test.go b/web/reports_test.go similarity index 99% rename from reports_test.go rename to web/reports_test.go index 8a63ce4..a1534fe 100644 --- a/reports_test.go +++ b/web/reports_test.go @@ -1,7 +1,7 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( "github.com/Team254/cheesy-arena/game" diff --git a/scoring_display.go b/web/scoring_display.go similarity index 97% rename from scoring_display.go rename to web/scoring_display.go index 3d70202..9e4a812 100644 --- a/scoring_display.go +++ b/web/scoring_display.go @@ -3,7 +3,7 @@ // // Web handlers for scoring interface. -package main +package web import ( "fmt" @@ -14,7 +14,6 @@ import ( "io" "log" "net/http" - "text/template" ) // Renders the scoring interface which enables input of scores in real-time. @@ -30,7 +29,7 @@ func (web *Web) scoringDisplayHandler(w http.ResponseWriter, r *http.Request) { return } - template, err := template.ParseFiles("templates/scoring_display.html", "templates/base.html") + template, err := web.parseFiles("templates/scoring_display.html", "templates/base.html") if err != nil { handleWebErr(w, err) return diff --git a/scoring_display_test.go b/web/scoring_display_test.go similarity index 99% rename from scoring_display_test.go rename to web/scoring_display_test.go index 4bc511c..e3055d5 100644 --- a/scoring_display_test.go +++ b/web/scoring_display_test.go @@ -1,7 +1,7 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( "github.com/Team254/cheesy-arena/field" diff --git a/setup_alliance_selection.go b/web/setup_alliance_selection.go similarity index 98% rename from setup_alliance_selection.go rename to web/setup_alliance_selection.go index 6877243..3581a45 100644 --- a/setup_alliance_selection.go +++ b/web/setup_alliance_selection.go @@ -3,13 +3,12 @@ // // Web routes for conducting the alliance selection process. -package main +package web import ( "fmt" "github.com/Team254/cheesy-arena/model" "github.com/Team254/cheesy-arena/tournament" - "html/template" "net/http" "strconv" "time" @@ -227,7 +226,7 @@ func (web *Web) allianceSelectionFinalizeHandler(w http.ResponseWriter, r *http. } func (web *Web) renderAllianceSelection(w http.ResponseWriter, r *http.Request, errorMessage string) { - template, err := template.ParseFiles("templates/setup_alliance_selection.html", "templates/base.html") + template, err := web.parseFiles("templates/setup_alliance_selection.html", "templates/base.html") if err != nil { handleWebErr(w, err) return diff --git a/setup_alliance_selection_test.go b/web/setup_alliance_selection_test.go similarity index 99% rename from setup_alliance_selection_test.go rename to web/setup_alliance_selection_test.go index fc74b7c..368c441 100644 --- a/setup_alliance_selection_test.go +++ b/web/setup_alliance_selection_test.go @@ -1,7 +1,7 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( "github.com/Team254/cheesy-arena/game" diff --git a/setup_field.go b/web/setup_field.go similarity index 91% rename from setup_field.go rename to web/setup_field.go index 5da4611..f6c80e2 100644 --- a/setup_field.go +++ b/web/setup_field.go @@ -3,11 +3,10 @@ // // Web routes for configuring the field components. -package main +package web import ( "github.com/Team254/cheesy-arena/model" - "html/template" "net/http" ) @@ -17,7 +16,7 @@ func (web *Web) fieldGetHandler(w http.ResponseWriter, r *http.Request) { return } - template, err := template.ParseFiles("templates/setup_field.html", "templates/base.html") + template, err := web.parseFiles("templates/setup_field.html", "templates/base.html") if err != nil { handleWebErr(w, err) return diff --git a/setup_field_test.go b/web/setup_field_test.go similarity index 98% rename from setup_field_test.go rename to web/setup_field_test.go index f9aa283..7dcd1f1 100644 --- a/setup_field_test.go +++ b/web/setup_field_test.go @@ -1,7 +1,7 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( "github.com/stretchr/testify/assert" diff --git a/setup_lower_thirds.go b/web/setup_lower_thirds.go similarity index 97% rename from setup_lower_thirds.go rename to web/setup_lower_thirds.go index 65c24d7..f4c8281 100644 --- a/setup_lower_thirds.go +++ b/web/setup_lower_thirds.go @@ -3,13 +3,12 @@ // // Web routes for managing lower thirds. -package main +package web import ( "fmt" "github.com/Team254/cheesy-arena/model" "github.com/mitchellh/mapstructure" - "html/template" "io" "log" "net/http" @@ -21,7 +20,7 @@ func (web *Web) lowerThirdsGetHandler(w http.ResponseWriter, r *http.Request) { return } - template, err := template.ParseFiles("templates/setup_lower_thirds.html", "templates/base.html") + template, err := web.parseFiles("templates/setup_lower_thirds.html", "templates/base.html") if err != nil { handleWebErr(w, err) return diff --git a/setup_lower_thirds_test.go b/web/setup_lower_thirds_test.go similarity index 99% rename from setup_lower_thirds_test.go rename to web/setup_lower_thirds_test.go index a548d48..d5c227b 100644 --- a/setup_lower_thirds_test.go +++ b/web/setup_lower_thirds_test.go @@ -1,7 +1,7 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( "github.com/Team254/cheesy-arena/model" diff --git a/setup_schedule.go b/web/setup_schedule.go similarity index 98% rename from setup_schedule.go rename to web/setup_schedule.go index d774d1d..aa5ca74 100644 --- a/setup_schedule.go +++ b/web/setup_schedule.go @@ -3,13 +3,12 @@ // // Web routes for generating practice and qualification schedules. -package main +package web import ( "fmt" "github.com/Team254/cheesy-arena/model" "github.com/Team254/cheesy-arena/tournament" - "html/template" "net/http" "strconv" "time" @@ -173,7 +172,7 @@ func (web *Web) renderSchedule(w http.ResponseWriter, r *http.Request, errorMess handleWebErr(w, err) return } - template, err := template.ParseFiles("templates/setup_schedule.html", "templates/base.html") + template, err := web.parseFiles("templates/setup_schedule.html", "templates/base.html") if err != nil { handleWebErr(w, err) return diff --git a/setup_schedule_test.go b/web/setup_schedule_test.go similarity index 99% rename from setup_schedule_test.go rename to web/setup_schedule_test.go index 06b1d75..2130412 100644 --- a/setup_schedule_test.go +++ b/web/setup_schedule_test.go @@ -1,7 +1,7 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( "github.com/Team254/cheesy-arena/model" diff --git a/setup_settings.go b/web/setup_settings.go similarity index 94% rename from setup_settings.go rename to web/setup_settings.go index fa651d0..445fc11 100644 --- a/setup_settings.go +++ b/web/setup_settings.go @@ -3,12 +3,11 @@ // // Web routes for configuring the event settings. -package main +package web import ( "fmt" "github.com/Team254/cheesy-arena/model" - "html/template" "io" "io/ioutil" "net/http" @@ -36,7 +35,6 @@ func (web *Web) settingsPostHandler(w http.ResponseWriter, r *http.Request) { eventSettings := web.arena.EventSettings eventSettings.Name = r.PostFormValue("name") - eventSettings.Code = r.PostFormValue("code") match, _ := regexp.MatchString("^#([0-9A-Fa-f]{3}){1,2}$", r.PostFormValue("displayBackgroundColor")) if !match { web.renderSettings(w, r, "Display background color must be a valid hex color value.") @@ -91,7 +89,7 @@ func (web *Web) saveDbHandler(w http.ResponseWriter, r *http.Request) { return } - dbFile, err := os.Open(web.arena.Database.GetPath()) + dbFile, err := os.Open(web.arena.Database.Path) defer dbFile.Close() if err != nil { handleWebErr(w, err) @@ -147,17 +145,17 @@ func (web *Web) restoreDbHandler(w http.ResponseWriter, r *http.Request) { // Replace the current database with the new one. web.arena.Database.Close() - err = os.Remove(eventDbPath) + err = os.Remove(web.arena.Database.Path) if err != nil { handleWebErr(w, err) return } - err = os.Rename(tempFilePath, eventDbPath) + err = os.Rename(tempFilePath, web.arena.Database.Path) if err != nil { handleWebErr(w, err) return } - web.arena.Database, err = model.OpenDatabase(eventDbPath) + web.arena.Database, err = model.OpenDatabase(web.arena.Database.Path) if err != nil { handleWebErr(w, err) return @@ -208,7 +206,7 @@ func (web *Web) clearDbHandler(w http.ResponseWriter, r *http.Request) { } func (web *Web) renderSettings(w http.ResponseWriter, r *http.Request, errorMessage string) { - template, err := template.ParseFiles("templates/setup_settings.html", "templates/base.html") + template, err := web.parseFiles("templates/setup_settings.html", "templates/base.html") if err != nil { handleWebErr(w, err) return diff --git a/setup_settings_test.go b/web/setup_settings_test.go similarity index 96% rename from setup_settings_test.go rename to web/setup_settings_test.go index 7643b3a..12cf925 100644 --- a/setup_settings_test.go +++ b/web/setup_settings_test.go @@ -1,11 +1,10 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( "bytes" - "fmt" "github.com/Team254/cheesy-arena/game" "github.com/Team254/cheesy-arena/model" "github.com/Team254/cheesy-arena/tournament" @@ -24,7 +23,6 @@ func TestSetupSettings(t *testing.T) { recorder := web.getHttpResponse("/setup/settings") assert.Equal(t, 200, recorder.Code) assert.Contains(t, recorder.Body.String(), "Untitled Event") - assert.Contains(t, recorder.Body.String(), "UE") assert.Contains(t, recorder.Body.String(), "#00ff00") assert.Contains(t, recorder.Body.String(), "8") assert.NotContains(t, recorder.Body.String(), "tbaPublishingEnabled\" checked") @@ -35,7 +33,6 @@ func TestSetupSettings(t *testing.T) { assert.Equal(t, 302, recorder.Code) recorder = web.getHttpResponse("/setup/settings") assert.Contains(t, recorder.Body.String(), "Chezy Champs") - assert.Contains(t, recorder.Body.String(), "CC") assert.Contains(t, recorder.Body.String(), "#ff00ff") assert.Contains(t, recorder.Body.String(), "16") assert.Contains(t, recorder.Body.String(), "tbaPublishingEnabled\" checked") @@ -109,8 +106,8 @@ func TestSetupSettingsBackupRestoreDb(t *testing.T) { // Check restoring with the backup retrieved before. recorder = web.postFileHttpResponse("/setup/db/restore", "databaseFile", backupBody) - fmt.Println(recorder.Body.String()) assert.Equal(t, "Chezy Champs", web.arena.EventSettings.Name) + } func (web *Web) postFileHttpResponse(path string, paramName string, file *bytes.Buffer) *httptest.ResponseRecorder { diff --git a/setup_sponsor_slides.go b/web/setup_sponsor_slides.go similarity index 94% rename from setup_sponsor_slides.go rename to web/setup_sponsor_slides.go index 4810baf..7f3ce2b 100644 --- a/setup_sponsor_slides.go +++ b/web/setup_sponsor_slides.go @@ -3,11 +3,10 @@ // // Web routes for managing sponsor slides. -package main +package web import ( "github.com/Team254/cheesy-arena/model" - "html/template" "net/http" "strconv" ) @@ -18,7 +17,7 @@ func (web *Web) sponsorSlidesGetHandler(w http.ResponseWriter, r *http.Request) return } - template, err := template.ParseFiles("templates/setup_sponsor_slides.html", "templates/base.html") + template, err := web.parseFiles("templates/setup_sponsor_slides.html", "templates/base.html") if err != nil { handleWebErr(w, err) return diff --git a/setup_sponsor_slides_test.go b/web/setup_sponsor_slides_test.go similarity index 99% rename from setup_sponsor_slides_test.go rename to web/setup_sponsor_slides_test.go index db76899..6f7dabf 100644 --- a/setup_sponsor_slides_test.go +++ b/web/setup_sponsor_slides_test.go @@ -1,7 +1,7 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( "github.com/Team254/cheesy-arena/model" diff --git a/setup_teams.go b/web/setup_teams.go similarity index 97% rename from setup_teams.go rename to web/setup_teams.go index 89b7fdc..f085f9f 100644 --- a/setup_teams.go +++ b/web/setup_teams.go @@ -3,7 +3,7 @@ // // Web routes for configuring the team list. -package main +package web import ( "bytes" @@ -11,7 +11,6 @@ import ( "github.com/Team254/cheesy-arena/model" "github.com/dchest/uniuri" "github.com/gorilla/mux" - "html/template" "net/http" "strconv" "strings" @@ -100,7 +99,7 @@ func (web *Web) teamEditGetHandler(w http.ResponseWriter, r *http.Request) { return } - template, err := template.ParseFiles("templates/edit_team.html", "templates/base.html") + template, err := web.parseFiles("templates/edit_team.html", "templates/base.html") if err != nil { handleWebErr(w, err) return @@ -234,7 +233,7 @@ func (web *Web) renderTeams(w http.ResponseWriter, r *http.Request, showErrorMes return } - template, err := template.ParseFiles("templates/setup_teams.html", "templates/base.html") + template, err := web.parseFiles("templates/setup_teams.html", "templates/base.html") if err != nil { handleWebErr(w, err) return diff --git a/setup_teams_test.go b/web/setup_teams_test.go similarity index 99% rename from setup_teams_test.go rename to web/setup_teams_test.go index 2855f64..a4252cc 100644 --- a/setup_teams_test.go +++ b/web/setup_teams_test.go @@ -1,7 +1,7 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( "fmt" diff --git a/web.go b/web/web.go similarity index 95% rename from web.go rename to web/web.go index 2d9f28d..f4ad334 100644 --- a/web.go +++ b/web/web.go @@ -3,7 +3,7 @@ // // Configuration and functions for the event server web interface. -package main +package web import ( "bitbucket.org/rj/httpauth-go" @@ -13,6 +13,7 @@ import ( "github.com/gorilla/mux" "log" "net/http" + "path/filepath" "text/template" ) @@ -55,9 +56,19 @@ func NewWeb(arena *field.Arena) *Web { return web } +// Starts the webserver and blocks, waiting on requests. Does not return until the application exits. +func (web *Web) ServeWebInterface(port int) { + http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static/")))) + http.Handle("/", web.newHandler()) + log.Printf("Serving HTTP requests on port %d", port) + + // Start Server + http.ListenAndServe(fmt.Sprintf(":%d", port), nil) +} + // Serves the root page of Cheesy Arena. func (web *Web) indexHandler(w http.ResponseWriter, r *http.Request) { - template, err := template.ParseFiles("templates/index.html", "templates/base.html") + template, err := web.parseFiles("templates/index.html", "templates/base.html") if err != nil { handleWebErr(w, err) return @@ -72,16 +83,6 @@ func (web *Web) indexHandler(w http.ResponseWriter, r *http.Request) { } } -// Starts the webserver and blocks, waiting on requests. Does not return until the application exits. -func (web *Web) ServeWebInterface(port int) { - http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static/")))) - http.Handle("/", web.newHandler()) - log.Printf("Serving HTTP requests on port %d", port) - - // Start Server - http.ListenAndServe(fmt.Sprintf(":%d", port), nil) -} - // Returns true if the given user is authorized for admin operations. Used for HTTP Basic Auth. func (web *Web) userIsAdmin(w http.ResponseWriter, r *http.Request) bool { if web.arena.EventSettings.AdminPassword == "" { @@ -192,3 +193,14 @@ func (web *Web) newHandler() http.Handler { func handleWebErr(w http.ResponseWriter, err error) { http.Error(w, "Internal server error: "+err.Error(), 500) } + +// Prepends the base directory to the template filenames. +func (web *Web) parseFiles(filenames ...string) (*template.Template, error) { + var paths []string + for _, filename := range filenames { + paths = append(paths, filepath.Join(model.BaseDir, filename)) + } + + template := template.New("").Funcs(web.templateHelpers) + return template.ParseFiles(paths...) +} diff --git a/web_test.go b/web/web_test.go similarity index 93% rename from web_test.go rename to web/web_test.go index 13ab091..7e4f99c 100644 --- a/web_test.go +++ b/web/web_test.go @@ -1,9 +1,10 @@ // Copyright 2014 Team 254. All Rights Reserved. // Author: pat@patfairbank.com (Patrick Fairbank) -package main +package web import ( + "github.com/Team254/cheesy-arena/field" "github.com/stretchr/testify/assert" "net/http" "net/http/httptest" @@ -68,3 +69,8 @@ func readWebsocketMultiple(t *testing.T, ws *Websocket, count int) map[string]in } return messages } + +func setupTestWeb(t *testing.T) *Web { + arena := field.SetupTestArena(t, "web") + return NewWeb(arena) +} diff --git a/websocket.go b/web/websocket.go similarity index 99% rename from websocket.go rename to web/websocket.go index ef9425f..8f6db1b 100644 --- a/websocket.go +++ b/web/websocket.go @@ -3,7 +3,7 @@ // // Functions for the server side of handling websockets. -package main +package web import ( "github.com/gorilla/websocket"