func NewPrinterManager(cups *cups.CUPS, gcp *gcp.GoogleCloudPrint, xmpp *xmpp.XMPP, snmp *snmp.SNMPManager, printerPollInterval string, gcpMaxConcurrentDownload, cupsQueueSize uint, jobFullUsername, ignoreRawPrinters bool, shareScope string) (*PrinterManager, error) {
	// Get the GCP printer list.
	gcpPrinters, queuedJobsCount, err := allGCPPrinters(gcp)
	if err != nil {
		return nil, err
	}
	// Organize the GCP printers into a map.
	for i := range gcpPrinters {
		gcpPrinters[i].CUPSJobSemaphore = lib.NewSemaphore(cupsQueueSize)
	}
	gcpPrintersByGCPID := lib.NewConcurrentPrinterMap(gcpPrinters)

	// Construct.
	pm := PrinterManager{
		cups: cups,
		gcp:  gcp,
		xmpp: xmpp,
		snmp: snmp,

		gcpPrintersByGCPID: gcpPrintersByGCPID,
		downloadSemaphore:  lib.NewSemaphore(gcpMaxConcurrentDownload),

		jobStatsMutex: sync.Mutex{},
		jobsDone:      0,
		jobsError:     0,

		jobsInFlightMutex: sync.Mutex{},
		jobsInFlight:      make(map[string]struct{}),

		cupsQueueSize:     cupsQueueSize,
		jobFullUsername:   jobFullUsername,
		ignoreRawPrinters: ignoreRawPrinters,
		shareScope:        shareScope,

		quit: make(chan struct{}),
	}

	// Sync once before returning, to make sure things are working.
	if err = pm.syncPrinters(); err != nil {
		return nil, err
	}

	ppi, err := time.ParseDuration(printerPollInterval)
	if err != nil {
		return nil, err
	}
	pm.syncPrintersPeriodically(ppi)
	pm.listenXMPPNotifications()

	for gcpID := range queuedJobsCount {
		go pm.handlePrinterNewJobs(gcpID)
	}

	return &pm, nil
}
func NewPrinterManager(cups *cups.CUPS, gcp *gcp.GoogleCloudPrint, privet *privet.Privet, snmp *snmp.SNMPManager, printerPollInterval string, cupsQueueSize uint, jobFullUsername, ignoreRawPrinters bool, shareScope string, jobs <-chan *lib.Job, xmppNotifications <-chan xmpp.PrinterNotification) (*PrinterManager, error) {
	var printers *lib.ConcurrentPrinterMap
	var queuedJobsCount map[string]uint

	var err error
	if gcp != nil {
		// Get all GCP printers.
		var gcpPrinters []lib.Printer
		gcpPrinters, queuedJobsCount, err = gcp.ListPrinters()
		if err != nil {
			return nil, err
		}
		// Organize the GCP printers into a map.
		for i := range gcpPrinters {
			gcpPrinters[i].CUPSJobSemaphore = lib.NewSemaphore(cupsQueueSize)
		}
		printers = lib.NewConcurrentPrinterMap(gcpPrinters)
	} else {
		printers = lib.NewConcurrentPrinterMap(nil)
	}

	// Construct.
	pm := PrinterManager{
		cups:   cups,
		gcp:    gcp,
		privet: privet,
		snmp:   snmp,

		printers: printers,

		jobStatsMutex: sync.Mutex{},
		jobsDone:      0,
		jobsError:     0,

		jobsInFlightMutex: sync.Mutex{},
		jobsInFlight:      make(map[string]struct{}),

		cupsQueueSize:     cupsQueueSize,
		jobFullUsername:   jobFullUsername,
		ignoreRawPrinters: ignoreRawPrinters,
		shareScope:        shareScope,

		quit: make(chan struct{}),
	}

	// Sync once before returning, to make sure things are working.
	// Ignore privet updates this first time because Privet always starts
	// with zero printers.
	if err = pm.syncPrinters(true); err != nil {
		return nil, err
	}

	// Initialize Privet printers.
	if privet != nil {
		for _, printer := range pm.printers.GetAll() {
			err := privet.AddPrinter(printer, pm.printers.GetByCUPSName)
			if err != nil {
				glog.Warningf("Failed to register %s locally: %s", printer.Name, err)
			} else {
				glog.Infof("Registered %s locally", printer.Name)
			}
		}
	}

	ppi, err := time.ParseDuration(printerPollInterval)
	if err != nil {
		return nil, err
	}
	pm.syncPrintersPeriodically(ppi)
	pm.listenNotifications(jobs, xmppNotifications)

	if gcp != nil {
		for gcpPrinterID := range queuedJobsCount {
			p, _ := printers.GetByGCPID(gcpPrinterID)
			go gcp.HandleJobs(&p, func() { pm.incrementJobsProcessed(false) })
		}
	}

	return &pm, nil
}
Example #3
0
func NewPrinterManager(cups *cups.CUPS, gcp *gcp.GoogleCloudPrint, xmpp *xmpp.XMPP, privet *privet.Privet, snmp *snmp.SNMPManager, printerPollInterval string, gcpMaxConcurrentDownload, cupsQueueSize uint, jobFullUsername, ignoreRawPrinters bool, shareScope string) (*PrinterManager, error) {
	// Get the GCP printer list.
	gcpPrinters, queuedJobsCount, err := allGCPPrinters(gcp)
	if err != nil {
		return nil, err
	}
	// Organize the GCP printers into a map.
	for i := range gcpPrinters {
		gcpPrinters[i].CUPSJobSemaphore = lib.NewSemaphore(cupsQueueSize)
	}
	gcpPrintersByGCPID := lib.NewConcurrentPrinterMap(gcpPrinters)

	// Construct.
	pm := PrinterManager{
		cups:   cups,
		gcp:    gcp,
		xmpp:   xmpp,
		privet: privet,
		snmp:   snmp,

		gcpPrintersByGCPID: gcpPrintersByGCPID,
		downloadSemaphore:  lib.NewSemaphore(gcpMaxConcurrentDownload),

		jobStatsMutex: sync.Mutex{},
		jobsDone:      0,
		jobsError:     0,

		gcpJobsInFlightMutex: sync.Mutex{},
		gcpJobsInFlight:      make(map[string]struct{}),

		cupsQueueSize:     cupsQueueSize,
		jobFullUsername:   jobFullUsername,
		ignoreRawPrinters: ignoreRawPrinters,
		shareScope:        shareScope,

		quit: make(chan struct{}),
	}

	// Sync once before returning, to make sure things are working.
	// Ignore privet updates this first time because Privet always starts
	// with zero printers.
	if err = pm.syncPrinters(true); err != nil {
		return nil, err
	}

	// Initialize Privet printers.
	if privet != nil {
		for _, printer := range pm.gcpPrintersByGCPID.GetAll() {
			getPrinter := func() (lib.Printer, bool) { return pm.gcpPrintersByGCPID.Get(printer.GCPID) }
			err := privet.AddPrinter(printer, getPrinter)
			if err != nil {
				glog.Warningf("Failed to register %s locally: %s", printer.Name, err)
			} else {
				glog.Infof("Registered %s locally", printer.Name)
			}
		}
	}

	ppi, err := time.ParseDuration(printerPollInterval)
	if err != nil {
		return nil, err
	}
	pm.syncPrintersPeriodically(ppi)
	if privet == nil {
		pm.listenNotifications(xmpp.Notifications(), make(chan *lib.Job))
	} else {
		pm.listenNotifications(xmpp.Notifications(), privet.Jobs())
	}

	for gcpID := range queuedJobsCount {
		go pm.handleNewGCPJobs(gcpID)
	}

	return &pm, nil
}