shiori/internal/cmd/utils.go

172 lines
3.7 KiB
Go
Raw Normal View History

2019-05-22 00:24:11 +08:00
package cmd
import (
"errors"
"fmt"
nurl "net/url"
"os"
2019-05-22 17:47:20 +08:00
"os/exec"
"path"
2019-05-22 17:47:20 +08:00
"runtime"
2019-05-22 00:24:11 +08:00
"strconv"
"strings"
2019-08-10 09:13:13 +08:00
"unicode/utf8"
2019-05-22 00:24:11 +08:00
"github.com/fatih/color"
"github.com/go-shiori/shiori/internal/model"
2022-02-13 23:38:27 +08:00
"golang.org/x/term"
2019-05-22 00:24:11 +08:00
)
var (
2022-02-13 23:38:27 +08:00
cIndex = color.New(color.FgHiCyan)
cSymbol = color.New(color.FgHiMagenta)
cTitle = color.New(color.FgHiGreen).Add(color.Bold)
cURL = color.New(color.FgHiYellow)
cExcerpt = color.New(color.FgHiWhite)
cTag = color.New(color.FgHiBlue)
cInfo = color.New(color.FgHiCyan)
cError = color.New(color.FgHiRed)
2019-05-22 17:13:52 +08:00
errInvalidIndex = errors.New("index is not valid")
2019-05-22 00:24:11 +08:00
)
func normalizeSpace(str string) string {
2019-05-23 10:22:47 +08:00
str = strings.TrimSpace(str)
2019-05-22 00:24:11 +08:00
return strings.Join(strings.Fields(str), " ")
}
func isURLValid(s string) bool {
tmp, err := nurl.Parse(s)
return err == nil && tmp.Scheme != "" && tmp.Hostname() != ""
}
func printBookmarks(bookmarks ...model.Bookmark) {
for _, bookmark := range bookmarks {
// Create bookmark index
strBookmarkIndex := fmt.Sprintf("%d. ", bookmark.ID)
strSpace := strings.Repeat(" ", len(strBookmarkIndex))
// Print bookmark title
cIndex.Print(strBookmarkIndex)
cTitle.Println(bookmark.Title)
// Print bookmark URL
cSymbol.Print(strSpace + "> ")
cURL.Println(bookmark.URL)
// Print bookmark excerpt
if bookmark.Excerpt != "" {
cSymbol.Print(strSpace + "+ ")
cExcerpt.Println(bookmark.Excerpt)
}
// Print bookmark tags
if len(bookmark.Tags) > 0 {
cSymbol.Print(strSpace + "# ")
for i, tag := range bookmark.Tags {
if i == len(bookmark.Tags)-1 {
cTag.Println(tag.Name)
} else {
cTag.Print(tag.Name + ", ")
}
}
}
// Append new line
fmt.Println()
}
}
// parseStrIndices converts a list of indices to their integer values
func parseStrIndices(indices []string) ([]int, error) {
var listIndex []int
for _, strIndex := range indices {
if !strings.Contains(strIndex, "-") {
index, err := strconv.Atoi(strIndex)
if err != nil || index < 1 {
return nil, errInvalidIndex
}
listIndex = append(listIndex, index)
continue
}
parts := strings.Split(strIndex, "-")
if len(parts) != 2 {
return nil, errInvalidIndex
}
minIndex, errMin := strconv.Atoi(parts[0])
maxIndex, errMax := strconv.Atoi(parts[1])
if errMin != nil || errMax != nil || minIndex < 1 || minIndex > maxIndex {
return nil, errInvalidIndex
}
for i := minIndex; i <= maxIndex; i++ {
listIndex = append(listIndex, i)
}
}
return listIndex, nil
}
2019-05-22 17:47:20 +08:00
// openBrowser tries to open the URL in a browser,
// and returns any error if it happened.
func openBrowser(url string) error {
var args []string
switch runtime.GOOS {
case "darwin":
args = []string{"open"}
case "windows":
args = []string{"cmd", "/c", "start"}
default:
args = []string{"xdg-open"}
}
cmd := exec.Command(args[0], append(args[1:], url)...)
return cmd.Run()
}
func getTerminalWidth() int {
2022-02-13 23:38:27 +08:00
width, _, _ := term.GetSize(int(os.Stdin.Fd()))
2019-05-22 17:47:20 +08:00
return width
}
2019-08-10 09:13:13 +08:00
func validateTitle(title, fallback string) string {
// Normalize spaces before we begin
title = normalizeSpace(title)
title = strings.TrimSpace(title)
// If at this point title already empty, just uses fallback
if title == "" {
return fallback
}
// Check if it's already valid UTF-8 string
if valid := utf8.ValidString(title); valid {
return title
2019-08-10 09:13:13 +08:00
}
// Remove invalid runes to get the valid UTF-8 title
2019-08-10 09:13:13 +08:00
fixUtf := func(r rune) rune {
if r == utf8.RuneError {
return -1
}
return r
}
validUtf := strings.Map(fixUtf, title)
2019-08-10 09:13:13 +08:00
// If it's empty use fallback string
validUtf = strings.TrimSpace(validUtf)
if validUtf == "" {
return fallback
}
return validUtf
}
func SFCallerPrettyfier(frame *runtime.Frame) (string, string) {
return "", fmt.Sprintf("%s:%d", path.Base(frame.File), frame.Line)
}