refac
This commit is contained in:
parent
f208f0f92f
commit
5dd659818e
13
Makefile
13
Makefile
@ -1,20 +1,21 @@
|
||||
build: wallhaven_dl
|
||||
|
||||
wallhaven_dl: $(shell find . -name '*.go')
|
||||
go build -o wallhaven_dl .
|
||||
go build -o dist/ .
|
||||
|
||||
run:
|
||||
go run main.go
|
||||
run: build
|
||||
./dist/wallhaven_dl
|
||||
|
||||
tidy:
|
||||
go mod tidy
|
||||
|
||||
clean:
|
||||
rm -f wallhaven_dl
|
||||
rm -rf dist
|
||||
|
||||
uninstall:
|
||||
rm -f /usr/bin/wallhaven_dl
|
||||
rm -f /usr/share/zsh/site-functions/_wallhaven_dl
|
||||
|
||||
install:
|
||||
cp wallhaven_dl /usr/bin
|
||||
./wallhaven_dl completion zsh > /usr/share/zsh/site-functions/_wallhaven_dl
|
||||
cp ./dist/wallhaven_dl /usr/bin
|
||||
cp ./completions/_wallhaven_dl /usr/share/zsh/site-functions/_wallhaven_dl
|
||||
|
21
cmd/root.go
21
cmd/root.go
@ -1,21 +0,0 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "wallhaven_dl",
|
||||
Short: "A wallpaper downloader and setter",
|
||||
}
|
||||
|
||||
// Execute executes the root command.
|
||||
func Execute() {
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
170
cmd/search.go
170
cmd/search.go
@ -1,170 +0,0 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"git.asdf.cafe/abs3nt/wallhaven_dl/src/wallhaven"
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(searchCmd)
|
||||
searchCmd.PersistentFlags().StringVarP(
|
||||
&searchRange,
|
||||
"range",
|
||||
"r",
|
||||
"1y",
|
||||
"range for search.",
|
||||
)
|
||||
searchCmd.PersistentFlags().StringVarP(
|
||||
&searchPurity,
|
||||
"purity",
|
||||
"p",
|
||||
"110",
|
||||
"purity for the search.",
|
||||
)
|
||||
searchCmd.PersistentFlags().StringVarP(
|
||||
&searchCategories,
|
||||
"categories",
|
||||
"c",
|
||||
"010",
|
||||
"categories for the search.",
|
||||
)
|
||||
searchCmd.PersistentFlags().StringVarP(
|
||||
&searchSorting,
|
||||
"sort",
|
||||
"s",
|
||||
"toplist",
|
||||
"sort by for results, valid sorts: date_added, relevance, random, views, favorites, searchlist.",
|
||||
)
|
||||
searchCmd.PersistentFlags().StringVarP(
|
||||
&searchOrder,
|
||||
"order",
|
||||
"o",
|
||||
"desc",
|
||||
"sort order for results, valid sorts: asc desc.",
|
||||
)
|
||||
searchCmd.PersistentFlags().IntVarP(
|
||||
&searchPage,
|
||||
"maxPage",
|
||||
"m",
|
||||
5,
|
||||
"number of pages to randomly choose wallpaper from.",
|
||||
)
|
||||
searchCmd.PersistentFlags().StringSliceVar(
|
||||
&searchRatios,
|
||||
"ratios",
|
||||
[]string{"16x9", "16x10"},
|
||||
"ratios to search for.",
|
||||
)
|
||||
searchCmd.PersistentFlags().StringVar(
|
||||
&searchAtLeast,
|
||||
"at-least",
|
||||
"2560x1440",
|
||||
"minimum resolution for results.",
|
||||
)
|
||||
searchCmd.PersistentFlags().StringVarP(
|
||||
&searchScript,
|
||||
"script",
|
||||
"t",
|
||||
"",
|
||||
"script to run after downloading the wallpaper",
|
||||
)
|
||||
searchCmd.PersistentFlags().StringVarP(
|
||||
&downloadPath,
|
||||
"download-path",
|
||||
"d",
|
||||
"",
|
||||
"directory to download the image too",
|
||||
)
|
||||
}
|
||||
|
||||
var (
|
||||
searchRange string
|
||||
searchPurity string
|
||||
searchCategories string
|
||||
searchSorting string
|
||||
searchOrder string
|
||||
searchAtLeast string
|
||||
searchScript string
|
||||
downloadPath string
|
||||
searchRatios []string
|
||||
searchPage int
|
||||
searchCmd = &cobra.Command{
|
||||
Use: "search",
|
||||
Aliases: []string{"s"},
|
||||
Args: cobra.RangeArgs(0, 1),
|
||||
Short: "Wallhaven downloader with the option to run a script after the image has been downloaded",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return search(args)
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func search(args []string) error {
|
||||
seed := rand.NewSource(time.Now().UnixNano())
|
||||
r := rand.New(seed)
|
||||
s := &wallhaven.Search{
|
||||
Categories: searchCategories,
|
||||
Purities: searchPurity,
|
||||
Sorting: searchSorting,
|
||||
Order: searchOrder,
|
||||
TopRange: searchRange,
|
||||
AtLeast: searchAtLeast,
|
||||
Ratios: searchRatios,
|
||||
Page: r.Intn(searchPage) + 1,
|
||||
}
|
||||
if len(args) > 0 {
|
||||
s.Query = wallhaven.Q{
|
||||
Tags: []string{args[0]},
|
||||
}
|
||||
}
|
||||
results, err := wallhaven.SearchWallpapers(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resultPath, err := getOrDownload(results, r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if searchScript != "" {
|
||||
err = runScript(resultPath, searchScript)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getOrDownload(results *wallhaven.SearchResults, r *rand.Rand) (string, error) {
|
||||
if len(results.Data) == 0 {
|
||||
return "", fmt.Errorf("no wallpapers found")
|
||||
}
|
||||
homedir, _ := os.UserHomeDir()
|
||||
if downloadPath == "" {
|
||||
downloadPath = path.Join(homedir, "Pictures/Wallpapers")
|
||||
}
|
||||
result := results.Data[r.Intn(len(results.Data))]
|
||||
fullPath := path.Join(downloadPath, path.Base(result.Path))
|
||||
if _, err := os.Stat(fullPath); err != nil {
|
||||
err = result.Download(path.Join(downloadPath))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
return fullPath, nil
|
||||
}
|
||||
|
||||
func runScript(imgPath, script string) error {
|
||||
_, err := exec.Command(script, imgPath).Output()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
20
completions/_wallhaven_dl
Normal file
20
completions/_wallhaven_dl
Normal file
@ -0,0 +1,20 @@
|
||||
#compdef wallhaven_dl
|
||||
|
||||
_cli_zsh_autocomplete() {
|
||||
local -a opts
|
||||
local cur
|
||||
cur=${words[-1]}
|
||||
if [[ "$cur" == "-"* ]]; then
|
||||
opts=("${(@f)$(${words[@]:0:#words[@]-1} ${cur} --generate-shell-completion)}")
|
||||
else
|
||||
opts=("${(@f)$(${words[@]:0:#words[@]-1} --generate-shell-completion)}")
|
||||
fi
|
||||
|
||||
if [[ "${opts[1]}" != "" ]]; then
|
||||
_describe 'values' opts
|
||||
else
|
||||
_files
|
||||
fi
|
||||
}
|
||||
|
||||
compdef _cli_zsh_autocomplete wallhaven_dl
|
8
go.mod
8
go.mod
@ -1,10 +1,14 @@
|
||||
module git.asdf.cafe/abs3nt/wallhaven_dl
|
||||
|
||||
go 1.21.3
|
||||
go 1.22.0
|
||||
|
||||
require github.com/spf13/cobra v1.7.0
|
||||
require (
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/urfave/cli/v3 v3.0.0-alpha9
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
)
|
||||
|
11
go.sum
11
go.sum
@ -1,10 +1,21 @@
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/urfave/cli/v3 v3.0.0-alpha9 h1:P0RMy5fQm1AslQS+XCmy9UknDXctOmG/q/FZkUFnJSo=
|
||||
github.com/urfave/cli/v3 v3.0.0-alpha9/go.mod h1:0kK/RUFHyh+yIKSfWxwheGndfnrvYSmYFVeKCh03ZUc=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
204
main.go
204
main.go
@ -1,7 +1,207 @@
|
||||
package main
|
||||
|
||||
import "git.asdf.cafe/abs3nt/wallhaven_dl/cmd"
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"git.asdf.cafe/abs3nt/wallhaven_dl/src/wallhaven"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cmd.Execute()
|
||||
app := cli.Command{
|
||||
EnableShellCompletion: true,
|
||||
Name: "wallhaven_dl",
|
||||
Usage: "Download wallpapers from wallhaven.cc",
|
||||
Action: func(ctx context.Context, c *cli.Command) error {
|
||||
fmt.Println("cli")
|
||||
return nil
|
||||
},
|
||||
Commands: []*cli.Command{
|
||||
{
|
||||
Name: "search",
|
||||
Usage: "Search for wallpapers",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "range",
|
||||
Aliases: []string{"r"},
|
||||
Value: "1y",
|
||||
Validator: func(s string) error {
|
||||
if s != "1d" && s != "3d" && s != "1w" && s != "1M" && s != "3M" && s != "6M" && s != "1y" {
|
||||
return fmt.Errorf("range must be '1d', '3d', '1w', '1M', '3M', '6M' or '1y'")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Usage: "Time range for top sorting",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "purity",
|
||||
Aliases: []string{"p"},
|
||||
Value: "110",
|
||||
Validator: func(s string) error {
|
||||
if len(s) != 3 {
|
||||
return fmt.Errorf("purity must be 3 characters long")
|
||||
}
|
||||
for _, c := range s {
|
||||
if c != '0' && c != '1' {
|
||||
return fmt.Errorf("purity must be 0 or 1")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Usage: "Purity of the wallpapers",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "categories",
|
||||
Aliases: []string{"c"},
|
||||
Value: "010",
|
||||
Validator: func(s string) error {
|
||||
if len(s) != 3 {
|
||||
return fmt.Errorf("categories must be 3 characters long")
|
||||
}
|
||||
for _, c := range s {
|
||||
if c != '0' && c != '1' {
|
||||
return fmt.Errorf("categories must be 0 or 1")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Usage: "Categories of the wallpapers",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "sort",
|
||||
Aliases: []string{"s"},
|
||||
Value: "toplist",
|
||||
Validator: func(s string) error {
|
||||
if s != "relevance" && s != "random" && s != "date_added" && s != "views" && s != "favorites" &&
|
||||
s != "toplist" {
|
||||
return fmt.Errorf(
|
||||
"sort must be 'relevance', 'random', 'date_added', 'views', 'favorites' or 'toplist'",
|
||||
)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Usage: "Sorting of the wallpapers",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "order",
|
||||
Aliases: []string{"o"},
|
||||
Value: "desc",
|
||||
Validator: func(s string) error {
|
||||
if s != "asc" && s != "desc" {
|
||||
return fmt.Errorf("order must be 'asc' or 'desc'")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Usage: "Order of the wallpapers",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "page",
|
||||
Aliases: []string{"pg"},
|
||||
Value: 5,
|
||||
Usage: "Pages to search",
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "ratios",
|
||||
Aliases: []string{"rt"},
|
||||
Value: []string{"16x9", "16x10"},
|
||||
Usage: "Ratios of the wallpapers",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "atLeast",
|
||||
Aliases: []string{"al"},
|
||||
Value: "2560x1440",
|
||||
Usage: "Minimum resolution",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "scriptPath",
|
||||
Aliases: []string{"sp"},
|
||||
Value: "",
|
||||
TakesFile: true,
|
||||
Usage: "Path to the script to run after downloading",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "downloadPath",
|
||||
Aliases: []string{"dp"},
|
||||
Value: os.Getenv("HOME") + "/Pictures/Wallpapers",
|
||||
TakesFile: true,
|
||||
Usage: "Path to download the wallpapers",
|
||||
},
|
||||
},
|
||||
Action: func(ctx context.Context, c *cli.Command) error {
|
||||
return search(c)
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := app.Run(context.Background(), os.Args); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func search(c *cli.Command) error {
|
||||
seed := rand.NewSource(time.Now().UnixNano())
|
||||
r := rand.New(seed)
|
||||
s := &wallhaven.Search{
|
||||
Categories: c.String("categories"),
|
||||
Purities: c.String("purity"),
|
||||
Sorting: c.String("sort"),
|
||||
Order: c.String("order"),
|
||||
TopRange: c.String("range"),
|
||||
AtLeast: c.String("atLeast"),
|
||||
Ratios: c.StringSlice("ratios"),
|
||||
Page: c.Int("page"),
|
||||
}
|
||||
query := c.Args().First()
|
||||
if query != "" {
|
||||
s.Query = wallhaven.Q{
|
||||
Tags: []string{query},
|
||||
}
|
||||
}
|
||||
results, err := wallhaven.SearchWallpapers(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resultPath, err := getOrDownload(results, r, c.String("downloadPath"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
searchScript := c.String("scriptPath")
|
||||
if searchScript != "" {
|
||||
err = runScript(resultPath, searchScript)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getOrDownload(results *wallhaven.SearchResults, r *rand.Rand, downloadPath string) (string, error) {
|
||||
if len(results.Data) == 0 {
|
||||
return "", fmt.Errorf("no wallpapers found")
|
||||
}
|
||||
result := results.Data[r.Intn(len(results.Data))]
|
||||
fullPath := path.Join(downloadPath, path.Base(result.Path))
|
||||
if _, err := os.Stat(fullPath); err != nil {
|
||||
err = result.Download(path.Join(downloadPath))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
return fullPath, nil
|
||||
}
|
||||
|
||||
func runScript(imgPath, script string) error {
|
||||
_, err := exec.Command(script, imgPath).Output()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ type Search struct {
|
||||
Resolutions []string
|
||||
Ratios []string
|
||||
Colors []string // Colors is an array of hex colors represented as strings in #RRGGBB format
|
||||
Page int
|
||||
Page int64
|
||||
}
|
||||
|
||||
func (s Search) toQuery() url.Values {
|
||||
@ -96,7 +96,7 @@ func (s Search) toQuery() url.Values {
|
||||
v.Add("colors", strings.Join([]string(s.Colors), ","))
|
||||
}
|
||||
if s.Page > 0 {
|
||||
v.Add("page", strconv.Itoa(s.Page))
|
||||
v.Add("page", strconv.FormatInt(s.Page, 10))
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user