Giter Club home page Giter Club logo

cloudprint's Introduction

Cloudprint Build Status

This project is no longer maintained

Google has announced that CloudPrint will be discontinued as of December 31, 2020. See their support article for their recommended migration paths.


Cloudprint is a Ruby library for interacting with Google's Cloud Print service, a technology that allows you to print over the web from anywhere to any printer.

Setting things up.

To start using cloudprint, you first need to add it to your Gemfile, with an entry such as this:

gem 'cloudprint'

Afterwards, run bundle install

Next, you'll need to authenticate your users with Google Cloud Print. Cloud Print uses OAuth2 as an authentication mechanism.

First, you need to register your application within the Google Console. To do that, go to https://cloud.google.com/console. Doing this will provide you with two things that will be needed to manage your users' printers: a client ID and a client secret.

Authenticating your users.

Once you've registered your application, you will need to send your users to a URL where they can allow your application to manage their printer. You will also need to specify a URL of yours where they will be sent back after giving you access.

client = CloudPrint::Client.new(client_id: 'your_app_id', client_secret: 'your_app_secret')
redirect_url = 'http://your.app/redirect_uri'
client.auth.generate_url(redirect_url)

When they come, their request to your URL will have an extra parameter named 'code' attached to it. You then exchange this code for a refresh token. Note that you also have to include the redirect URL which you specified above.

code = params[:code]
token = client.auth.generate_token(code, redirect_url)

The client is all set to start using the URI, but you will want to store this refresh token so you can get access again at a later time. Subsequently, you can set the refresh token on Cloudprint::Client instances yourself.

client = CloudPrint::Client.new(
  refresh_token: 'refresh_token',
  client_id: 'your_app_id',
  client_secret: 'your_app_secret',
)

With this in place โ€” and with the user's printer set up from the CloudPrint UI โ€” you now have everything you need to start using their printer.

Printing

Printing with the cloudprint gem is done with two kinds of objects. CloudPrint::Printer objects represent printers your users have set up in their CloudPrint accounts. You then ask these objects to print things like this:

# Get a list of all the printers this client can talk to.
printers = client.printers.all                      

# Get a printer with a specific id
my_printer = client.printers.find('printer_id')

# Print using this printer.
# The :content option can also take a File object as a parameter. 
# CloudPrint accepts HTML and PDF files.
my_printer.print(content: "<h1>Hello World</h1>", content_type: "text/html")

Here's where the second kind of object comes in. If your content has been succesfully sent to the printer, the cloudprint gem will return a CloudPrint::PrintJob object. Among other things, this object will provide you with an ID for the print job and, a status code, and an error code if anything happened that prevented your document from getting printed.

Most of the time, the PrintJob object that your print() call will return has a status of IN_PROGRESS or QUEUED.

If your application can simply wait for the job, you can call refresh! on your print job until its status changes. If not, you can store the ID and fetch the print job at a later time to verify its status.

my_job = client.print_jobs.find('job_id')

# Returns the status, one of QUEUED, IN_PROGRESS, DONE, ERROR, SUBMITTED
my_job.status 

You can also delete a job, after it has finished.

my_job.delete!

Example Print Parameters

While sending the print option to google coudprint we need to set some custom parameters an exmaple of all the parameters below:

my_printer.print(
  content: "<h1>Hello World</h1>", 
  content_type: "text/html", 
  title: 'Example Title', 
  ticket: {
    version: "1.0",
    print: {
      vendor_ticket_item:
        [
          { id: "psk:PageMediaType", value: "psk:Plain" },
          { id: "force-pwg-raster", value: "false" }
        ],
      color:{ vendor_id: "", type: 1 },
      duplex:{ type: 0 },
      page_orientation: { type: 2 },
      copies: { copies: 1 },
      dpi: { horizontal_dpi: 300,vertical_dpi: 300, vendor_id: "" },
      fit_to_page: { type: 3 },
      media_size: { width_microns: 210000, height_microns: 297000, is_continuous_feed: false, vendor_id: "2" },
      collate: { collate: false },
      reverse_order: { reverse_order: false }
    }
  }
)

Note that for using pdf your need to set

  content: open(file_path, r),
  content_type: 'application/pdf'

Testing

For your testing needs, cloudprint objects can be stubbed at will and initializing them does not require a connection. For example, to stub a print() call with the shoulda library, one would do this:

my_printer = CloudPrint::Printer.new(id: 'id', status: 'OK', name: 'test_printer', display_name: 'Test Printer'
my_job = CloudPrint::PrintJob.new({}) # see the PrintJob class for what this hash can hold
my_printer.stubs(:print).returns(my_job)

More help

Please submit an issue via GitHub if you need more help with the cloudprint gem.

cloudprint's People

Contributors

broosk1993 avatar dilkhush avatar jimryan avatar josephecombs avatar nasa42 avatar owyongsk avatar sebastianszturo avatar troelskn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cloudprint's Issues

Trying to print returns nil

p = CloudPrint::Client.new(refresh_token: "refresh", client_id: "id", client_secret: "secret", callback_url: "Valid callback url")
my_printer = p.printers.find("id")
my_printer.print(content: "html", content_type: "text/html")

return nil :(

A refresh_token is not available

Hello all,

me again ๐Ÿ˜ž

I'm getting A refresh_token is not available.

So, this happens once the OAuth has been authenticated, and we try to hit the endpoint on Google again.

I've debugged the code and tried to run client.refresh_token, no luck here.

Any ideas?

Example of actually printing a PDF file?

So arguably this is likely a documentation issue more than a problem (I hope), but the docs mention that you just pass a File as the content (and presumably application/pdf as the content type), but I canntot get that to work (I get errors about "no implicit conversion of nil into String" from within net/http/generic_request).

I also see other issues where it looks like folks are encoding the PDF content into base64 ahead of time - not sure if that is a choice of a necessity.

So any chance of an example of what you need to minimally print a PDF file via the gem would be much appreciated!

Unable to Connect to google

could you create a example application, on how this should properly be implemented with oauth connecting to google.

PDF not align properly.

Hi.

I'm using your gem and it works perfect, almost...

I want to print a label for a product, I construct the PDF in my app, no problem, Initialize a CloudPrint instance and call print on it. The problem comes when the printer prints the label. The position of the label is totally wrong. It's not at the top of the page where I've expected it to be.

Can you have any control over the page settings, e.g. "Fit to page" or other options you have when printing directly to a printer in Google Chrome?

Here is my code:

          client_id = file[Rails.env.downcase]["client_id"]
          client_secret = file[Rails.env.downcase]["client_secret"]
          client = CloudPrint::Client.new(
            client_id: client_id,
            client_secret: client_secret,
            refresh_token: refresh_token
          )
          client.printers.find(default_printer_id).print(content: base64, content_type: "application/pdf", ticket: {"version": "1.0", "print": {}}, content_transfer_encoding: "base64")

Thank you.

Rewrite the HTTP code to use Faraday.

OAuth2 depends on Faraday which is a lot nicer to work with than Net::HTTP. Since that dependency is already a given, this gem might as well take advantage of Faraday too.

Update Documentation/Readme

Google's documentation for cloudprint is really old now. Their API playground does not feature it any longer, rather they have a ...minimal... simulation tool here

Also, using this gem before the point of having a refresh_token is impossible, and understanding the flow of obtaining a refresh_token is complicated. Martin Fowler wrote an article about this, and he was using a well-documented API!

client.auth method does not exist

I am using gem version 0.3.2 which is also the latest version in the repo. The README says that I should call client.auth.generate_url method. However, I get the following error:

NoMethodError: undefined method `auth' for #CloudPrint::Client:0x007f9559098918

It seems like, either a new gem version needs to be pushed to rubygems.org or the documentation is out of date.

Change Paper Size

Is there anyway to change the paper size with this gem? I'm trying to print a 5x7 card and I can't find anywhere that the paper size is specified, so it's forcing a letter size on my print job.

Automate the process of authenticating.

I think we want a singleton class like CloudPrint::Auth that supports the following methods:

  • generate_url should generate a correct URL.
  • process_code should generate a refresh token (default) or single access token (optional)

Failure to open TCP connection

Hello,

Very recently, and out of nowhere, the following error keeps coming up when trying to use client.printers.find(<printer_id>):

SocketError: Failed to open TCP connection to www.google.com:443 (getaddrinfo: No address associated with hostname)

I wonder what could be causing this problem?

UI State not available on print job

Google Cloud Print provides a UI State that includes a summary, progress of a job, and a cause for display use. Parsing that information into the print_job would help us display errors correctly with the same terminology as Google's UI.

search_all delegates to invalid query

Calling client.printers.all delegates to client.printers.search_all, which in turn delegates to client.printers.search('all'). This doesn't return any printers, except for the default "Save to Google Docs" (__google__docs). I suggest changing method_missing to exclude "all" from the regexp, and then change def all to be an alias on search

Ruby on Rails

How do I run an application in Ruby on Rails? is possible?

Update dependency versions

The current latest published gem has a dependency on oauth2 0.8.0. This is incompatible with the latest Rails.

It seems to work fine if I change the dependency to 1.1.0. Could you update and publish a new gem version?

CloudPrint return nil after used .print method

I'm using this:

cp = CloudPrint::Client.new(refresh_token: "sent refresh token valid", client_id: "sent valid id", client_secret: "sent valid secret", callback_url: "Valid callback url")
my_printer = cp.printers.find("valid id printer") #get correctly the printer

my_printer.print(content: "<h1>Hello World</h1>", content_type: "text/html")
#this return nil and not print

what is my mistake ?

Can't print PDF google drive

Can't get pdf to correctly print when printing to google drive. pdf shows up fine on local but comes across blank in google drive.
File.open(Rails.root.join('public', "#{invoice_number}.pdf"), 'wb') do |file|
file.write(decoded_invoice_pdf)
end
printer.print(title: "#{invoice_number}_1.pdf", content: decoded_invoice_pdf, content_type: "application/pdf")
printer.print(title: "#{invoice_number}_2.pdf", content: File.read(Rails.root.join('public', "#{invoice_number}.pdf")), content_type: "application/pdf")

Net::ReadTimeout: Net::ReadTimeout

Hello,

This gem has been working properly in the past. Now the exception "Net::ReadTimeout:Net::ReadTimeout" is raised when a job is submitted.

What could be the reason for this? I saw a pull request that suggests to update the Net::HTTP to Faraday. Could it be that Net::HTTP is getting old?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.