package main import ( "context" "fmt" "log" "net/http" "os" "os/signal" "syscall" "time" "app_compartir/internal/auth" "app_compartir/internal/cleaner" "app_compartir/internal/config" "app_compartir/internal/db" "app_compartir/internal/handlers" ) func main() { cfg := config.Load() log.Println("==================================================") log.Printf("🚀 Iniciando app_compartir en puerto %s", cfg.Port) log.Printf("🌐 URL Base: %s", cfg.BaseURL) log.Printf("📂 Almacenamiento: %s (Uploads: %s)", cfg.DataDir, cfg.UploadDir) log.Printf("🛡️ Auth WebControl: %s", cfg.WebControlURL) if cfg.GoogleClientID != "" { log.Println("🔑 Google OAuth: Habilitado") } else { log.Println("🔑 Google OAuth: Deshabilitado (variables no configuradas)") } log.Println("⏰ Política de retención: Solo Guest expira en 24h. Cuentas registradas = permanente.") log.Println("==================================================") // Inicializar Base de Datos SQLite database, err := db.Init(cfg.DBPath, cfg.UploadDir) if err != nil { log.Fatalf("Error fatal iniciando base de datos: %v", err) } defer database.Close() // Iniciar servicio de purga automática cada 10 minutos para archivos guest vencidos cleanerSvc := cleaner.New(database, cfg.UploadDir, 10*time.Minute) cleanerSvc.Start() defer cleanerSvc.Stop() // Servicio de Autenticación authSvc := auth.New(cfg, database) // Handlers HTTP h, err := handlers.New(cfg, database, authSvc) if err != nil { log.Fatalf("Error fatal configurando handlers: %v", err) } mux := http.NewServeMux() // Rutas Web mux.HandleFunc("GET /", h.Index) mux.HandleFunc("GET /v/{id}", h.View) mux.HandleFunc("GET /d/{id}", h.Download) mux.HandleFunc("GET /raw/{id}", h.Raw) mux.HandleFunc("GET /qr/{id}", h.QR) // Subida y compartir mux.HandleFunc("POST /api/upload", h.Upload) mux.HandleFunc("POST /api/share-text", h.ShareText) mux.HandleFunc("DELETE /api/shares/{id}", h.DeleteShare) // Autenticación mux.HandleFunc("GET /login", h.LoginView) mux.HandleFunc("POST /login/webcontrol", h.WebControlLogin) mux.HandleFunc("GET /auth/google", h.GoogleLogin) mux.HandleFunc("GET /auth/google/callback", h.GoogleCallback) mux.HandleFunc("GET /logout", h.Logout) // Panel de usuario mux.HandleFunc("GET /mis-archivos", h.MyShares) server := &http.Server{ Addr: ":" + cfg.Port, Handler: mux, ReadTimeout: 120 * time.Second, WriteTimeout: 120 * time.Second, IdleTimeout: 120 * time.Second, } // Manejo de apagado graceful stop := make(chan os.Signal, 1) signal.Notify(stop, os.Interrupt, syscall.SIGTERM) go func() { if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("Error en el servidor HTTP: %v", err) } }() fmt.Printf("\n⚡ Servidor escuchando en http://localhost:%s\n\n", cfg.Port) <-stop log.Println("\n🛑 Apagando servidor con gracia...") ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := server.Shutdown(ctx); err != nil { log.Printf("Error apagando servidor: %v", err) } log.Println("👋 Servidor apagado correctamente.") }