Source

ukiyo / ukiyo.go

package main

import (
	"fmt"
	"github.com/jmoiron/go-pkg-optarg"
	"strconv"
	"strings"
)

const VERSION = "0.1b"

type Options struct {
	Update          bool
	Help            bool
	Version         bool
	Verbose         bool
	List            bool
	SetDownloadPath bool
	Sync            bool
	Show            bool
	// sites
	ListSites       bool
	AddSite         string
	RemoveSite      string
	SetSitePriority string
	Search          bool

	Filter *Filter
}

var opts Options

// print only if verbose is on
func vPrintf(s string, x ...interface{}) {
	if opts.Verbose {
		fmt.Printf(s, x...)
	}
}

func main() {
	if opts.Help {
		optarg.Usage()
		return
	}
	if opts.Version {
		fmt.Printf("%s\n", VERSION)
		return
	}
	if opts.Verbose {
		fmt.Printf("Verbosity on.\n")
	}

	if opts.ListSites {
		ListSites()
		return
	}

	if len(opts.AddSite) > 0 {
		var priority int
		var err error
		name := opts.AddSite
		if len(optarg.Remainder) == 0 {
			fmt.Printf("Error: --add-site requires at least a name and a url for argument.")
			return
		}
		url := optarg.Remainder[0]

		// set the optional priority, or use the max
		if len(optarg.Remainder) > 1 {
			priority, err = strconv.Atoi(optarg.Remainder[1])
			if err != nil {
				fmt.Printf("Error with priority argument: %s\n", err)
			}
		} else {
			db := config.Open()
			defer db.Close()
			row := db.QueryRow("select max(priority) from sites")
			err = row.Scan(&priority)
			if err != nil {
				priority = 1
			} else {
				priority += 1
			}
		}

		AddSite(name, url, priority)
		return
	}

	if len(opts.RemoveSite) > 0 {
		RemoveSite(opts.RemoveSite)
		return
	}

	if opts.Update {
		Update()
	}

	if opts.Search {
		Search(optarg.Remainder...)
	}

	if opts.Show {
		Show(optarg.Remainder...)
	}

}

func Update() {
	UpdateSites(false)
}

func ListSites() {
	db := config.Open()
	defer db.Close()

	rows, err := db.Query("SELECT name, url, priority FROM sites ORDER BY priority")
	if err != nil {
		fmt.Printf("Error fetching sites: %s\n", err)
	}
	for rows.Next() {
		site := new(Site)
		err = rows.Scan(&site.Name, &site.Url, &site.Priority)
		if err == nil {
			fmt.Printf(" %d. %s [%s]\n", site.Priority, site.Name, site.Url)
		} else {
			fmt.Printf("Error: %s\n", err)
		}
	}
}

func Search(terms ...string) {
	UpdateSites(false)
	series, err := FindSeries(true, terms...)
	if err != nil {
		fmt.Printf("Error searching for terms: %s\n", err)
	}

	for _, s := range series {
		fmt.Printf(" * %s (%s)\n", s.Name, s.Site)
	}
}

func Show(terms ...string) {
	UpdateSites()
	series, err := FindOneSeries(true, terms...)
	if err != nil {
		fmt.Printf("Error searching for terms: %s\n", err)
	}

	if len(series) == 0 {
		fmt.Printf("No series found matching term %s\n", strings.Join(terms, " "))
		return
	}
	if len(series) > 1 {
		fmt.Printf("Found %d series matching term \"%s\":\n", len(series), strings.Join(terms, " "))
		for _, s := range series {
			fmt.Printf(" * %s (%s)\n", s.Name, s.Site)
		}
		fmt.Printf("Try using the exact name (or key) of a series.\n")
		return
	}

	chapters := UpdateChapters(series[0].Name)
	for _, c := range chapters {
		fmt.Printf(" * %s %s (%s)\n", c.Series, c.Number, c.Site)
	}
}

func AddSite(name, url string, priority int) {
	err := config.AddSite(name, url, priority)
	if err != nil {
		fmt.Printf("Error adding site: %s\n", err)
	}
}

func RemoveSite(name string) {
	err := config.RemoveSite(name)
	if err != nil {
		fmt.Printf("Error removing site: %s\n", err)
	}
}

func init() {
	optarg.HeaderFmt = "\n  %s options"

	optarg.Add("h", "help", "Show help.", false)
	optarg.Add("", "version", "Show version and exit.", false)
	optarg.Add("v", "verbose", "Show more output.", false)

	optarg.Header("Downloading")
	optarg.Add("u", "update", "Update all site & series info.", false)
	optarg.Add("", "sync", "Sync series info with what is on disk.", false)
	optarg.Add("d", "download", "Download new chapters from series.", false)

	optarg.Header("Sites")
	optarg.Add("", "sites", "List sites.", false)
	optarg.Add("", "add-site", "<name> <url> [priority], Add a site.", "")
	optarg.Add("", "rm-site", "<name>, Remove a site.", "")
	optarg.Add("", "set-site-priority", "<name> <priority>, Set download priority.", "")

	optarg.Header("Series")
	optarg.Add("l", "list", "List series being followed.", false)
	optarg.Add("a", "add-series", "Add a series to the follow list.", false)
	optarg.Add("r", "rm-series", "Remove a series from the follow list.", false)
	optarg.Add("", "find", "Find a series.", false)
	optarg.Add("", "search", "Alias for --find.", false)

	optarg.Header("Chapters")
	optarg.Add("s", "show", "Show chapters from a series.", false)
	optarg.Add("f", "filter", "Filter chapters to show or download.", "")

	for opt := range optarg.Parse() {
		switch opt.Name {
		case "help":
			opts.Help = opt.Bool()
		case "update":
			opts.Update = opt.Bool()
		case "version":
			opts.Version = opt.Bool()
		case "verbose":
			opts.Verbose = opt.Bool()
		// sites
		case "sites":
			opts.ListSites = opt.Bool()
		case "add-site":
			opts.AddSite = opt.String()
		case "rm-site":
			opts.RemoveSite = opt.String()
		case "find", "search":
			opts.Search = opt.Bool()
		case "show":
			opts.Show = opt.Bool()
		case "filter":
			opts.Filter = CompileFilter(opt.String())
		}
	}

}