From da03138d5cfe24c2919f28ce186d2edf9f5cc544 Mon Sep 17 00:00:00 2001 From: Joren Date: Mon, 23 Sep 2024 17:23:22 +0200 Subject: [PATCH] Implement logging, console window --- src/downloaders.go | 26 +++++++++++++++++++++----- src/handlers.go | 23 +++++++++++++++++++++++ src/logger.go | 36 ++++++++++++++++++++++++++++++++++++ src/main.go | 6 +++++- src/subtitles.go | 9 +++++++++ 5 files changed, 94 insertions(+), 6 deletions(-) create mode 100644 src/logger.go diff --git a/src/downloaders.go b/src/downloaders.go index 647aeae..7678bbc 100644 --- a/src/downloaders.go +++ b/src/downloaders.go @@ -21,11 +21,12 @@ func removeBOM(input []byte) []byte { } func downloadFile(item Item, jobInfo *JobInfo) error { - fmt.Println("Downloading:", item.Filename) + logger.LogInfo("Download File", fmt.Sprintf("Starting download for: %s", item.Filename)) tempDir := filepath.Join(config.TempBaseDir, sanitizeFilename(item.Filename)) err := os.MkdirAll(tempDir, 0755) if err != nil { + logger.LogError("Download File", fmt.Sprintf("Error creating temporary directory: %v", err)) return fmt.Errorf("error creating temporary directory: %v", err) } @@ -35,19 +36,23 @@ func downloadFile(item Item, jobInfo *JobInfo) error { if !isValidURL(item.MPD) { decodedMPD, err := base64.StdEncoding.DecodeString(item.MPD) if err != nil { + logger.LogError("Download File", fmt.Sprintf("Error decoding base64 MPD: %v", err)) return fmt.Errorf("error decoding base64 MPD: %v", err) } tempFile, err := os.CreateTemp("", "temp_mpd_*.mpd") if err != nil { + logger.LogError("Download File", fmt.Sprintf("Error creating temporary MPD file: %v", err)) return fmt.Errorf("error creating temporary MPD file: %v", err) } defer os.Remove(tempFile.Name()) if _, err := tempFile.Write(decodedMPD); err != nil { + logger.LogError("Download File", fmt.Sprintf("Error writing to temporary MPD file: %v", err)) return fmt.Errorf("error writing to temporary MPD file: %v", err) } if err := tempFile.Close(); err != nil { + logger.LogError("Download File", fmt.Sprintf("Error closing temporary MPD file: %v", err)) return fmt.Errorf("error closing temporary MPD file: %v", err) } @@ -55,30 +60,36 @@ func downloadFile(item Item, jobInfo *JobInfo) error { } else if strings.HasPrefix(item.MPD, "https://pubads.g.doubleclick.net") { resp, err := http.Get(item.MPD) if err != nil { + logger.LogError("Download File", fmt.Sprintf("Error downloading MPD: %v", err)) return fmt.Errorf("error downloading MPD: %v", err) } defer resp.Body.Close() mpdContent, err := io.ReadAll(resp.Body) if err != nil { + logger.LogError("Download File", fmt.Sprintf("Error reading MPD content: %v", err)) return fmt.Errorf("error reading MPD content: %v", err) } fixedMPDContent, err := fixGoPlay(string(mpdContent)) if err != nil { + logger.LogError("Download File", fmt.Sprintf("Error fixing MPD content: %v", err)) return fmt.Errorf("error fixing MPD content: %v", err) } tempFile, err := os.CreateTemp("", "fixed_mpd_*.mpd") if err != nil { + logger.LogError("Download File", fmt.Sprintf("Error creating temporary MPD file: %v", err)) return fmt.Errorf("error creating temporary MPD file: %v", err) } defer os.Remove(tempFile.Name()) if _, err := tempFile.WriteString(fixedMPDContent); err != nil { + logger.LogError("Download File", fmt.Sprintf("Error writing to temporary MPD file: %v", err)) return fmt.Errorf("error writing to temporary MPD file: %v", err) } if err := tempFile.Close(); err != nil { + logger.LogError("Download File", fmt.Sprintf("Error closing temporary MPD file: %v", err)) return fmt.Errorf("error closing temporary MPD file: %v", err) } @@ -90,23 +101,25 @@ func downloadFile(item Item, jobInfo *JobInfo) error { if item.Subtitles != "" { subtitlePaths, err := downloadAndConvertSubtitles(item.Subtitles) if err != nil { - fmt.Printf("Error processing subtitles: %v\n", err) + logger.LogError("Download File", fmt.Sprintf("Error processing subtitles: %v", err)) } else { for _, path := range subtitlePaths { - fmt.Println("Adding subtitle:", path) + logger.LogInfo("Download File", fmt.Sprintf("Adding subtitle: %s", path)) command += fmt.Sprintf(" --mux-import \"path=%s:lang=nl:name=Nederlands\"", path) } } } cmd := exec.Command("bash", "-c", command) + jobInfo.Cmd = cmd var outputBuffer bytes.Buffer - cmd.Stdout = io.MultiWriter(os.Stdout, &outputBuffer) + cmd.Stdout = io.MultiWriter(&outputBuffer) cmd.Stderr = os.Stderr err = cmd.Start() if err != nil { + logger.LogError("Download File", fmt.Sprintf("Error starting download command: %v", err)) return fmt.Errorf("error starting download command: %v", err) } @@ -131,17 +144,20 @@ func downloadFile(item Item, jobInfo *JobInfo) error { cmd.Process.Kill() } os.RemoveAll(tempDir) + logger.LogInfo("Download File", "Download aborted") return fmt.Errorf("download aborted") case err := <-done: if jobInfo.Paused { + logger.LogInfo("Download File", "Download paused") return fmt.Errorf("download paused") } if err != nil { + logger.LogError("Download File", fmt.Sprintf("Error executing download command: %v", err)) return fmt.Errorf("error executing download command: %v", err) } } - fmt.Println("Download completed successfully") + logger.LogInfo("Download File", "Download completed successfully") return nil } diff --git a/src/handlers.go b/src/handlers.go index ee72dae..0590199 100644 --- a/src/handlers.go +++ b/src/handlers.go @@ -50,19 +50,23 @@ func handleRoot(w http.ResponseWriter, r *http.Request) { } }{jobsInfo}) if err != nil { + logger.LogError("Handle Root", fmt.Sprintf("Error executing template: %v", err)) http.Error(w, err.Error(), http.StatusInternalServerError) } } func handleUpload(w http.ResponseWriter, r *http.Request) { + logger.LogInfo("Handle Upload", "Starting file upload") err := r.ParseMultipartForm(32 << 20) if err != nil { + logger.LogError("Handle Upload", fmt.Sprintf("Error parsing multipart form: %v", err)) http.Error(w, err.Error(), http.StatusBadRequest) return } files := r.MultipartForm.File["files"] if len(files) == 0 { + logger.LogError("Handle Upload", "No files uploaded") http.Error(w, "No files uploaded", http.StatusBadRequest) return } @@ -72,6 +76,7 @@ func handleUpload(w http.ResponseWriter, r *http.Request) { for _, fileHeader := range files { file, err := fileHeader.Open() if err != nil { + logger.LogError("Handle Upload", fmt.Sprintf("Error opening file: %v", err)) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -79,6 +84,7 @@ func handleUpload(w http.ResponseWriter, r *http.Request) { tempFile, err := os.CreateTemp(uploadDir, fileHeader.Filename) if err != nil { + logger.LogError("Handle Upload", fmt.Sprintf("Error creating temporary file: %v", err)) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -86,6 +92,7 @@ func handleUpload(w http.ResponseWriter, r *http.Request) { _, err = io.Copy(tempFile, file) if err != nil { + logger.LogError("Handle Upload", fmt.Sprintf("Error copying file: %v", err)) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -94,6 +101,7 @@ func handleUpload(w http.ResponseWriter, r *http.Request) { _, err = parseInputFile(tempFile.Name()) if err != nil { + logger.LogError("Handle Upload", fmt.Sprintf("Error parsing input file: %v", err)) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -107,10 +115,12 @@ func handleUpload(w http.ResponseWriter, r *http.Request) { } if len(validFiles) == 0 { + logger.LogError("Handle Upload", "No valid files were uploaded") http.Error(w, "No valid files were uploaded", http.StatusBadRequest) return } + logger.LogInfo("Handle Upload", fmt.Sprintf("Redirecting to select with files: %v", validFiles)) http.Redirect(w, r, "/select?files="+url.QueryEscape(strings.Join(validFiles, ",")), http.StatusSeeOther) } @@ -127,11 +137,13 @@ func handleSelect(w http.ResponseWriter, r *http.Request) { fullPath := filepath.Join(uploadDir, filename) if _, err := os.Stat(fullPath); os.IsNotExist(err) { + logger.LogError("Handle Select", fmt.Sprintf("File does not exist: %s", fullPath)) continue } items, err := parseInputFile(fullPath) if err != nil { + logger.LogError("Handle Select", fmt.Sprintf("Error parsing input file: %v", err)) continue } @@ -142,6 +154,7 @@ func handleSelect(w http.ResponseWriter, r *http.Request) { } if len(allItems) == 0 { + logger.LogError("Handle Select", "No valid files were processed") http.Error(w, "No valid files were processed", http.StatusBadRequest) return } @@ -154,18 +167,22 @@ func handleSelect(w http.ResponseWriter, r *http.Request) { AllItems: allItems, }) if err != nil { + logger.LogError("Handle Select", fmt.Sprintf("Error executing template: %v", err)) http.Error(w, err.Error(), http.StatusInternalServerError) } } func handleProcess(w http.ResponseWriter, r *http.Request) { + logger.LogInfo("Handle Process", "Starting process") if err := r.ParseForm(); err != nil { + logger.LogError("Handle Process", fmt.Sprintf("Error parsing form: %v", err)) http.Error(w, err.Error(), http.StatusBadRequest) return } selectedItems := r.Form["items"] if len(selectedItems) == 0 { + logger.LogError("Handle Process", "No items selected") http.Error(w, "No items selected", http.StatusBadRequest) return } @@ -174,6 +191,7 @@ func handleProcess(w http.ResponseWriter, r *http.Request) { for _, item := range selectedItems { parts := strings.SplitN(item, ":", 2) if len(parts) != 2 { + logger.LogError("Handle Process", "Invalid item format") continue } filename, itemName := parts[0], parts[1] @@ -181,9 +199,11 @@ func handleProcess(w http.ResponseWriter, r *http.Request) { } for filename, items := range itemsByFile { + logger.LogInfo("Handle Process", fmt.Sprintf("Processing file: %s", filename)) fullPath := filepath.Join(uploadDir, filename) allItems, err := parseInputFile(fullPath) if err != nil { + logger.LogError("Handle Process", fmt.Sprintf("Error parsing input file: %v", err)) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -226,6 +246,7 @@ func handleProgress(w http.ResponseWriter, r *http.Request) { func handlePause(w http.ResponseWriter, r *http.Request) { filename := r.URL.Query().Get("filename") if filename == "" { + logger.LogError("Pause Handler", "Filename is required") http.Error(w, "Filename is required", http.StatusBadRequest) return } @@ -235,12 +256,14 @@ func handlePause(w http.ResponseWriter, r *http.Request) { jobsMutex.Unlock() if !exists { + logger.LogError("Pause Handler", "Job not found") http.Error(w, "Job not found", http.StatusNotFound) return } jobInfo.Paused = true if jobInfo.Cmd != nil && jobInfo.Cmd.Process != nil { + logger.LogJobState(filename, "pausing") jobInfo.Cmd.Process.Kill() } diff --git a/src/logger.go b/src/logger.go new file mode 100644 index 0000000..4375a0f --- /dev/null +++ b/src/logger.go @@ -0,0 +1,36 @@ +package main + +import ( + "log" + "os" +) + +type Logger struct { + *log.Logger +} + +const ( + Reset = "\033[0m" + Red = "\033[31m" + Green = "\033[32m" + Yellow = "\033[33m" + Blue = "\033[34m" +) + +func NewLogger(prefix string) *Logger { + return &Logger{ + Logger: log.New(os.Stdout, prefix, log.Ldate|log.Ltime|log.Lshortfile), + } +} + +func (l *Logger) LogInfo(jobName, message string) { + l.Printf("%s[INFO] [%s] %s%s", Green, jobName, message, Reset) +} + +func (l *Logger) LogError(jobName, message string) { + l.Printf("%s[ERROR] [%s] %s%s", Red, jobName, message, Reset) +} + +func (l *Logger) LogJobState(jobName, state string) { + l.Printf("%s[JOB STATE] [%s] %s%s", Yellow, jobName, state, Reset) +} diff --git a/src/main.go b/src/main.go index 8f955e1..d9434f4 100644 --- a/src/main.go +++ b/src/main.go @@ -12,6 +12,8 @@ import ( "embed" ) +var logger *Logger + type Item struct { MPD string Keys string @@ -48,6 +50,8 @@ func init() { } templates = template.Must(template.ParseFS(templateFS, "templates/*")) + + logger = NewLogger("") } func main() { @@ -60,7 +64,7 @@ func main() { } else { items, err := parseInputFile(*inputFile) if err != nil { - fmt.Printf("Error parsing input file: %v\n", err) + logger.LogError("Main", fmt.Sprintf("Error parsing input file: %v", err)) return } processItems(*inputFile, items) diff --git a/src/subtitles.go b/src/subtitles.go index c30bd81..91b22b8 100644 --- a/src/subtitles.go +++ b/src/subtitles.go @@ -15,13 +15,16 @@ func downloadAndConvertSubtitles(subtitlesURLs string) ([]string, error) { urls := strings.Split(subtitlesURLs, ",") for _, url := range urls { + logger.LogInfo("Subtitle Download", fmt.Sprintf("Downloading subtitle from %s", url)) vttPath, err := downloadSubtitle(url) if err != nil { + logger.LogError("Subtitle Download", fmt.Sprintf("Error downloading subtitle: %v", err)) return nil, fmt.Errorf("error downloading subtitle: %v", err) } srtPath, err := convertVTTtoSRT(vttPath) if err != nil { + logger.LogError("Subtitle Download", fmt.Sprintf("Error converting subtitle: %v", err)) return nil, fmt.Errorf("error converting subtitle: %v", err) } @@ -32,23 +35,28 @@ func downloadAndConvertSubtitles(subtitlesURLs string) ([]string, error) { } func downloadSubtitle(url string) (string, error) { + logger.LogInfo("Download Subtitle", fmt.Sprintf("Starting download from %s", url)) resp, err := http.Get(url) if err != nil { + logger.LogError("Download Subtitle", fmt.Sprintf("Error getting subtitle URL: %v", err)) return "", err } defer resp.Body.Close() tempFile, err := os.CreateTemp("", "subtitle_*.vtt") if err != nil { + logger.LogError("Download Subtitle", fmt.Sprintf("Error creating temp file: %v", err)) return "", err } defer tempFile.Close() _, err = io.Copy(tempFile, resp.Body) if err != nil { + logger.LogError("Download Subtitle", fmt.Sprintf("Error copying to temp file: %v", err)) return "", err } + logger.LogInfo("Download Subtitle", "Subtitle downloaded successfully") return tempFile.Name(), nil } @@ -56,5 +64,6 @@ func convertVTTtoSRT(vttPath string) (string, error) { srtPath := strings.TrimSuffix(vttPath, ".vtt") + ".srt" s1, _ := astisub.OpenFile(vttPath) s1.Write(srtPath) + logger.LogInfo("Convert VTT to SRT", fmt.Sprintf("Converted %s to %s", vttPath, srtPath)) return srtPath, nil }