- Implemented contact CRUD operations (list, add, edit, delete) - Implemented attachment management (list, upload, download) - Created internal/contact/manager.go for contact persistence - Created internal/attachment/manager.go for attachment storage - Added CLI commands in cmd/contacts.go and cmd/attachments.go - Integrated contact and attachment commands into root CLI Files: - internal/contact/types.go - Contact data models - internal/contact/manager.go - Contact CRUD operations - internal/attachment/manager.go - Attachment file operations - cmd/contacts.go - Contact CLI commands - cmd/attachments.go - Attachment CLI commands Contacts stored in ~/.config/pop/contacts.json Attachments stored in ~/.config/pop/attachments/
125 lines
2.7 KiB
Go
125 lines
2.7 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
|
|
"github.com/frenocorp/pop/internal/attachment"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
func attachmentCmd() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "attachment",
|
|
Short: "Manage attachments",
|
|
Long: `List, download, and upload attachments.`,
|
|
}
|
|
|
|
cmd.AddCommand(attachmentListCmd())
|
|
cmd.AddCommand(attachmentDownloadCmd())
|
|
cmd.AddCommand(attachmentUploadCmd())
|
|
|
|
return cmd
|
|
}
|
|
|
|
func attachmentListCmd() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "list",
|
|
Short: "List all attachments",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
manager := attachment.NewAttachmentManager()
|
|
|
|
ids, err := manager.List()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to list attachments: %w", err)
|
|
}
|
|
|
|
if len(ids) == 0 {
|
|
fmt.Println("No attachments found")
|
|
return nil
|
|
}
|
|
|
|
fmt.Println("Attachments:")
|
|
for _, id := range ids {
|
|
fmt.Printf(" - %s\n", id)
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
|
|
return cmd
|
|
}
|
|
|
|
func attachmentDownloadCmd() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "download <attachment-id> [output-dir]",
|
|
Short: "Download an attachment",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
if len(args) < 1 {
|
|
return fmt.Errorf("attachment ID is required")
|
|
}
|
|
|
|
id := args[0]
|
|
outputDir := "."
|
|
if len(args) > 1 {
|
|
outputDir = args[1]
|
|
}
|
|
|
|
manager := attachment.NewAttachmentManager()
|
|
|
|
data, err := manager.Get(id)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get attachment: %w", err)
|
|
}
|
|
|
|
if err := manager.Download(id, id, outputDir); err != nil {
|
|
return fmt.Errorf("failed to download attachment: %w", err)
|
|
}
|
|
|
|
fmt.Printf("Downloaded attachment %s to %s\n", id, outputDir)
|
|
fmt.Printf("Size: %d bytes\n", len(data))
|
|
return nil
|
|
},
|
|
}
|
|
|
|
return cmd
|
|
}
|
|
|
|
func attachmentUploadCmd() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "upload <attachment-id> <file-path>",
|
|
Short: "Upload an attachment",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
if len(args) < 2 {
|
|
return fmt.Errorf("attachment ID and file path are required")
|
|
}
|
|
|
|
id := args[0]
|
|
filePath := args[1]
|
|
|
|
file, err := os.Open(filePath)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to open file: %w", err)
|
|
}
|
|
defer file.Close()
|
|
|
|
manager := attachment.NewAttachmentManager()
|
|
|
|
if err := manager.Upload(id, file.Name(), file); err != nil {
|
|
return fmt.Errorf("failed to upload attachment: %w", err)
|
|
}
|
|
|
|
info, _ := file.Stat()
|
|
fmt.Printf("Uploaded attachment %s (%s, %d bytes)\n", id, file.Name(), info.Size())
|
|
return nil
|
|
},
|
|
}
|
|
|
|
return cmd
|
|
}
|
|
|
|
func readAll(r io.Reader) ([]byte, error) {
|
|
return io.ReadAll(r)
|
|
}
|