mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 02:32:57 +00:00
dev day #62
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type DocsController struct {
|
||||
DocsPath string
|
||||
}
|
||||
|
||||
func NewDocsController(docsPath string) *DocsController {
|
||||
return &DocsController{
|
||||
DocsPath: docsPath,
|
||||
}
|
||||
}
|
||||
|
||||
// GetDocFile serves a specific documentation file
|
||||
func (dc *DocsController) GetDocFile(c *gin.Context) {
|
||||
// Get the requested file path from the URL
|
||||
docPath := c.Param("filepath")
|
||||
|
||||
// Security: Prevent directory traversal
|
||||
if strings.Contains(docPath, "..") {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid file path"})
|
||||
return
|
||||
}
|
||||
|
||||
// Build full path
|
||||
fullPath := filepath.Join(dc.DocsPath, docPath)
|
||||
|
||||
// Check if file exists and is a markdown file
|
||||
if !strings.HasSuffix(fullPath, ".md") {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Only markdown files are allowed"})
|
||||
return
|
||||
}
|
||||
|
||||
// Read the file
|
||||
content, err := ioutil.ReadFile(fullPath)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Documentation file not found"})
|
||||
return
|
||||
}
|
||||
|
||||
// Return the content as plain text
|
||||
c.Header("Content-Type", "text/markdown; charset=utf-8")
|
||||
c.String(http.StatusOK, string(content))
|
||||
}
|
||||
|
||||
// ListDocFiles returns a list of available documentation files
|
||||
func (dc *DocsController) ListDocFiles(c *gin.Context) {
|
||||
files, err := ioutil.ReadDir(dc.DocsPath)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to read documentation directory"})
|
||||
return
|
||||
}
|
||||
|
||||
var docFiles []map[string]interface{}
|
||||
|
||||
for _, file := range files {
|
||||
if !file.IsDir() && strings.HasSuffix(file.Name(), ".md") {
|
||||
docFiles = append(docFiles, map[string]interface{}{
|
||||
"name": file.Name(),
|
||||
"path": "/DOCS/" + file.Name(),
|
||||
"size": file.Size(),
|
||||
"modified_at": file.ModTime(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"files": docFiles,
|
||||
"total": len(docFiles),
|
||||
})
|
||||
}
|
||||
|
||||
// SearchDocs searches through documentation files
|
||||
func (dc *DocsController) SearchDocs(c *gin.Context) {
|
||||
query := c.Query("q")
|
||||
if query == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Search query is required"})
|
||||
return
|
||||
}
|
||||
|
||||
query = strings.ToLower(query)
|
||||
files, err := ioutil.ReadDir(dc.DocsPath)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to read documentation directory"})
|
||||
return
|
||||
}
|
||||
|
||||
var results []map[string]interface{}
|
||||
|
||||
for _, file := range files {
|
||||
if file.IsDir() || !strings.HasSuffix(file.Name(), ".md") {
|
||||
continue
|
||||
}
|
||||
|
||||
fullPath := filepath.Join(dc.DocsPath, file.Name())
|
||||
content, err := ioutil.ReadFile(fullPath)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
contentLower := strings.ToLower(string(content))
|
||||
nameLower := strings.ToLower(file.Name())
|
||||
|
||||
// Check if query matches filename or content
|
||||
if strings.Contains(nameLower, query) || strings.Contains(contentLower, query) {
|
||||
// Find context around match
|
||||
index := strings.Index(contentLower, query)
|
||||
start := 0
|
||||
end := len(content)
|
||||
|
||||
if index > 100 {
|
||||
start = index - 100
|
||||
}
|
||||
if index+len(query)+200 < len(content) {
|
||||
end = index + len(query) + 200
|
||||
}
|
||||
|
||||
excerpt := string(content[start:end])
|
||||
|
||||
results = append(results, map[string]interface{}{
|
||||
"name": file.Name(),
|
||||
"path": "/DOCS/" + file.Name(),
|
||||
"excerpt": excerpt,
|
||||
"matches": strings.Count(contentLower, query),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"results": results,
|
||||
"total": len(results),
|
||||
"query": query,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user