✨ Add drop:yt command and refine ytdlp.Drop functionality
This commit is contained in:
parent
ee70f2b96f
commit
b0f6628817
3 changed files with 98 additions and 16 deletions
69
cli/ytdrop.go
Normal file
69
cli/ytdrop.go
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2026 Dan Jones <danjones@goodevilgenius.org>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"my-log-wynter/ytdlp"
|
||||||
|
|
||||||
|
mycli "codeberg.org/danjones000/my-log/cli"
|
||||||
|
"codeberg.org/danjones000/my-log/config"
|
||||||
|
"codeberg.org/danjones000/my-log/formatters"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var outJson bool
|
||||||
|
|
||||||
|
// YtDropCmd represents the drop command
|
||||||
|
var YtDropCmd = &cobra.Command{
|
||||||
|
Use: "drop:yt url",
|
||||||
|
Short: "Add a new YouTube video to the watched log",
|
||||||
|
// Long: ``,
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
SilenceUsage: true,
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
if outJson {
|
||||||
|
config.Overrides["output.stdout.config.format"] = "json"
|
||||||
|
}
|
||||||
|
|
||||||
|
url := args[0]
|
||||||
|
log, err := ytdlp.Drop(cmd.Context(), url)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
form, err := formatters.Preferred()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
out, err := form.Log(log)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(out) > 0 && out[len(out)-1] != 10 {
|
||||||
|
out = append(out, 10)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(cmd.OutOrStdout(), "%s", out)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
mycli.RootCmd.AddCommand(YtDropCmd)
|
||||||
|
YtDropCmd.Flags().BoolVarP(&outJson, "output_json", "o", false, "Output result as JSON")
|
||||||
|
}
|
||||||
|
|
@ -16,8 +16,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "codeberg.org/danjones000/my-log/cli"
|
import (
|
||||||
|
_ "my-log-wynter/cli"
|
||||||
|
|
||||||
|
mylog "codeberg.org/danjones000/my-log/cli"
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cli.Execute()
|
mylog.Execute()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,23 +12,25 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Drop adds the URL specified by the url to the watched log.
|
// Drop adds the URL specified by the url to the watched log.
|
||||||
func Drop(ctx context.Context, url string) (models.Entry, error) {
|
func Drop(ctx context.Context, url string) (models.Log, error) {
|
||||||
var ent models.Entry
|
var ent models.Entry
|
||||||
|
var log models.Log
|
||||||
if ctx.Err() != nil {
|
if ctx.Err() != nil {
|
||||||
return ent, context.Cause(ctx)
|
return log, context.Cause(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
info, err := Fetch(ctx, url)
|
info, err := Fetch(ctx, url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ent, err
|
return log, err
|
||||||
}
|
}
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
ent.Date = now
|
||||||
|
|
||||||
metas := &ent.Fields
|
metas := &ent.Fields
|
||||||
metas.Set("id", getID(now, info))
|
*metas = metas.Set("id", getID(now, info))
|
||||||
|
|
||||||
source := FirstNonZero(info.ExtractorKey, info.WebpageURLDomain, new("Web Video"))
|
source := FirstNonZero(info.ExtractorKey, info.WebpageURLDomain, new("Web Video"))
|
||||||
metas.Set("source", source)
|
*metas = metas.Set("source", source)
|
||||||
|
|
||||||
ent.Title = FirstNonZero(info.Title, info.AltTitle, new(fmt.Sprintf("%s %s", source, info.ID)))
|
ent.Title = FirstNonZero(info.Title, info.AltTitle, new(fmt.Sprintf("%s %s", source, info.ID)))
|
||||||
|
|
||||||
|
|
@ -39,12 +41,12 @@ func Drop(ctx context.Context, url string) (models.Entry, error) {
|
||||||
|
|
||||||
// TODO Add show info
|
// TODO Add show info
|
||||||
|
|
||||||
log := models.Log{Name: "watched", Entries: []models.Entry{ent}}
|
log = models.Log{Name: "watched", Entries: []models.Entry{ent}}
|
||||||
if err := files.Append(log); err != nil {
|
if err := files.Append(log); err != nil {
|
||||||
return ent, err
|
return log, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return ent, nil
|
return log, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getID(now time.Time, info *ytd.ExtractedInfo) string {
|
func getID(now time.Time, info *ytd.ExtractedInfo) string {
|
||||||
|
|
@ -63,34 +65,41 @@ func getID(now time.Time, info *ytd.ExtractedInfo) string {
|
||||||
func setNote(metas *models.Metas, info *ytd.ExtractedInfo) {
|
func setNote(metas *models.Metas, info *ytd.ExtractedInfo) {
|
||||||
desc := FirstNonZero(info.Description)
|
desc := FirstNonZero(info.Description)
|
||||||
if desc != "" {
|
if desc != "" {
|
||||||
metas.Set("note", desc)
|
desc = strings.SplitN(desc, "\n", 2)[0]
|
||||||
|
*metas = metas.Set("note", desc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setArtist(metas *models.Metas, info *ytd.ExtractedInfo) {
|
func setArtist(metas *models.Metas, info *ytd.ExtractedInfo) {
|
||||||
art := FirstNonZero(info.Artist, info.AlbumArtist, info.Uploader)
|
art := FirstNonZero(info.Artist, info.AlbumArtist, info.Uploader)
|
||||||
if art != "" {
|
if art != "" {
|
||||||
metas.Set("artist", art)
|
*metas = metas.Set("artist", art)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setTags(metas *models.Metas, info *ytd.ExtractedInfo) {
|
func setTags(metas *models.Metas, info *ytd.ExtractedInfo) {
|
||||||
tags := append(info.Tags, info.Categories...)
|
tags := make([]any, 0, len(info.Tags)+len(info.Categories))
|
||||||
|
for _, t := range info.Tags {
|
||||||
|
tags = append(tags, t)
|
||||||
|
}
|
||||||
|
for _, c := range info.Categories {
|
||||||
|
tags = append(tags, c)
|
||||||
|
}
|
||||||
if len(tags) > 0 {
|
if len(tags) > 0 {
|
||||||
metas.Set("tags", tags)
|
*metas = metas.Set("tags", tags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setDuration(metas *models.Metas, info *ytd.ExtractedInfo) {
|
func setDuration(metas *models.Metas, info *ytd.ExtractedInfo) {
|
||||||
dur := FirstNonZero(info.Duration)
|
dur := FirstNonZero(info.Duration)
|
||||||
if dur > 0 {
|
if dur > 0 {
|
||||||
metas.Set("duration", dur)
|
*metas = metas.Set("duration", dur)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setUrl(metas *models.Metas, info *ytd.ExtractedInfo, origUrl string) {
|
func setUrl(metas *models.Metas, info *ytd.ExtractedInfo, origUrl string) {
|
||||||
url := FirstNonZero(info.WebpageURL, info.PageURL, info.URL, &origUrl)
|
url := FirstNonZero(info.WebpageURL, info.PageURL, info.URL, &origUrl)
|
||||||
metas.Set("url", url)
|
*metas = metas.Set("url", url)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FirstNonZero[T comparable](vals ...*T) T {
|
func FirstNonZero[T comparable](vals ...*T) T {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue