Commit bfddb09a authored by Robert Czechowski's avatar Robert Czechowski
Browse files

Add group user list csv download

parent 287fd6d5
......@@ -21,14 +21,21 @@ pub fn parse_yaml(content: &str, filename: &str, directory: &str) -> Option<Cont
let config: ContestYaml = serde_yaml::from_str(&content).unwrap();
use self::time::{strptime, Timespec};
let mut contest = Contest::new(directory.to_string(),
filename.to_string(),
config.name?,
config.duration_minutes?,
config.public_listing.unwrap_or(false),
config.participation_start.map(|x| strptime(&x, &"%FT%T%z").map(|t| t.to_timespec()).unwrap_or_else(|_| Timespec::new(0, 0))),
config.participation_end.map(|x| strptime(&x, &"%FT%T%z").map(|t| t.to_timespec()).unwrap_or_else(|_| Timespec::new(0, 0))));
let mut contest =
Contest::new(directory.to_string(),
filename.to_string(),
config.name?,
config.duration_minutes?,
config.public_listing.unwrap_or(false),
config.participation_start
.map(|x| {
strptime(&x, &"%FT%T%z").map(|t| t.to_timespec()).unwrap_or_else(|_| Timespec::new(0, 0))
}),
config.participation_end
.map(|x| {
strptime(&x, &"%FT%T%z").map(|t| t.to_timespec()).unwrap_or_else(|_| Timespec::new(0, 0))
}));
// TODO: Timeparsing should fail more pleasantly (-> Panic, thus shows message)
for (positionalnumber, (name, info)) in config.tasks?.into_iter().enumerate() {
......
......@@ -141,14 +141,11 @@ pub fn show_contests<T: MedalConnection>(conn: &T, session_token: &str, visibili
let session = conn.get_session_or_new(&session_token);
fill_user_data(&session, &mut data);
if session.is_logged_in() {
data.insert("can_start".to_string(), to_json(&true));
}
let v: Vec<ContestInfo> = conn.get_contest_list()
.iter()
.map(|c| ContestInfo { id: c.id.unwrap(),
......@@ -312,7 +309,7 @@ pub fn show_contest_results<T: MedalConnection>(conn: &T, contest_id: i32, sessi
let session = conn.get_session(&session_token).ensure_logged_in().ok_or(MedalError::NotLoggedIn)?;
let mut data = json_val::Map::new();
fill_user_data(&session, &mut data);
let (tasknames, resultdata) = conn.get_contest_groups_grades(session.id, contest_id);
let mut results: Vec<(String, i32, Vec<(String, i32, Vec<String>)>)> = Vec::new();
......@@ -348,7 +345,6 @@ pub fn show_contest_results<T: MedalConnection>(conn: &T, contest_id: i32, sessi
results.push((format!("{}", group.name), group.id.unwrap_or(0), groupresults));
}
data.insert("taskname".to_string(), to_json(&tasknames));
data.insert("result".to_string(), to_json(&results));
......@@ -382,7 +378,7 @@ pub fn start_contest<T: MedalConnection>(conn: &T, contest_id: i32, session_toke
return Err(MedalError::AccessDenied);
}
}
// Check logged in or open contest
if c.duration != 0 && !session.is_logged_in() {
return Err(MedalError::AccessDenied);
......@@ -585,7 +581,7 @@ pub struct MemberInfo {
pub fn show_group<T: MedalConnection>(conn: &T, group_id: i32, session_token: &str) -> MedalValueResult {
let session = conn.get_session(&session_token).ensure_logged_in().ok_or(MedalError::NotLoggedIn)?;
let group = conn.get_group_complete(group_id).unwrap(); // TODO handle error
let mut data = json_val::Map::new();
fill_user_data(&session, &mut data);
......@@ -610,6 +606,7 @@ pub fn show_group<T: MedalConnection>(conn: &T, group_id: i32, session_token: &s
data.insert("group".to_string(), to_json(&gi));
data.insert("member".to_string(), to_json(&v));
data.insert("groupname".to_string(), to_json(&gi.name));
Ok(("group".to_string(), data))
}
......
......@@ -595,6 +595,29 @@ fn group<C>(req: &mut Request) -> IronResult<Response>
Ok(resp)
}
fn group_download<C>(req: &mut Request) -> IronResult<Response>
where C: MedalConnection + std::marker::Send + 'static {
let group_id = req.expect_int::<i32>("groupid")?;
let session_token = req.require_session_token()?;
let (template, data) = with_conn![core::show_group, C, req, group_id, &session_token].aug(req)?;
use iron::headers::{Charset, ContentDisposition, DispositionParam, DispositionType};
let cd = ContentDisposition { disposition: DispositionType::Attachment,
parameters: vec![DispositionParam::Filename(
Charset::Ext("Utf-8".to_string()), // The character set for the bytes of the filename
None, // The optional language tag (see `language-tag` crate)
format!("{}.csv", data.get("groupname").unwrap().as_str().unwrap()).as_bytes().to_vec(), // the actual bytes of the filename
// TODO: The name should be returned by core::show_group directly
)] };
let mut resp = Response::new();
resp.headers.set(cd);
resp.set_mut(Template::new(&format!("{}_download", template), data)).set_mut(status::Ok);
Ok(resp)
}
//TODO: Secure with CSRF-Token?
fn group_post<C>(req: &mut Request) -> IronResult<Response>
where C: MedalConnection + std::marker::Send + 'static {
......@@ -885,7 +908,7 @@ pub fn get_handlebars_engine(template_name: &str) -> impl AfterMiddleware {
// HandlebarsEngine will look up all files with "./examples/templates/**/*.hbs"
let mut hbse = HandlebarsEngine::new();
hbse.add(Box::new(DirectorySource::new(&format!("./templates/{}/", template_name) as &str, ".hbs")));
// load templates from all registered sources
if let Err(r) = hbse.reload() {
panic!("{}", r);
......@@ -949,6 +972,7 @@ pub fn start_server<C>(conn: C, config: Config) -> iron::error::HttpResult<iron:
groups: get "/group/" => groups::<C>,
groups: post "/group/" => new_group::<C>,
group: get "/group/:groupid" => group::<C>,
group_download: get "/group/download/:groupid" => group_download::<C>,
group_post: post "/group" => group_post::<C>,
groupcsv: get "/group/csv" => group_csv::<C>,
groupcsv_post: post "/group/csv" => group_csv_upload::<C>,
......
Vorname,Nachname,Jahrgangsstufe,Logincode
{{#each member}}{{group.name}},{{firstname}},{{lastname}},{{grade}},{{logincode}}
{{/each}}
\ No newline at end of file
../default/group_download.hbs
\ No newline at end of file
......@@ -41,6 +41,7 @@
<th>Mitglieder</th>
<th>Marker</th>
<th></th>
<th>Download</th>
</tr>
{{#each group}}
<tr>
......@@ -49,6 +50,7 @@
<td></td>
<td>{{tag}}</td>
<td><a href="/group/{{id}}">bearbeiten …</a></td>
<td><a href="/group/download/{{id}}">{{name}}.csv</a></td>
</tr>
{{/each}}
</table>
......
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