github.com/soulteary/pocket-bookcase@v0.0.0-20240428065142-0b5a9a0fc98a/internal/cmd/print.go (about)

     1  package cmd
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"os"
     7  
     8  	"github.com/soulteary/pocket-bookcase/internal/database"
     9  	"github.com/spf13/cobra"
    10  )
    11  
    12  func printCmd() *cobra.Command {
    13  	cmd := &cobra.Command{
    14  		Use:   "print [indices]",
    15  		Short: "Print the saved bookmarks",
    16  		Long: "Show the saved bookmarks by its database index. " +
    17  			"Accepts space-separated list of indices (e.g. 5 6 23 4 110 45), " +
    18  			"hyphenated range (e.g. 100-200) or both (e.g. 1-3 7 9). " +
    19  			"If no arguments, all records with actual index from database are shown.",
    20  		Aliases: []string{"list", "ls"},
    21  		Run:     printHandler,
    22  	}
    23  
    24  	cmd.Flags().BoolP("json", "j", false, "Output data in JSON format")
    25  	cmd.Flags().BoolP("latest", "l", false, "Sort bookmark by latest instead of ID")
    26  	cmd.Flags().BoolP("index-only", "i", false, "Only print the index of bookmarks")
    27  	cmd.Flags().StringP("search", "s", "", "Search bookmark with specified keyword")
    28  	cmd.Flags().StringSliceP("tags", "t", []string{}, "Print bookmarks with matching tag(s)")
    29  	cmd.Flags().StringSliceP("exclude-tags", "e", []string{}, "Print bookmarks without these tag(s)")
    30  
    31  	return cmd
    32  }
    33  
    34  func printHandler(cmd *cobra.Command, args []string) {
    35  	_, deps := initShiori(cmd.Context(), cmd)
    36  
    37  	// Read flags
    38  	tags, _ := cmd.Flags().GetStringSlice("tags")
    39  	keyword, _ := cmd.Flags().GetString("search")
    40  	useJSON, _ := cmd.Flags().GetBool("json")
    41  	indexOnly, _ := cmd.Flags().GetBool("index-only")
    42  	orderLatest, _ := cmd.Flags().GetBool("latest")
    43  	excludedTags, _ := cmd.Flags().GetStringSlice("exclude-tags")
    44  
    45  	// Convert args to ids
    46  	ids, err := parseStrIndices(args)
    47  	if err != nil {
    48  		cError.Printf("Failed to parse args: %v\n", err)
    49  		return
    50  	}
    51  
    52  	// Read bookmarks from database
    53  	orderMethod := database.DefaultOrder
    54  	if orderLatest {
    55  		orderMethod = database.ByLastModified
    56  	}
    57  
    58  	searchOptions := database.GetBookmarksOptions{
    59  		IDs:          ids,
    60  		Tags:         tags,
    61  		ExcludedTags: excludedTags,
    62  		Keyword:      keyword,
    63  		OrderMethod:  orderMethod,
    64  	}
    65  
    66  	bookmarks, err := deps.Database.GetBookmarks(cmd.Context(), searchOptions)
    67  	if err != nil {
    68  		cError.Printf("Failed to get bookmarks: %v\n", err)
    69  		return
    70  	}
    71  
    72  	if len(bookmarks) == 0 {
    73  		switch {
    74  		case len(ids) > 0:
    75  			cError.Println("No matching index found")
    76  		case keyword != "", len(tags) > 0:
    77  			cError.Println("No matching bookmarks found")
    78  		default:
    79  			cError.Println("No bookmarks saved yet")
    80  		}
    81  		return
    82  	}
    83  
    84  	// Print data
    85  	if useJSON {
    86  		bt, err := json.MarshalIndent(&bookmarks, "", "    ")
    87  		if err != nil {
    88  			cError.Println(err)
    89  			os.Exit(1)
    90  		}
    91  
    92  		fmt.Println(string(bt))
    93  		return
    94  	}
    95  
    96  	if indexOnly {
    97  		for _, bookmark := range bookmarks {
    98  			fmt.Printf("%d ", bookmark.ID)
    99  		}
   100  
   101  		fmt.Println()
   102  		return
   103  	}
   104  
   105  	printBookmarks(bookmarks...)
   106  }