Periodically refresh the match list for scouting
I've had a few instances where students thought that we didn't support
eliminations matches because they don't show up when first importing
the match list. The eliminations matches are only importable after the
alliance selections.
To work around this, the webserver now periodically imports the latest
match list. This means we don't need anyone to manually use the
"Import Match List" tab on the app anymore. I deleted that tab as
part of this patch.
The new `scouting/webserver/match_list/match_list.go` file is largely
just the code that I deleted from
`scouting/webserver/requests/requests.go`. I.e. it's really just
moving code around. The main difference now is that instead of
`requests.go` handling match list imports,
`scouting/webserver/main.go` now starts a background task to scrape
the match list every 10 minutes or so.
Signed-off-by: Philipp Schrader <philipp.schrader@gmail.com>
Change-Id: Ic37df45261f03a323069c1b38c4fd9682a9c4a3e
diff --git a/scouting/www/BUILD b/scouting/www/BUILD
index cbcecc3..93bcbb2 100644
--- a/scouting/www/BUILD
+++ b/scouting/www/BUILD
@@ -17,7 +17,6 @@
"//:node_modules/@angular/animations",
"//scouting/www/driver_ranking:_lib",
"//scouting/www/entry:_lib",
- "//scouting/www/import_match_list:_lib",
"//scouting/www/match_list:_lib",
"//scouting/www/notes:_lib",
"//scouting/www/shift_schedule:_lib",
diff --git a/scouting/www/app/app.module.ts b/scouting/www/app/app.module.ts
index ead8b37..7b200d0 100644
--- a/scouting/www/app/app.module.ts
+++ b/scouting/www/app/app.module.ts
@@ -4,7 +4,6 @@
import {App} from './app';
import {EntryModule} from '../entry';
-import {ImportMatchListModule} from '../import_match_list';
import {MatchListModule} from '../match_list';
import {NotesModule} from '../notes';
import {ShiftScheduleModule} from '../shift_schedule';
@@ -18,7 +17,6 @@
BrowserAnimationsModule,
EntryModule,
NotesModule,
- ImportMatchListModule,
MatchListModule,
ShiftScheduleModule,
DriverRankingModule,
diff --git a/scouting/www/app/app.ng.html b/scouting/www/app/app.ng.html
index d9dbead..526cd61 100644
--- a/scouting/www/app/app.ng.html
+++ b/scouting/www/app/app.ng.html
@@ -49,15 +49,6 @@
<li class="nav-item">
<a
class="nav-link"
- [class.active]="tabIs('ImportMatchList')"
- (click)="switchTabToGuarded('ImportMatchList')"
- >
- Import Match List
- </a>
- </li>
- <li class="nav-item">
- <a
- class="nav-link"
[class.active]="tabIs('ShiftSchedule')"
(click)="switchTabToGuarded('ShiftSchedule')"
>
@@ -90,9 +81,6 @@
></app-entry>
<frc971-notes *ngSwitchCase="'Notes'"></frc971-notes>
<app-driver-ranking *ngSwitchCase="'DriverRanking'"></app-driver-ranking>
- <app-import-match-list
- *ngSwitchCase="'ImportMatchList'"
- ></app-import-match-list>
<shift-schedule *ngSwitchCase="'ShiftSchedule'"></shift-schedule>
<app-view
(switchTabsEvent)="switchTabTo($event)"
diff --git a/scouting/www/app/app.ts b/scouting/www/app/app.ts
index 7e81d84..f7d2770 100644
--- a/scouting/www/app/app.ts
+++ b/scouting/www/app/app.ts
@@ -5,12 +5,11 @@
| 'Notes'
| 'Entry'
| 'DriverRanking'
- | 'ImportMatchList'
| 'ShiftSchedule'
| 'View';
// Ignore the guard for tabs that don't require the user to enter any data.
-const unguardedTabs: Tab[] = ['MatchList', 'ImportMatchList'];
+const unguardedTabs: Tab[] = ['MatchList'];
type TeamInMatch = {
teamNumber: number;
diff --git a/scouting/www/import_match_list/BUILD b/scouting/www/import_match_list/BUILD
deleted file mode 100644
index bc1d5d5..0000000
--- a/scouting/www/import_match_list/BUILD
+++ /dev/null
@@ -1,18 +0,0 @@
-load("@npm//:defs.bzl", "npm_link_all_packages")
-load("//tools/build_rules:js.bzl", "ng_pkg")
-
-npm_link_all_packages(name = "node_modules")
-
-ng_pkg(
- name = "import_match_list",
- extra_srcs = [
- "//scouting/www:app_common_css",
- ],
- deps = [
- ":node_modules/@angular/forms",
- "//scouting/webserver/requests/messages:error_response_ts_fbs",
- "//scouting/webserver/requests/messages:refresh_match_list_response_ts_fbs",
- "//scouting/webserver/requests/messages:refresh_match_list_ts_fbs",
- "@com_github_google_flatbuffers//ts:flatbuffers_ts",
- ],
-)
diff --git a/scouting/www/import_match_list/import_match_list.component.css b/scouting/www/import_match_list/import_match_list.component.css
deleted file mode 100644
index e220645..0000000
--- a/scouting/www/import_match_list/import_match_list.component.css
+++ /dev/null
@@ -1,3 +0,0 @@
-* {
- padding: 10px;
-}
diff --git a/scouting/www/import_match_list/import_match_list.component.ts b/scouting/www/import_match_list/import_match_list.component.ts
deleted file mode 100644
index 526a636..0000000
--- a/scouting/www/import_match_list/import_match_list.component.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import {Component, OnInit} from '@angular/core';
-
-import {Builder, ByteBuffer} from 'flatbuffers';
-import {ErrorResponse} from '../../webserver/requests/messages/error_response_generated';
-import {RefreshMatchListResponse} from '../../webserver/requests/messages/refresh_match_list_response_generated';
-import {RefreshMatchList} from '../../webserver/requests/messages/refresh_match_list_generated';
-
-@Component({
- selector: 'app-import-match-list',
- templateUrl: './import_match_list.ng.html',
- styleUrls: ['../app/common.css', './import_match_list.component.css'],
-})
-export class ImportMatchListComponent {
- year: number = new Date().getFullYear();
- eventCode: string = '';
- progressMessage: string = '';
- errorMessage: string = '';
-
- async importMatchList() {
- const block_alerts = document.getElementById(
- 'block_alerts'
- ) as HTMLInputElement;
- console.log(block_alerts.checked);
- if (!block_alerts.checked) {
- if (!window.confirm('Actually import new matches?')) {
- return;
- }
- }
-
- this.errorMessage = '';
-
- const builder = new Builder();
- const eventCode = builder.createString(this.eventCode);
- RefreshMatchList.startRefreshMatchList(builder);
- RefreshMatchList.addYear(builder, this.year);
- RefreshMatchList.addEventCode(builder, eventCode);
- builder.finish(RefreshMatchList.endRefreshMatchList(builder));
-
- this.progressMessage = 'Importing match list. Please be patient.';
-
- const buffer = builder.asUint8Array();
- const res = await fetch('/requests/refresh_match_list', {
- method: 'POST',
- body: buffer,
- });
-
- if (res.ok) {
- // We successfully submitted the data.
- this.progressMessage = 'Successfully imported match list.';
- } else {
- this.progressMessage = '';
- const resBuffer = await res.arrayBuffer();
- const fbBuffer = new ByteBuffer(new Uint8Array(resBuffer));
- const parsedResponse = ErrorResponse.getRootAsErrorResponse(fbBuffer);
-
- const errorMessage = parsedResponse.errorMessage();
- this.errorMessage = `Received ${res.status} ${res.statusText}: "${errorMessage}"`;
- }
- }
-}
diff --git a/scouting/www/import_match_list/import_match_list.module.ts b/scouting/www/import_match_list/import_match_list.module.ts
deleted file mode 100644
index cdb6fea..0000000
--- a/scouting/www/import_match_list/import_match_list.module.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import {NgModule} from '@angular/core';
-import {CommonModule} from '@angular/common';
-import {ImportMatchListComponent} from './import_match_list.component';
-import {FormsModule} from '@angular/forms';
-
-@NgModule({
- declarations: [ImportMatchListComponent],
- exports: [ImportMatchListComponent],
- imports: [CommonModule, FormsModule],
-})
-export class ImportMatchListModule {}
diff --git a/scouting/www/import_match_list/import_match_list.ng.html b/scouting/www/import_match_list/import_match_list.ng.html
deleted file mode 100644
index fdd7687..0000000
--- a/scouting/www/import_match_list/import_match_list.ng.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<div class="header">
- <h2>Import Match List</h2>
-</div>
-
-<div class="container-fluid">
- <div class="row">
- <label for="year">Year</label>
- <input [(ngModel)]="year" type="number" id="year" min="1970" max="2500" />
- </div>
- <div class="row">
- <label for="event_code">Event Code</label>
- <input [(ngModel)]="eventCode" type="text" id="event_code" />
- </div>
-
- <span class="progress_message">{{ progressMessage }}</span>
- <span class="error_message">{{ errorMessage }}</span>
- <div class="text-right">
- <button class="btn btn-primary" (click)="importMatchList()">Import</button>
- </div>
-</div>
diff --git a/scouting/www/import_match_list/package.json b/scouting/www/import_match_list/package.json
deleted file mode 100644
index 05aa790..0000000
--- a/scouting/www/import_match_list/package.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "name": "@org_frc971/scouting/www/import_match_list",
- "private": true,
- "dependencies": {
- "@angular/forms": "15.1.5"
- }
-}