func (c *APIClient) RetrieveObjects(endpoint string, args []string, outCh chan *vt.Object, errCh chan error) error {
	defer close(outCh)
	defer close(errCh)
	h := PQueue{}
	heap.Init(&h)
	objCh := make(chan PQueueNode)
	getWg := &sync.WaitGroup{}
	threads := viper.GetInt("threads")
	if threads == 0 {
		panic("RetrieveObjects called with 0 threads")
	}
	throttler := make(chan interface{}, threads)
	for order, arg := range args {
		getWg.Add(1)
		go func(order int, arg string) {
			throttler <- nil
			obj, err := c.GetObject(vt.URL(endpoint, arg))
			if err == nil {
				objCh <- PQueueNode{Priority: order, Data: obj}
			} else {
				if apiErr, ok := err.(vt.Error); ok && apiErr.Code == "NotFoundError" {
					objCh <- PQueueNode{Priority: order, Data: err}
				} else {
					fmt.Fprintln(os.Stderr, err)
					os.Exit(1)
				}
			}
			getWg.Done()
			<-throttler
		}(order, arg)
	}
	outWg := &sync.WaitGroup{}
	outWg.Add(1)
	go func() {
		order := 0
		for p := range objCh {
			heap.Push(&h, p)
			if h[0].Priority == order {
				if obj, ok := h[0].Data.(*vt.Object); ok {
					outCh <- obj
				} else {
					errCh <- h[0].Data.(error)
				}
				heap.Pop(&h)
				order++
			}
		}
		for h.Len() > 0 {
			item := heap.Pop(&h).(PQueueNode).Data
			if obj, ok := item.(*vt.Object); ok {
				outCh <- obj
			} else {
				errCh <- item.(error)
			}
		}
		outWg.Done()
	}()
	getWg.Wait()
	close(objCh)
	outWg.Wait()
	return nil
}
RetrieveObjects retrieves objects from the specified endpoint. The endpoint
must contain a %s placeholder that will be replaced with items from the args
slice. The objects are put into the outCh as they are retrieved.
package utils
import (
	"container/heap"
	"errors"
	"fmt"
	vt "github.com/VirusTotal/vt-go"
	"github.com/spf13/viper"
	"os"
	"sync"
)
type APIClient struct {
	*vt.Client
}
func NewAPIClient(agent string) (*APIClient, error) {
	apikey := viper.GetString("apikey")
	if apikey == "" {
		return nil, errors.New(
			"An API key is needed. Either use the --apikey flag or run \"vt init\" to set up your API key")
	}
	c := vt.NewClient(apikey)
	c.Agent = agent
	return &APIClient{c}, nil
}