2019-05-21 11:31:40 +08:00
|
|
|
package cmd
|
|
|
|
|
|
|
|
import (
|
2019-05-22 00:24:11 +08:00
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
|
2019-09-20 17:48:57 +08:00
|
|
|
"github.com/go-shiori/shiori/internal/core"
|
2019-05-22 00:24:11 +08:00
|
|
|
"github.com/go-shiori/shiori/internal/model"
|
2019-05-21 11:31:40 +08:00
|
|
|
"github.com/spf13/cobra"
|
|
|
|
)
|
|
|
|
|
|
|
|
func addCmd() *cobra.Command {
|
|
|
|
cmd := &cobra.Command{
|
|
|
|
Use: "add url",
|
|
|
|
Short: "Bookmark the specified URL",
|
|
|
|
Args: cobra.ExactArgs(1),
|
2019-05-22 00:24:11 +08:00
|
|
|
Run: addHandler,
|
2019-05-21 11:31:40 +08:00
|
|
|
}
|
|
|
|
|
2019-06-09 18:02:16 +08:00
|
|
|
cmd.Flags().StringP("title", "i", "", "Custom title for this bookmark")
|
|
|
|
cmd.Flags().StringP("excerpt", "e", "", "Custom excerpt for this bookmark")
|
|
|
|
cmd.Flags().StringSliceP("tags", "t", []string{}, "Comma-separated tags for this bookmark")
|
|
|
|
cmd.Flags().BoolP("offline", "o", false, "Save bookmark without fetching data from internet")
|
2019-06-10 16:49:54 +08:00
|
|
|
cmd.Flags().BoolP("no-archival", "a", false, "Save bookmark without creating offline archive")
|
2019-06-10 01:20:24 +08:00
|
|
|
cmd.Flags().Bool("log-archival", false, "Log the archival process")
|
2019-05-21 11:31:40 +08:00
|
|
|
|
|
|
|
return cmd
|
|
|
|
}
|
2019-05-22 00:24:11 +08:00
|
|
|
|
|
|
|
func addHandler(cmd *cobra.Command, args []string) {
|
|
|
|
// Read flag and arguments
|
|
|
|
url := args[0]
|
|
|
|
title, _ := cmd.Flags().GetString("title")
|
|
|
|
excerpt, _ := cmd.Flags().GetString("excerpt")
|
|
|
|
tags, _ := cmd.Flags().GetStringSlice("tags")
|
|
|
|
offline, _ := cmd.Flags().GetBool("offline")
|
2019-06-10 16:49:54 +08:00
|
|
|
noArchival, _ := cmd.Flags().GetBool("no-archival")
|
2019-06-10 01:20:24 +08:00
|
|
|
logArchival, _ := cmd.Flags().GetBool("log-archival")
|
2019-05-22 00:24:11 +08:00
|
|
|
|
2019-09-22 17:17:51 +08:00
|
|
|
// Normalize input
|
2019-09-23 00:36:36 +08:00
|
|
|
title = validateTitle(title, "")
|
2019-09-22 17:17:51 +08:00
|
|
|
excerpt = normalizeSpace(excerpt)
|
|
|
|
|
2019-09-20 17:48:57 +08:00
|
|
|
// Create bookmark item
|
|
|
|
book := model.Bookmark{
|
|
|
|
URL: url,
|
2019-09-22 17:17:51 +08:00
|
|
|
Title: title,
|
|
|
|
Excerpt: excerpt,
|
2019-09-20 17:48:57 +08:00
|
|
|
CreateArchive: !noArchival,
|
2019-05-22 00:24:11 +08:00
|
|
|
}
|
|
|
|
|
2019-09-20 17:48:57 +08:00
|
|
|
// Set bookmark tags
|
|
|
|
book.Tags = make([]model.Tag, len(tags))
|
|
|
|
for i, tag := range tags {
|
|
|
|
book.Tags[i].Name = strings.TrimSpace(tag)
|
2019-05-22 00:24:11 +08:00
|
|
|
}
|
|
|
|
|
2019-05-22 17:13:52 +08:00
|
|
|
// Create bookmark ID
|
2019-09-20 17:48:57 +08:00
|
|
|
var err error
|
2019-08-09 11:19:43 +08:00
|
|
|
book.ID, err = db.CreateNewID("bookmark")
|
2019-05-22 17:13:52 +08:00
|
|
|
if err != nil {
|
|
|
|
cError.Printf("Failed to create ID: %v\n", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-09-20 17:48:57 +08:00
|
|
|
// Clean up bookmark URL
|
|
|
|
book.URL, err = core.RemoveUTMParams(book.URL)
|
|
|
|
if err != nil {
|
|
|
|
cError.Printf("Failed to clean URL: %v\n", err)
|
|
|
|
return
|
2019-05-22 00:24:11 +08:00
|
|
|
}
|
|
|
|
|
2019-09-20 17:48:57 +08:00
|
|
|
// If it's not offline mode, fetch data from internet.
|
2019-05-22 00:24:11 +08:00
|
|
|
if !offline {
|
2019-09-20 17:48:57 +08:00
|
|
|
cInfo.Println("Downloading article...")
|
2019-05-23 20:33:00 +08:00
|
|
|
|
2019-09-20 17:48:57 +08:00
|
|
|
var isFatalErr bool
|
|
|
|
content, contentType, err := core.DownloadBookmark(book.URL)
|
|
|
|
if err != nil {
|
|
|
|
cError.Printf("Failed to download: %v\n", err)
|
|
|
|
}
|
2019-06-09 15:54:07 +08:00
|
|
|
|
2019-09-20 17:48:57 +08:00
|
|
|
if err == nil && content != nil {
|
|
|
|
request := core.ProcessRequest{
|
|
|
|
DataDir: dataDir,
|
|
|
|
Bookmark: book,
|
|
|
|
Content: content,
|
|
|
|
ContentType: contentType,
|
|
|
|
LogArchival: logArchival,
|
2019-09-22 17:17:51 +08:00
|
|
|
KeepTitle: title != "",
|
|
|
|
KeepExcerpt: excerpt != "",
|
2019-05-23 20:33:00 +08:00
|
|
|
}
|
|
|
|
|
2019-09-20 17:48:57 +08:00
|
|
|
book, isFatalErr, err = core.ProcessBookmark(request)
|
|
|
|
content.Close()
|
2019-06-10 16:49:54 +08:00
|
|
|
|
2019-06-10 21:15:09 +08:00
|
|
|
if err != nil {
|
2019-09-20 17:48:57 +08:00
|
|
|
cError.Printf("Failed: %v\n", err)
|
2019-05-23 20:33:00 +08:00
|
|
|
}
|
|
|
|
|
2019-09-20 17:48:57 +08:00
|
|
|
if isFatalErr {
|
|
|
|
return
|
2019-05-24 14:25:29 +08:00
|
|
|
}
|
2019-09-20 17:48:57 +08:00
|
|
|
}
|
2019-05-22 00:24:11 +08:00
|
|
|
}
|
|
|
|
|
2019-10-03 21:23:28 +08:00
|
|
|
// Make sure bookmark's title not empty
|
|
|
|
if book.Title == "" {
|
|
|
|
book.Title = book.URL
|
|
|
|
}
|
|
|
|
|
2019-05-22 00:24:11 +08:00
|
|
|
// Save bookmark to database
|
2019-08-09 11:19:43 +08:00
|
|
|
_, err = db.SaveBookmarks(book)
|
2019-05-22 00:24:11 +08:00
|
|
|
if err != nil {
|
2019-05-22 17:13:52 +08:00
|
|
|
cError.Printf("Failed to save bookmark: %v\n", err)
|
2019-05-22 00:24:11 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-05-22 17:13:52 +08:00
|
|
|
// Print added bookmark
|
|
|
|
fmt.Println()
|
2019-05-22 00:24:11 +08:00
|
|
|
printBookmarks(book)
|
|
|
|
}
|