show.go

  1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
  2//
  3// SPDX-License-Identifier: AGPL-3.0-or-later
  4
  5package note
  6
  7import (
  8	"encoding/json"
  9	"fmt"
 10
 11	"git.secluded.site/go-lunatask"
 12	"git.secluded.site/lune/internal/client"
 13	"git.secluded.site/lune/internal/config"
 14	"git.secluded.site/lune/internal/ui"
 15	"git.secluded.site/lune/internal/validate"
 16	"github.com/spf13/cobra"
 17)
 18
 19// ShowCmd displays a note by ID. Exported for potential use by shortcuts.
 20var ShowCmd = &cobra.Command{
 21	Use:   "show ID",
 22	Short: "Show note details",
 23	Long: `Show detailed information for a note.
 24
 25Accepts a UUID or lunatask:// deep link.
 26
 27Note: Due to end-to-end encryption, note name and content
 28are not available through the API. Only metadata is shown.`,
 29	Args: cobra.ExactArgs(1),
 30	RunE: runShow,
 31}
 32
 33func init() {
 34	ShowCmd.Flags().Bool("json", false, "Output as JSON")
 35}
 36
 37func runShow(cmd *cobra.Command, args []string) error {
 38	id, err := validate.Reference(args[0])
 39	if err != nil {
 40		return err
 41	}
 42
 43	apiClient, err := client.New()
 44	if err != nil {
 45		return err
 46	}
 47
 48	note, err := ui.Spin("Fetching note…", func() (*lunatask.Note, error) {
 49		return apiClient.GetNote(cmd.Context(), id)
 50	})
 51	if err != nil {
 52		return err
 53	}
 54
 55	if mustGetBoolFlag(cmd, "json") {
 56		return outputNoteJSON(cmd, note)
 57	}
 58
 59	return printNoteDetails(cmd, note)
 60}
 61
 62func outputNoteJSON(cmd *cobra.Command, note *lunatask.Note) error {
 63	enc := json.NewEncoder(cmd.OutOrStdout())
 64	enc.SetIndent("", "  ")
 65
 66	if err := enc.Encode(note); err != nil {
 67		return fmt.Errorf("encoding JSON: %w", err)
 68	}
 69
 70	return nil
 71}
 72
 73func printNoteDetails(cmd *cobra.Command, note *lunatask.Note) error {
 74	link, _ := lunatask.BuildDeepLink(lunatask.ResourceNote, note.ID)
 75
 76	fmt.Fprintf(cmd.OutOrStdout(), "%s\n", ui.H1.Render("Note"))
 77	fmt.Fprintf(cmd.OutOrStdout(), "  ID:   %s\n", note.ID)
 78	fmt.Fprintf(cmd.OutOrStdout(), "  Link: %s\n", link)
 79
 80	printNotebook(cmd, note)
 81
 82	if note.DateOn != nil {
 83		fmt.Fprintf(cmd.OutOrStdout(), "  Date: %s\n", ui.FormatDate(note.DateOn.Time))
 84	}
 85
 86	if note.Pinned {
 87		fmt.Fprintf(cmd.OutOrStdout(), "  Pinned: yes\n")
 88	}
 89
 90	if len(note.Sources) > 0 {
 91		fmt.Fprintf(cmd.OutOrStdout(), "  Sources:\n")
 92
 93		for _, src := range note.Sources {
 94			fmt.Fprintf(cmd.OutOrStdout(), "    - %s: %s\n", src.Source, src.SourceID)
 95		}
 96	}
 97
 98	fmt.Fprintf(cmd.OutOrStdout(), "  Created: %s\n", ui.FormatDate(note.CreatedAt))
 99	fmt.Fprintf(cmd.OutOrStdout(), "  Updated: %s\n", ui.FormatDate(note.UpdatedAt))
100
101	return nil
102}
103
104func printNotebook(cmd *cobra.Command, note *lunatask.Note) {
105	if note.NotebookID == nil {
106		return
107	}
108
109	notebookDisplay := *note.NotebookID
110	cfg, _ := config.Load()
111
112	if cfg != nil {
113		if notebook := cfg.NotebookByID(*note.NotebookID); notebook != nil {
114			notebookDisplay = fmt.Sprintf("%s (%s)", notebook.Name, notebook.Key)
115		}
116	}
117
118	fmt.Fprintf(cmd.OutOrStdout(), "  Notebook: %s\n", notebookDisplay)
119}