Unverified Commit f6e075fa authored by Yann DELABY's avatar Yann DELABY
Browse files

Merge branch 'club-ranking'

parents b7adc570 cc1d031e
use serde::Serialize;
use super::club::Club;
use super::club_ranking::ClubRanking;
use super::class::Class;
use super::regatta::Regatta;
......@@ -11,17 +12,20 @@ pub struct Championship {
edition: String,
pub clubs: Vec<Club>,
pub classes: Vec<Class>,
// list of classes counted in clubs ranking (class id, class weight)
club_ranking_classes: Vec<Vec<(u32, u32)>>,
regattas: Vec<Regatta>,
}
impl Championship {
/// Initialie a new championship
/// Initialize a new championship
pub fn new() -> Championship {
let mut new_cs = Championship {
name: String::new(),
edition: String::new(),
clubs: Vec::new(),
classes: Vec::new(),
club_ranking_classes: Vec::new(),
regattas: Vec::new(),
};
new_cs.add_club("".to_string(), "".to_string(), "".to_string());
......@@ -61,6 +65,9 @@ impl Championship {
search_string: search_string,
}
);
// Add this class to list of results classes
self.add_club_ranking_classes(vec!((self.classes.len() as u32 - 1, 0)));
}
/// Get ranking class id from string
......@@ -73,4 +80,34 @@ impl Championship {
}
id
}
/// Get ranking class id from class code
pub fn get_class_from_code(&self, code: String) -> u32 {
let mut id: u32 = 0;
for class in &self.classes {
if class.code == code {
id = class.id;
}
}
id
}
/// Add this class or classes to list of classes counted in club ranking
pub fn add_club_ranking_classes(&mut self, classes: Vec<(u32, u32)>) {
// Get id of class to remove
for class in &classes {
for (i, cla) in self.club_ranking_classes.clone().iter().enumerate() {
if cla[0].0 == class.0 {
self.club_ranking_classes.remove(i);
}
}
}
self.club_ranking_classes.push(classes);
}
/// Add a regatta to this championship
pub fn add_regatta(&mut self, regatta: Regatta) {
self.regattas.push(regatta);
}
}
use serde::Serialize;
/// A ranking class
#[derive(Serialize)]
#[derive(Serialize, Debug)]
pub struct Class {
pub id: u32,
pub name: String,
......
use serde::Serialize;
/// A club ranking.
#[derive(Serialize)]
pub struct ClubRanking {
pub rank: i32,
pub club_id: String,
/// Sailing club full name as string
pub club_name: String,
/// Net points
pub points_net: f64,
/// Total points
pub points_total: f64,
/// Points per classes (places, points, removed)
pub points_per_classes: Vec<(u32, f64, bool)>,
}
impl ClubRanking {
/// Initialize new Ranking
pub fn new() -> ClubRanking {
ClubRanking {
rank: 0,
club_id: String::new(),
club_name: String::new(),
points_net: 0.0,
points_total: 0.0,
points_per_classes: Vec::new(),
}
}
}
......@@ -94,7 +94,8 @@
\pagebreak
{{#each results}}
{{#each championship.regattas}}
{{#each this.class_results}}
\subsection{ {{this.class_name}} }
{\scriptsize
\begin{longtable}[h!]{rrllcccccccccccccccccccccccccccccccccccc}
......@@ -149,7 +150,7 @@
\endlastfoot
{{#each this.rankings}}
{{#each this.racers_rankings}}
\textbf{ {{this.rank}} }
& {{this.id}}
& \rmfamily{\href{http://www.ffvoile.fr/ffv/sportif/cif/cif_detail.aspx?NoLicence={{this.ffv_id}}}{ {{this.name}} }}
......@@ -172,6 +173,7 @@
\pagebreak
{{/each}}
{{/each}}
\section{E. V. Locquirec | 05-10-2019}
......
......@@ -10,9 +10,11 @@ mod club;
mod regatta;
mod regatta_class_result;
mod racer_ranking;
mod club_ranking;
use championship::Championship;
use racer_ranking::RacerRanking as Ranking;
use regatta::Regatta;
use regatta_class_result::RegattaClassResult;
/// Handlebars helper adding the correct number of races to group results header
......@@ -178,6 +180,34 @@ fn parse_group(cs: &Championship, group: scraper::element_ref::ElementRef) -> Re
group_result
}
/// Parse a regatta results HTML file
fn parse_regatta(cs: &Championship, file: String) -> Regatta {
// List of regatta's races results
let mut regatta = Regatta::new(1, "today".to_string());
let fragment = Html::parse_fragment(&file);
// HTML selector
let selector_group = Selector::parse("div center").unwrap();
// Tables iterator
let group_iter = fragment.select(&selector_group);
// For each center markup
for group in group_iter {
// Parse only center containing results
if group.inner_html().find("size=\"2\"").is_none() {
regatta.add_results(parse_group(&cs, group));
}
}
// Calculate rankings
regatta.calculate_clubs_rankings(cs);
// Return regatta
regatta
}
// Program main function
pub fn main() {
// Impl write trait to vector of u8
......@@ -203,26 +233,17 @@ pub fn main() {
cs.add_class("Planche 1ère année".to_string(), "PA1".to_string(), "PAV 1".to_string());
cs.add_class("Planche".to_string(), "PAV".to_string(), "PLANC".to_string());
// List of regatta's races results
let mut regatta_results = Vec::new();
// Read from HTML file, convert to utf-8
let doc: String = std::fs::read("iso8859-1.html").unwrap().iter().map(|&c| c as char).collect();
let fragment = Html::parse_fragment(&doc);
// Group classes
cs.add_club_ranking_classes(vec!((cs.get_class_from_code("OPE".to_string()), 0),
(cs.get_class_from_code("OP1".to_string()), 1)));
// HTML selector
let selector_group = Selector::parse("div center").unwrap();
cs.add_club_ranking_classes(vec!((cs.get_class_from_code("PAV".to_string()), 0),
(cs.get_class_from_code("PA1".to_string()), 1)));
// Tables iterator
let group_iter = fragment.select(&selector_group);
// Read from HTML file, convert to utf-8
let doc: String = std::fs::read("iso8859-1.html").unwrap().iter().map(|&c| c as char).collect();
// For each center markup
for group in group_iter {
// Parse only center containing results
if group.inner_html().find("size=\"2\"").is_none() {
regatta_results.push(parse_group(&cs, group));
}
}
cs.add_regatta(parse_regatta(&cs, doc));
// Handlebars instance
let mut handlebars = Handlebars::new();
......@@ -233,7 +254,7 @@ pub fn main() {
handlebars.register_helper("for_races", Box::new(for_races_helper));
// Insert all group results to handlebars instance
data.insert("results".to_string(), to_json(&regatta_results));
data.insert("championship".to_string(), to_json(&cs));
// Template file
let source_template = include_str!("kampionad.tex");
......
use serde::Serialize;
use super::championship::Championship;
use super::club_ranking::ClubRanking;
use super::regatta_class_result::RegattaClassResult;
/// A regatta
#[derive(Serialize)]
pub struct Regatta {
id: u32,
date: String,
class_results: Vec<RegattaClassResult>,
clubs_rankings: Vec<ClubRanking>,
}
impl Regatta {
/// Initialize a new regatta
pub fn new(id: u32, date: String) -> Regatta {
Regatta {
id: id,
date: date,
class_results: Vec::new(),
clubs_rankings: Vec::new(),
}
}
/// Add a new class result to the regatta
pub fn add_results(&mut self, result: RegattaClassResult) {
self.class_results.push(result);
}
/// Calculate clubs rankings
pub fn calculate_clubs_rankings(&mut self, cs: &Championship) {
// For each real clubs
for club in &cs.clubs {
if club.id != 0 {
// New calculated ranking
let new_ranking = ClubRanking::new();
//
}
}
}
}
use serde::Serialize;
use super::racer_ranking::RacerRanking;
use super::club_ranking::ClubRanking;
/// Regatta results for a class.
#[derive(Serialize)]
......@@ -16,7 +17,9 @@ pub struct RegattaClassResult {
/// Number of races keeped for ranking
pub races_net: u32,
/// Racers rankings
rankings: Vec<RacerRanking>,
racers_rankings: Vec<RacerRanking>,
/// Clubs rankings
clubs_rankings: Vec<ClubRanking>,
}
impl RegattaClassResult {
......@@ -28,13 +31,14 @@ impl RegattaClassResult {
registrants: 0,
races_total: 0,
races_net: 0,
rankings: Vec::new(),
racers_rankings: Vec::new(),
clubs_rankings: Vec::new(),
}
}
/// Add a new racer ranking
pub fn add(&mut self, ranking: RacerRanking) {
self.rankings.push(ranking);
self.racers_rankings.push(ranking);
self.registrants = self.registrants + 1;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment