diff --git a/qa/api/qa.go b/qa/api/qa.go
index da03ec14..27f56881 100644
--- a/qa/api/qa.go
+++ b/qa/api/qa.go
@@ -17,6 +17,8 @@ func declareQARoutes(router *gin.RouterGroup) {
exercicesRoutes.GET("", getExerciceQA)
exercicesRoutes.POST("", createExerciceQA)
+ exercicesRoutes.GET("/export", exportQA)
+
qaRoutes := exercicesRoutes.Group("/:qid")
qaRoutes.Use(qaHandler)
qaRoutes.PUT("", updateExerciceQA)
@@ -83,6 +85,64 @@ func getExerciceQA(c *gin.Context) {
c.JSON(http.StatusOK, qa)
}
+func exportQA(c *gin.Context) {
+ var report string
+
+ themes, err := fic.GetThemes()
+ if err != nil {
+ log.Println("Unable to GetThemes: ", err.Error())
+ c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to list themes: %s", err.Error())})
+ return
+ }
+
+ for _, th := range themes {
+ report += fmt.Sprintf("# %s {#%s}\n\n", th.Name, th.URLId)
+
+ exercices, err := th.GetExercices()
+ if err != nil {
+ log.Println("Unable to GetExercices: ", err.Error())
+ c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to list exercices for theme #%d: %s", th.Id, err.Error())})
+ return
+ }
+
+ for _, exercice := range exercices {
+ report += fmt.Sprintf("## %s {#%s}\n\n", exercice.Title, exercice.URLId)
+
+ qa, err := exercice.GetQAQueries()
+ if err != nil {
+ log.Println("Unable to GetQAQueries: ", err.Error())
+ c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to list QA entries: %s", err.Error())})
+ return
+ }
+
+ for _, q := range qa {
+ emoji := "❓"
+
+ if q.Closed != nil {
+ emoji = "👌"
+ } else if q.Solved != nil {
+ emoji = "✅"
+ }
+
+ report += fmt.Sprintf("### %s [%s] %s\n\nOuvert par %s le %s\n\n", emoji, q.State, q.Subject, q.User, q.Creation)
+
+ comments, err := q.GetComments()
+ if err != nil {
+ log.Println("Unable to GetQAComments: ", err.Error())
+ c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to list QA comments: %s", err.Error())})
+ return
+ }
+
+ for _, c := range comments {
+ report += fmt.Sprintf("Le %s, %s :\n%s\n\n", c.Date, c.User, c.Content)
+ }
+ }
+ }
+ }
+
+ c.JSON(http.StatusOK, report)
+}
+
type QAQueryAndComment struct {
*fic.QAQuery
Content string `json:"content"`
diff --git a/qa/static.go b/qa/static.go
index 7ba09b06..90536692 100644
--- a/qa/static.go
+++ b/qa/static.go
@@ -120,6 +120,7 @@ func declareStaticRoutes(router *gin.RouterGroup, baseURL string) {
router.GET("/", serveOrReverse("", baseURL))
router.GET("/exercices", serveOrReverse("/", baseURL))
router.GET("/exercices/*_", serveOrReverse("/", baseURL))
+ router.GET("/export", serveOrReverse("/", baseURL))
router.GET("/themes", serveOrReverse("/", baseURL))
router.GET("/themes/*_", serveOrReverse("/", baseURL))
router.GET("/_app/*_", serveOrReverse("", baseURL))
diff --git a/qa/ui/src/routes/export/+page.svelte b/qa/ui/src/routes/export/+page.svelte
new file mode 100644
index 00000000..7103c2fd
--- /dev/null
+++ b/qa/ui/src/routes/export/+page.svelte
@@ -0,0 +1,16 @@
+
+
+
+ {#await fetch('api/qa/export')}
+
+ {:then res}
+ {#await res.json() then md}
+ {md}
+ {/await}
+ {/await}
+