Compare commits
7 Commits
cb95df096d
...
eb6427ec6c
Author | SHA1 | Date | |
---|---|---|---|
eb6427ec6c | |||
bf556753b3 | |||
e486ad0c1b | |||
e9cc2e1331 | |||
364124db35 | |||
b2d2cd860c | |||
0a8e352622 |
73
main.go
73
main.go
@ -30,9 +30,10 @@ func Serve(w http.ResponseWriter, r *http.Request) {
|
|||||||
<head>
|
<head>
|
||||||
<title>` + title + `</title>
|
<title>` + title + `</title>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
|
||||||
<style>.table > tbody > tr > th, .table > tbody > tr > td { vertical-align: middle; }
|
<style>.table > tbody > tr > th, .table > tbody > tr > td { vertical-align: middle; }
|
||||||
td.danger { text-align: center; }
|
td.danger { text-align: center; }
|
||||||
|
.hash { max-width: 150px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; display: inline-block; }
|
||||||
</style>
|
</style>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
function disp(rendus) {
|
function disp(rendus) {
|
||||||
@ -42,6 +43,7 @@ function disp(rendus) {
|
|||||||
var row = document.createElement("tr");
|
var row = document.createElement("tr");
|
||||||
|
|
||||||
var col = document.createElement("th");
|
var col = document.createElement("th");
|
||||||
|
col.id = login;
|
||||||
col.innerHTML = login;
|
col.innerHTML = login;
|
||||||
row.appendChild(col);
|
row.appendChild(col);
|
||||||
|
|
||||||
@ -50,7 +52,7 @@ function disp(rendus) {
|
|||||||
if (work) {
|
if (work) {
|
||||||
var col = document.createElement("td");
|
var col = document.createElement("td");
|
||||||
col.className = "success";
|
col.className = "success";
|
||||||
col.innerHTML = work["date"] + "<br>" + work["hash"];
|
col.innerHTML = (new Intl.DateTimeFormat('default', { weekday: 'short', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric' }).format(new Date(work["date"]))) + '<br><span class="hash" title="' + work["hash"] + '">' + work["hash"] + '</span>';
|
||||||
row.appendChild(col);
|
row.appendChild(col);
|
||||||
} else {
|
} else {
|
||||||
var col = document.createElement("td");
|
var col = document.createElement("td");
|
||||||
@ -68,6 +70,35 @@ function disp(rendus) {
|
|||||||
document.getElementById("head").appendChild(col);
|
document.getElementById("head").appendChild(col);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function disp_std(rendus, login) {
|
||||||
|
Object.keys(rendus).map(function(label) {
|
||||||
|
var work = rendus[label];
|
||||||
|
|
||||||
|
var row = document.createElement("tr");
|
||||||
|
|
||||||
|
var col = document.createElement("th");
|
||||||
|
col.innerHTML = label;
|
||||||
|
row.appendChild(col);
|
||||||
|
|
||||||
|
if (work) {
|
||||||
|
var col = document.createElement("td");
|
||||||
|
col.className = "success";
|
||||||
|
col.innerHTML = (new Intl.DateTimeFormat('default', { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric' }).format(new Date(work["date"]))) + '<br>' + work["hash"];
|
||||||
|
row.appendChild(col);
|
||||||
|
} else {
|
||||||
|
var col = document.createElement("td");
|
||||||
|
col.className = "danger";
|
||||||
|
col.innerHTML = "<span class=\"glyphicon glyphicon-remove\" aria-hidden=\"true\"></span>";
|
||||||
|
row.appendChild(col);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("students").appendChild(row);
|
||||||
|
});
|
||||||
|
var col = document.createElement("th");
|
||||||
|
col.innerHTML = login;
|
||||||
|
document.getElementById("head").appendChild(col);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body class="container">
|
<body class="container">
|
||||||
@ -80,6 +111,16 @@ function disp(rendus) {
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
if (window.location.pathname[window.location.pathname.length - 1] != "/")
|
||||||
|
fetch(window.location.pathname.replace(".html", "") + ".json")
|
||||||
|
.then(function(response) {
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(function(submissions) {
|
||||||
|
var spl = window.location.pathname.split("/")
|
||||||
|
disp_std(submissions, spl[spl.length - 1]);
|
||||||
|
});
|
||||||
|
else
|
||||||
fetch('rendus.json') // You can also fetch login_x.json
|
fetch('rendus.json') // You can also fetch login_x.json
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
return response.json();
|
return response.json();
|
||||||
@ -136,7 +177,7 @@ func genStudent(login string) map[string]*Submission {
|
|||||||
ret[dir.Name()] = new(Submission)
|
ret[dir.Name()] = new(Submission)
|
||||||
ret[dir.Name()].Date = fi.ModTime()
|
ret[dir.Name()].Date = fi.ModTime()
|
||||||
if lnk, err := os.Readlink(p); err == nil {
|
if lnk, err := os.Readlink(p); err == nil {
|
||||||
ret[dir.Name()].Hash = strings.TrimPrefix(lnk, login + ".")
|
ret[dir.Name()].Hash = strings.TrimPrefix(lnk, login+".")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret[dir.Name()] = nil
|
ret[dir.Name()] = nil
|
||||||
@ -166,11 +207,22 @@ func ServeJSONStudent(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type arrayFlags []string
|
||||||
|
|
||||||
|
func (i *arrayFlags) String() string {
|
||||||
|
return fmt.Sprintf("%v", *i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *arrayFlags) Set(value string) error {
|
||||||
|
*i = append(*i, value)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var studentsFile string
|
var studentsFiles arrayFlags
|
||||||
|
|
||||||
var bind = flag.String("bind", "0.0.0.0:8081", "Bind port/socket")
|
var bind = flag.String("bind", "0.0.0.0:8081", "Bind port/socket")
|
||||||
flag.StringVar(&studentsFile, "students", "./students.csv", "Path to a CSV file containing in the third column the name of the directory to look for")
|
flag.Var(&studentsFiles, "students", "Path to a CSV file containing in the third column the name of the directory to look for (can be repeated multiple times)")
|
||||||
flag.StringVar(&rendusDir, "path", "./rendu/", "Path to the submissions directory (each subdirectory is a project)")
|
flag.StringVar(&rendusDir, "path", "./rendu/", "Path to the submissions directory (each subdirectory is a project)")
|
||||||
flag.StringVar(&title, "title", "Rendus VIRLI", "Title of the page")
|
flag.StringVar(&title, "title", "Rendus VIRLI", "Title of the page")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
@ -195,15 +247,22 @@ func main() {
|
|||||||
|
|
||||||
// Read and parse students list
|
// Read and parse students list
|
||||||
log.Println("Reading students files...")
|
log.Println("Reading students files...")
|
||||||
|
for _, studentsFile := range studentsFiles {
|
||||||
|
log.Println("Reading", studentsFile, "...")
|
||||||
if studentsFile, err = filepath.Abs(studentsFile); err != nil {
|
if studentsFile, err = filepath.Abs(studentsFile); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
} else if fi, err := os.Open(studentsFile); err != nil {
|
} else if fi, err := os.Open(studentsFile); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
} else {
|
} else {
|
||||||
|
var nstudents [][]string
|
||||||
|
|
||||||
r := csv.NewReader(bufio.NewReader(fi))
|
r := csv.NewReader(bufio.NewReader(fi))
|
||||||
if students, err = r.ReadAll(); err != nil {
|
if nstudents, err = r.ReadAll(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
students = append(students, nstudents...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
log.Println(len(students), "students loaded.")
|
log.Println(len(students), "students loaded.")
|
||||||
|
|
||||||
@ -211,7 +270,7 @@ func main() {
|
|||||||
http.HandleFunc("/", Serve)
|
http.HandleFunc("/", Serve)
|
||||||
http.HandleFunc("/rendus.json", ServeJSON)
|
http.HandleFunc("/rendus.json", ServeJSON)
|
||||||
for _, student := range students {
|
for _, student := range students {
|
||||||
http.HandleFunc("/" + student[2] + ".json", ServeJSONStudent)
|
http.HandleFunc("/"+student[2]+".json", ServeJSONStudent)
|
||||||
}
|
}
|
||||||
log.Println(fmt.Sprintf("Ready, listening on %s", *bind))
|
log.Println(fmt.Sprintf("Ready, listening on %s", *bind))
|
||||||
if err := http.ListenAndServe(*bind, nil); err != nil {
|
if err := http.ListenAndServe(*bind, nil); err != nil {
|
||||||
|
Reference in New Issue
Block a user