199 lines
3.9 KiB
Go
199 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
var registry *XdccProviderRegistry = nil
|
|
|
|
func init() {
|
|
registry = NewProviderRegistry()
|
|
registry.AddProvider(&XdccEuProvider{})
|
|
}
|
|
|
|
var defaultColWidths []int = []int{100, 10, -1}
|
|
|
|
const (
|
|
KiloByte = 1024
|
|
MegaByte = KiloByte * 1024
|
|
GigaByte = MegaByte * 1024
|
|
)
|
|
|
|
func FloatToString(value float64) string {
|
|
if value-float64(int64(value)) > 0 {
|
|
return strconv.FormatFloat(value, 'f', 2, 32)
|
|
}
|
|
return strconv.FormatFloat(value, 'f', 0, 32)
|
|
}
|
|
|
|
func formatSize(size int64) string {
|
|
if size < 0 {
|
|
return "--"
|
|
}
|
|
|
|
if size >= GigaByte {
|
|
return FloatToString(float64(size)/float64(GigaByte)) + "GB"
|
|
} else if size >= MegaByte {
|
|
return FloatToString(float64(size)/float64(MegaByte)) + "MB"
|
|
} else if size >= KiloByte {
|
|
return FloatToString(float64(size)/float64(KiloByte)) + "KB"
|
|
}
|
|
return FloatToString(float64(size)) + "B"
|
|
}
|
|
|
|
func searchCommand(args []string) {
|
|
searchCmd := flag.NewFlagSet("search", flag.ExitOnError)
|
|
sortByFilename := searchCmd.Bool("s", false, "sort results by filename")
|
|
|
|
args = parseFlags(searchCmd, args)
|
|
|
|
printer := NewTablePrinter([]string{"File Name", "Size", "URL"})
|
|
printer.SetMaxWidths(defaultColWidths)
|
|
|
|
if len(args) < 1 {
|
|
fmt.Println("search: no keyword provided.")
|
|
os.Exit(1)
|
|
}
|
|
|
|
res, _ := registry.Search(args[0])
|
|
for _, fileInfo := range res {
|
|
printer.AddRow(Row{fileInfo.Name, formatSize(fileInfo.Size), fileInfo.Url})
|
|
}
|
|
|
|
if *sortByFilename {
|
|
printer.SortByColumn(0)
|
|
}
|
|
printer.Print()
|
|
}
|
|
|
|
func transferLoop(transfer *XdccTransfer) {
|
|
pb := NewProgressBar()
|
|
|
|
evts := transfer.PollEvents()
|
|
quit := false
|
|
for !quit {
|
|
e := <-evts
|
|
switch evtType := e.(type) {
|
|
case *TransferStartedEvent:
|
|
pb.SetTotal(int(evtType.FileSize))
|
|
pb.SetFileName(evtType.FileName)
|
|
pb.SetState(ProgressStateDownloading)
|
|
case *TransferProgessEvent:
|
|
pb.Increment(int(evtType.transferBytes))
|
|
case *TransferCompletedEvent:
|
|
pb.SetState(ProgressStateCompleted)
|
|
quit = true
|
|
}
|
|
}
|
|
// TODO: do clean-up operations here
|
|
}
|
|
|
|
func doTransfer(transfer *XdccTransfer) {
|
|
err := transfer.Start()
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
transferLoop(transfer)
|
|
}
|
|
|
|
func parseFlags(flagSet *flag.FlagSet, args []string) []string {
|
|
findFirstFlag := func(args []string) int {
|
|
for i, arg := range args {
|
|
if strings.HasPrefix(arg, "-") || strings.HasPrefix(arg, "--") {
|
|
return i
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
flagIdx := findFirstFlag(args)
|
|
if flagIdx >= 0 {
|
|
flagSet.Parse(args[flagIdx:])
|
|
return args[:flagIdx]
|
|
}
|
|
return args
|
|
}
|
|
|
|
func loadUrlListFile(filePath string) []string {
|
|
file, err := os.Open(filePath)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
urlList := make([]string, 0)
|
|
|
|
scanner := bufio.NewScanner(file)
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
urlList = append(urlList, line)
|
|
}
|
|
|
|
if err := scanner.Err(); err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
return urlList
|
|
}
|
|
|
|
func getCommand(args []string) {
|
|
getCmd := flag.NewFlagSet("get", flag.ExitOnError)
|
|
path := getCmd.String("o", ".", "output folder of dowloaded file")
|
|
inputFile := getCmd.String("i", "", "input file containing a list of urls")
|
|
|
|
urlList := parseFlags(getCmd, args)
|
|
|
|
if *inputFile != "" {
|
|
urlList = append(urlList, loadUrlListFile(*inputFile)...)
|
|
}
|
|
|
|
wg := sync.WaitGroup{}
|
|
for _, urlStr := range urlList {
|
|
if strings.HasPrefix(urlStr, "irc://") {
|
|
url, err := parseIRCFileURl(urlStr)
|
|
|
|
if err != nil {
|
|
fmt.Println(err.Error())
|
|
os.Exit(1)
|
|
}
|
|
|
|
wg.Add(1)
|
|
transfer := NewXdccTransfer(*url, *path)
|
|
go func(transfer *XdccTransfer) {
|
|
doTransfer(transfer)
|
|
wg.Done()
|
|
}(transfer)
|
|
} else {
|
|
|
|
}
|
|
}
|
|
wg.Wait()
|
|
}
|
|
|
|
func main() {
|
|
|
|
if len(os.Args) < 2 {
|
|
fmt.Println("one of the following subcommands is expected: [search, get]")
|
|
os.Exit(1)
|
|
}
|
|
|
|
switch os.Args[1] {
|
|
case "search":
|
|
searchCommand(os.Args[2:])
|
|
case "get":
|
|
getCommand(os.Args[2:])
|
|
default:
|
|
fmt.Println("no such command: ", os.Args[1])
|
|
os.Exit(1)
|
|
}
|
|
}
|