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