Пример #1
0
func (p *parser) printUsage(w io.Writer) {
	fmt.Fprintf(w, "Usage:\n  %s", p.program)
	if p.hasOptions() {
		fmt.Fprintf(w, " [OPTIONS...]")
	}
	for _, arg := range p.posArgs {
		fs := func() string {
			switch arg.arity {
			case arity{0, 1}:
				return "[%s]"
			case arity{1, infArity}:
				return "%s..."
			case arity{0, infArity}:
				return "[%s...]"
			default:
				return "<%s>"
			}
		}()
		// if arg.arity != arity{1,1} {
		fmt.Fprintf(w, " "+fs, arg.name)
		// }
		// if arg.arity > 1 {
		//  for range iter.N(int(arg.arity - 1)) {
		//      fmt.Fprintf(w, " "+fs, arg.name)
		//  }
		// }
	}
	fmt.Fprintf(w, "\n")
	if p.description != "" {
		fmt.Fprintf(w, "\n%s\n", missinggo.Unchomp(p.description))
	}
	if awd := p.posWithHelp(); len(awd) != 0 {
		fmt.Fprintf(w, "Arguments:\n")
		tw := newUsageTabwriter(w)
		for _, a := range awd {
			fmt.Fprintf(tw, "  %s\t(%s)\t%s\n", a.name, a.value.Type(), a.help)
		}
		tw.Flush()
	}
	var opts []arg
	for _, v := range p.flags {
		opts = append(opts, v)
	}
	slices.Sort(opts, func(left, right arg) bool {
		return left.name < right.name
	})
	writeOptionUsage(w, opts)
}
Пример #2
0
// This is a helper that sets Files and Pieces from a root path and its
// children.
func (info *Info) BuildFromFilePath(root string) (err error) {
	info.Name = filepath.Base(root)
	info.Files = nil
	err = filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if fi.IsDir() {
			// Directories are implicit in torrent files.
			return nil
		} else if path == root {
			// The root is a file.
			info.Length = fi.Size()
			return nil
		}
		relPath, err := filepath.Rel(root, path)
		log.Println(relPath, err)
		if err != nil {
			return fmt.Errorf("error getting relative path: %s", err)
		}
		info.Files = append(info.Files, FileInfo{
			Path:   strings.Split(relPath, string(filepath.Separator)),
			Length: fi.Size(),
		})
		return nil
	})
	if err != nil {
		return
	}
	slices.Sort(info.Files, func(l, r FileInfo) bool {
		return strings.Join(l.Path, "/") < strings.Join(r.Path, "/")
	})
	err = info.GeneratePieces(func(fi FileInfo) (io.ReadCloser, error) {
		return os.Open(filepath.Join(root, strings.Join(fi.Path, string(filepath.Separator))))
	})
	if err != nil {
		err = fmt.Errorf("error generating pieces: %s", err)
	}
	return
}
Пример #3
0
func (t *Torrent) writeStatus(w io.Writer, cl *Client) {
	fmt.Fprintf(w, "Infohash: %x\n", t.infoHash)
	fmt.Fprintf(w, "Metadata length: %d\n", t.metadataSize())
	if !t.haveInfo() {
		fmt.Fprintf(w, "Metadata have: ")
		for _, h := range t.metadataCompletedChunks {
			fmt.Fprintf(w, "%c", func() rune {
				if h {
					return 'H'
				} else {
					return '.'
				}
			}())
		}
		fmt.Fprintln(w)
	}
	fmt.Fprintf(w, "Piece length: %s\n", func() string {
		if t.haveInfo() {
			return fmt.Sprint(t.usualPieceSize())
		} else {
			return "?"
		}
	}())
	if t.haveInfo() {
		fmt.Fprintf(w, "Num Pieces: %d\n", t.numPieces())
		fmt.Fprint(w, "Piece States:")
		for _, psr := range t.pieceStateRuns() {
			w.Write([]byte(" "))
			w.Write([]byte(pieceStateRunStatusChars(psr)))
		}
		fmt.Fprintln(w)
	}
	fmt.Fprintf(w, "Reader Pieces:")
	t.forReaderOffsetPieces(func(begin, end int) (again bool) {
		fmt.Fprintf(w, " %d:%d", begin, end)
		return true
	})
	fmt.Fprintln(w)

	fmt.Fprintf(w, "Trackers:\n")
	func() {
		tw := tabwriter.NewWriter(w, 0, 0, 2, ' ', 0)
		fmt.Fprintf(tw, "    URL\tNext announce\tLast announce\n")
		for _, ta := range slices.Sort(slices.FromMapElems(t.trackerAnnouncers), func(l, r *trackerScraper) bool {
			return l.url < r.url
		}).([]*trackerScraper) {
			fmt.Fprintf(tw, "    %s\n", ta.statusLine())
		}
		tw.Flush()
	}()

	fmt.Fprintf(w, "DHT Announces: %d\n", t.numDHTAnnounces)

	fmt.Fprintf(w, "Pending peers: %d\n", len(t.peers))
	fmt.Fprintf(w, "Half open: %d\n", len(t.halfOpen))
	fmt.Fprintf(w, "Active peers: %d\n", len(t.conns))
	slices.Sort(t.conns, worseConn)
	for i, c := range t.conns {
		fmt.Fprintf(w, "%2d. ", i+1)
		c.WriteStatus(w, t)
	}
}