Skip to content

Commit

Permalink
Standings view (#19)
Browse files Browse the repository at this point in the history
Adds a basic table of the league standings to the `Standings` tab.
  • Loading branch information
andschneider authored Jun 21, 2021
1 parent 68f860d commit 51b85a7
Show file tree
Hide file tree
Showing 19 changed files with 44,578 additions and 51 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@
.idea/
.vscode/
api/target/

.DS_Store
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- Standings view: [PR 19](https://github.com/mlb-rs/mlbt/pull/19)
- Added integration tests for the API

## [0.0.7] - 2021-06-05

- Separate threads for network calls and rendering.
Expand Down
76 changes: 72 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[package]
name = "mlbt"
version = "0.0.7"
version = "0.0.7-alpha1"
authors = ["Andrew Schneider <andjschneider@gmail.com>"]
edition = "2018"

[workspace]
members = [".", "api"]

[dependencies]
mlb-api = {path = "api/", version = "0.0.4"}
mlb-api = {path = "api/", version = "0.0.4-alpha1"}
chrono = "0.4"
chrono-tz = "0.5"
crossbeam-channel = "0.5"
Expand Down
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ TODO - add to crates.io

- [X] gameday

- [ ] standings
- [X] standings
- [ ] team information

- [ ] stats
- [ ] player stats
Expand Down Expand Up @@ -109,14 +110,14 @@ Press `2` to activate this tab.

Each pane can be toggled on and off using:

- info pane: `i`
- pitches pane: `p`
- box score pane: `b`
- `i`: info pane
- `p`: pitches pane
- `b`: box score pane

To switch the team displayed in the box score:

- `h` for the home team
- `a` for the away team
- `h`: home team
- `a`: away team

### Stats

Expand All @@ -128,7 +129,9 @@ TODO

Press `4` to activate this tab.

TODO
To select different teams, use `j` and `k`.

TODO Press `Enter` to display a teams roster.

### Help

Expand Down
5 changes: 4 additions & 1 deletion api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mlb-api"
version = "0.0.4"
version = "0.0.4-alpha1"
authors = ["Andrew Schneider <andjschneider@gmail.com>"]
edition = "2018"

Expand All @@ -12,3 +12,6 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
strum = "0.20"
strum_macros = "0.20"

[dev-dependencies]
mockito = "0.30"
43 changes: 23 additions & 20 deletions api/src/client.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::live::LiveResponse;
use crate::schedule::ScheduleResponse;
use crate::{live, schedule};
use crate::standings::StandingsResponse;

use chrono::NaiveDate;
use chrono::{DateTime, Datelike, Local, NaiveDate};
use derive_builder::Builder;
use reqwest::blocking::Client;
use serde::de::DeserializeOwned;
Expand All @@ -22,7 +22,7 @@ pub struct MLBApi {
impl MLBApi {
pub fn get_todays_schedule(&self) -> ScheduleResponse {
let url = format!("{}v1/schedule?sportId=1", self.base_url);
self.get::<schedule::ScheduleResponse>(url)
self.get::<ScheduleResponse>(url)
}

pub fn get_schedule_date(&self, date: NaiveDate) -> ScheduleResponse {
Expand All @@ -31,7 +31,7 @@ impl MLBApi {
self.base_url,
date.format("%Y-%m-%d").to_string()
);
self.get::<schedule::ScheduleResponse>(url)
self.get::<ScheduleResponse>(url)
}

pub fn get_live_data(&self, game_id: u64) -> LiveResponse {
Expand All @@ -42,25 +42,28 @@ impl MLBApi {
"{}v1.1/game/{}/feed/live?language=en",
self.base_url, game_id
);
self.get::<live::LiveResponse>(url)
self.get::<LiveResponse>(url)
}

pub fn get_standings(&self) -> StandingsResponse {
let local: DateTime<Local> = Local::now();
let url = format!(
"{}v1/standings?sportId=1&season={}&date={}&leagueId=103,104",
self.base_url,
local.year().to_string(),
local.format("%Y-%m-%d").to_string(),
);
self.get::<StandingsResponse>(url)
}

// TODO need better error handling, especially on parsing
fn get<T: Default + DeserializeOwned>(&self, url: String) -> T {
let response = self.client.get(url).send();
let response = match response {
Ok(r) => r,
Err(e) => {
panic!("network error {:?}", e);
}
};
let json = response.json::<T>().map(From::from);
match json {
Ok(j) => j,
Err(e) => {
eprintln!("parsing error {:?}", e);
T::default()
}
}
let response = self.client.get(url).send().unwrap_or_else(|err| {
panic!("network error {:?}", err);
});
response.json::<T>().map(From::from).unwrap_or_else(|err| {
eprintln!("parsing error {:?}", err);
T::default()
})
}
}
1 change: 1 addition & 0 deletions api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pub mod client;
pub mod live;
pub mod plays;
pub mod schedule;
pub mod standings;
91 changes: 91 additions & 0 deletions api/src/standings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
use crate::schedule::IdNameLink;
use serde::{Deserialize, Serialize};

#[derive(Default, Debug, Serialize, Deserialize)]
pub struct StandingsResponse {
pub copyright: String,
pub records: Vec<Record>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Record {
#[serde(rename = "standingsType")]
pub standings_type: String,
pub league: IdLink,
pub division: IdLink,
#[serde(rename = "lastUpdated")]
pub last_updated: String,
#[serde(rename = "teamRecords")]
pub team_records: Vec<TeamRecord>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct IdLink {
pub id: u8,
pub link: String,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TeamRecord {
pub team: IdNameLink,
pub season: String,
pub streak: Streak,
pub division_rank: String,
pub league_rank: String,
pub sport_rank: String,
pub games_played: u8,
pub games_back: String,
pub wild_card_games_back: String,
pub league_games_back: String,
pub sport_games_back: String,
pub division_games_back: String,
pub conference_games_back: String,
pub league_record: RecordElement,
pub last_updated: String,
pub records: Records,
pub runs_allowed: u16,
pub runs_scored: u16,
pub division_champ: bool,
pub division_leader: bool,
pub has_wildcard: bool,
pub clinched: bool,
pub elimination_number: String,
pub magic_number: Option<String>,
pub wins: u8,
pub losses: u8,
pub run_differential: i16,
pub winning_percentage: String,
pub wild_card_rank: Option<String>,
pub wild_card_leader: Option<bool>,
pub wild_card_elimination_number: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct RecordElement {
pub wins: u8,
pub losses: u8,
pub pct: String,
pub division: Option<IdNameLink>,
#[serde(rename = "type")]
pub record_type: Option<String>,
pub league: Option<IdNameLink>,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Records {
pub split_records: Vec<RecordElement>,
pub division_records: Vec<RecordElement>,
pub overall_records: Vec<RecordElement>,
pub league_records: Vec<RecordElement>,
pub expected_records: Vec<RecordElement>,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Streak {
pub streak_type: String,
pub streak_number: u8,
pub streak_code: String,
}
Loading

0 comments on commit 51b85a7

Please sign in to comment.