2024-12-05 14:00:58 +01:00
|
|
|
package web
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/google/uuid"
|
|
|
|
)
|
|
|
|
|
|
|
|
func handleIndex(w http.ResponseWriter, r *http.Request) {
|
|
|
|
tmpl, err := loadTemplates("index.html")
|
|
|
|
if err != nil {
|
|
|
|
http.Error(w, "Error loading template", http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
tmpl.Execute(w, nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
func handleUpload(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
|
|
if r.Method != http.MethodPost {
|
|
|
|
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
file, _, err := r.FormFile("file")
|
|
|
|
if err != nil {
|
|
|
|
http.Error(w, "Error reading file", http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
// Save temp file
|
|
|
|
uploadDir := os.Getenv("UPLOAD_DIR")
|
|
|
|
if uploadDir == "" {
|
|
|
|
uploadDir = "uploads"
|
|
|
|
}
|
|
|
|
os.MkdirAll(uploadDir, os.ModePerm)
|
|
|
|
tempFile, err := os.CreateTemp(uploadDir, "history-*.txt")
|
|
|
|
if err != nil {
|
|
|
|
http.Error(w, "Error saving file", http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
defer tempFile.Close()
|
|
|
|
|
|
|
|
_, err = io.Copy(tempFile, file)
|
|
|
|
if err != nil {
|
|
|
|
http.Error(w, "Error copying file", http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
commandCounts, categories, pipeRedirectionCounts, commonPatterns := ProcessHistory(tempFile.Name())
|
|
|
|
|
|
|
|
err = os.Remove(tempFile.Name())
|
|
|
|
if err != nil {
|
|
|
|
http.Error(w, "Error deleting temporary file", http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
limit := os.Getenv("TOP_N_COMMANDS")
|
|
|
|
limitInt, err := strconv.Atoi(limit)
|
|
|
|
if err != nil {
|
|
|
|
limitInt = 5
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stats
|
|
|
|
commandStats := ConvertAndSort(commandCounts, limitInt)
|
|
|
|
|
|
|
|
// Graph generation
|
|
|
|
bar := createBarChart(commandStats)
|
|
|
|
var chartHTML strings.Builder
|
|
|
|
if err := bar.Render(&chartHTML); err != nil {
|
|
|
|
http.Error(w, "Error generating chart", http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// More stats
|
|
|
|
stats := GenerateStats(commandCounts, categories, commonPatterns)
|
|
|
|
|
|
|
|
stats["chartHTML"] = chartHTML.String()
|
|
|
|
|
|
|
|
// Categories
|
|
|
|
categoryStats := ConvertAndSort(categories, limitInt)
|
|
|
|
stats["categoryStats"] = categoryStats
|
|
|
|
|
|
|
|
// Top commands
|
|
|
|
topCommands := ConvertAndSort(commandCounts, limitInt)
|
|
|
|
stats["topCommands"] = topCommands
|
|
|
|
|
|
|
|
// Common patterns
|
|
|
|
commonPatternStats := ConvertAndSort(commonPatterns, limitInt)
|
|
|
|
stats["commonPatternStats"] = commonPatternStats
|
|
|
|
|
|
|
|
// Pipe counts
|
|
|
|
stats["pipeRedirectionCounts"] = pipeRedirectionCounts
|
|
|
|
|
|
|
|
// Save results
|
|
|
|
uniqueID := uuid.New().String()
|
|
|
|
saveResults(uniqueID, stats)
|
|
|
|
|
|
|
|
http.Redirect(w, r, "/results/"+uniqueID, http.StatusSeeOther)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func handleResults(w http.ResponseWriter, r *http.Request) {
|
|
|
|
uniqueID := strings.TrimPrefix(r.URL.Path, "/results/")
|
|
|
|
|
|
|
|
stats, err := loadResults(uniqueID)
|
|
|
|
if err != nil {
|
|
|
|
http.Error(w, "Results not found", http.StatusNotFound)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
stats["uniqueID"] = uniqueID
|
|
|
|
baseURL := os.Getenv("BASE_URL")
|
|
|
|
if baseURL == "" {
|
|
|
|
baseURL = "https://wrappd.oscarmlage.com"
|
|
|
|
}
|
|
|
|
stats["baseURL"] = baseURL
|
|
|
|
|
2024-12-05 14:13:54 +01:00
|
|
|
mastodon := os.Getenv("MASTODON_INSTANCE_FOR_SHARING")
|
|
|
|
stats["mastodon"] = mastodon
|
|
|
|
|
2024-12-05 14:00:58 +01:00
|
|
|
tmpl, err := loadTemplates("result.html")
|
|
|
|
if err != nil {
|
|
|
|
http.Error(w, "Error loading template", http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
tmpl.Execute(w, stats)
|
|
|
|
}
|