package main import ( "log/slog" "os" "git.intruders.space/public/opentimestamps" "git.intruders.space/public/opentimestamps/pdf" "github.com/spf13/cobra" ) var ( // PDF command flags pdfOutput string pdfIncludeContent bool pdfTitle string pdfComment string pdfEsploraURL string ) // pdfCmd represents the pdf command var pdfCmd = &cobra.Command{ Use: "pdf [flags] ", Short: "Generate a PDF certificate for a timestamp", Long: `Generate a PDF certificate that explains how to verify the timestamp. The PDF includes all necessary information such as hashes, operations, and instructions for manual verification.`, Args: cobra.ExactArgs(2), Run: runPdfCmd, } func init() { // Local flags for the pdf command pdfCmd.Flags().StringVarP(&pdfOutput, "output", "o", "", "Output PDF filename (default: original filename with .pdf extension)") pdfCmd.Flags().BoolVar(&pdfIncludeContent, "include-content", false, "Include the original file content in the PDF (for text files only)") pdfCmd.Flags().StringVar(&pdfTitle, "title", "OpenTimestamps Certificate", "Title for the PDF document") pdfCmd.Flags().StringVar(&pdfComment, "comment", "", "Additional comment to include in the certificate") pdfCmd.Flags().StringVar(&pdfEsploraURL, "esplora", "https://blockstream.info/api", "URL of Esplora API for fetching block information") } func runPdfCmd(cmd *cobra.Command, args []string) { filePath := args[0] otsPath := args[1] // Determine output file path outputPath := pdfOutput if outputPath == "" { outputPath = filePath + ".certificate.pdf" } // Read the original file fileData, err := os.ReadFile(filePath) if err != nil { slog.Error("Failed to read file", "file", filePath, "error", err) os.Exit(1) } // Read and parse the OTS file otsData, err := os.ReadFile(otsPath) if err != nil { slog.Error("Failed to read OTS file", "file", otsPath, "error", err) os.Exit(1) } timestampFile, err := opentimestamps.ReadFromFile(otsData) if err != nil { slog.Error("Failed to parse OTS file", "file", otsPath, "error", err) os.Exit(1) } // Set up PDF options from command line flags options := pdf.CertificateOptions{ Title: pdfTitle, Comment: pdfComment, IncludeContent: pdfIncludeContent, EsploraURL: pdfEsploraURL, } // Generate the PDF pdfBuffer, err := pdf.GenerateCertificate( filePath, fileData, timestampFile, options, ) if err != nil { slog.Error("Failed to generate PDF", "error", err) os.Exit(1) } // Write to file err = pdf.WriteToFile(pdfBuffer, outputPath) if err != nil { slog.Error("Failed to write PDF to file", "file", outputPath, "error", err) os.Exit(1) } slog.Info("PDF certificate generated successfully", "file", outputPath) }