// assembleJob prepares for printing a job by fetching the job's ticket and payload. // // The caller is responsible to remove the returned file. // // Errors are returned as a string (last return value), for reporting // to GCP and local log. func (gcp *GoogleCloudPrint) assembleJob(job *Job) (*cdd.CloudJobTicket, string, string, *cdd.PrintJobStateDiff) { ticket, err := gcp.Ticket(job.GCPJobID) if err != nil { return nil, "", fmt.Sprintf("Failed to get a ticket: %s", err), &cdd.PrintJobStateDiff{ State: &cdd.JobState{ Type: cdd.JobStateAborted, DeviceActionCause: &cdd.DeviceActionCause{ErrorCode: cdd.DeviceActionCauseInvalidTicket}, }, } } file, err := ioutil.TempFile("", "cups-connector-gcp-") if err != nil { return nil, "", fmt.Sprintf("Failed to create a temporary file: %s", err), &cdd.PrintJobStateDiff{ State: &cdd.JobState{ Type: cdd.JobStateAborted, DeviceActionCause: &cdd.DeviceActionCause{ErrorCode: cdd.DeviceActionCauseOther}, }, } } gcp.downloadSemaphore.Acquire() t := time.Now() // Do not check err until semaphore is released and timer is stopped. err = gcp.Download(file, job.FileURL) dt := time.Since(t) gcp.downloadSemaphore.Release() if err != nil { // Clean up this temporary file so the caller doesn't need extra logic. os.Remove(file.Name()) return nil, "", fmt.Sprintf("Failed to download data: %s", err), &cdd.PrintJobStateDiff{ State: &cdd.JobState{ Type: cdd.JobStateAborted, DeviceActionCause: &cdd.DeviceActionCause{ErrorCode: cdd.DeviceActionCauseDownloadFailure}, }, } } log.InfoJobf(job.GCPJobID, "Downloaded in %s", dt.String()) defer file.Close() log.DebugJobf(job.GCPJobID, "Assembled with file %s: %+v", file.Name(), ticket.Print.Color) return ticket, file.Name(), "", &cdd.PrintJobStateDiff{} }
// listenNotifications handles the messages found on the channels. func (pm *PrinterManager) listenNotifications(jobs <-chan *lib.Job, xmppMessages <-chan xmpp.PrinterNotification) { go func() { for { select { case <-pm.quit: return case job := <-jobs: log.DebugJobf(job.JobID, "Received job: %+v", job) go pm.printJob(job.CUPSPrinterName, job.Filename, job.Title, job.User, job.JobID, job.Ticket, job.UpdateJob) case notification := <-xmppMessages: log.Debugf("Received XMPP message: %+v", notification) if notification.Type == xmpp.PrinterNewJobs { if p, exists := pm.printers.GetByGCPID(notification.GCPID); exists { go pm.gcp.HandleJobs(&p, func() { pm.incrementJobsProcessed(false) }) } } } } }() }