package web import ( "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(file) // THE UPLOAD FILE IS INMEDIATELY REMOVED // ONCE THE STATS ARE GENERATED // 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 mastodon := os.Getenv("MASTODON_INSTANCE_FOR_SHARING") stats["mastodon"] = mastodon tmpl, err := loadTemplates("result.html") if err != nil { http.Error(w, "Error loading template", http.StatusInternalServerError) return } tmpl.Execute(w, stats) }