This post originated from an RSS feed registered with Web Buzz
by Stuart Langridge.
Original Post: An Ubuntu One printer
Feed Title: as days pass by
Feed URL: http://feeds.feedburner.com/kryogenix
Feed Description: scratched tallies on the prison wall
At the Ubuntu Developer Summit in October 2011 there was
a
session on Ubuntu One cloud printing. That session was about Ubuntu One being
a gateway to existing cloud printing services, like HP's ePrint and Google Cloud
Print, and I'm looking into that. However, the idea of Ubuntu One being itself a cloud printing service
came up in that discussion: specifically, if I've got an Ubuntu machine with
a printer plugged into it, can I make that printer available from other machines
(or other devices such as phones) through Ubuntu One itself? Can I take my home
printer and use Ubuntu One to set it up so that I can print to that printer
from anywhere in the world and from any device? We (the U1 team)
won't be working on that idea directly, but in the session I suggested that it would
be relatively easily done. Some people asked how it could be done, and suggested
that they might be interested in working on it. This describes one way to do it.
Basically, this process involves being able to send documents to the machine
with the printer connected to it, and then having that machine notice the
newly-arrived documents and printing them. To do this, we need a "U1 printer
daemon" on the printer machine. I propose the following architecture:
There is a machine, in your house or similar, with a printer connected to it.
We'll call this machine the printer machine. On the printer machine,
set up the printer so it can be printed to locally. Next, we invent a printer
daemon. This printer daemon creates a folder and marks that folder as synced
with Ubuntu One, and subscribes to that folder on this machine. The printer daemon then waits for new files in that folder (see
below for how to do this). When a new file arrives, the
printer daemon sends the file to the local printer, and then
deletes the file (so it doesn't linger around forever).
I suggest that the folder that's creates is named
$HOME/.ubuntuone/Print Queues/printer name. It's a hidden
folder because it's not really something that should be shown in a user's home
folder; it's under .ubuntuone because that's a static path across
machines (putting it in $XDG_DATA_HOME is problematic because that
path may not be the same on all machines), it's a separate synced folder
(rather than being under $HOME/Ubuntu One) because files for
printer A only need to be synced to the machine connected to printer A, not to
all machines you have connected to Ubuntu One, and it's under
.ubuntuone/Print Queues because third party apps which want to offer
"print to an Ubuntu One printer" can then list all your Ubuntu One printers by
enumerating the contents of that folder via the
REST API.
A third-party app (say, one on a mobile phone) which wants to offer "print to
an Ubuntu One printer" would then take the document to be printed, show the user
the collection of Ubuntu One printers (by enumerating the contents of
.ubuntuone/Print Queues using the REST API) and then upload the
document to be printed to the chosen .ubuntuone/Print Queues/printer name
folder. No-one ever sees the existence of the .ubuntuone/Print Queues
folder, of course; it's all transparent to the user.
Now, how does one monitor an Ubuntu One synced folder for changes? If you're
a Python app (on Ubuntu or Windows) and you're running a very recent build of
Ubuntu One (the shortly-to-be-released Windows build, or a nightly build on
Ubuntu) you can use the Python SyncDaemonTool,
and your daemon would look roughly like this:
import os, sys
if sys.platform != 'win32':
from twisted.internet import glib2reactor
glib2reactor.install()
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
from twisted.internet import defer, reactor
from ubuntuone.platform.tools import SyncDaemonTool
EXPECTED = os.path.expanduser('~/.ubuntuone/Print Queues/')
@defer.inlineCallbacks
def track_file_download():
sd = SyncDaemonTool()
success_filter = lambda path, info: path.startswith(EXPECTED)
path, info = yield sd.wait_for_signals(signal_ok='DownloadFinished',
success_filter=success_filter)
print '==========\n', path, info
if __name__ == '__main__':
reactor.callWhenRunning(track_file_download)
reactor.run()
This, as noted, requires a very very recent build of Ubuntu One, so it's
probably not useful right now (it will be in the future, though, so if you're
reading this as a result of a Google search, do it this way). The other way
to do this on Ubuntu is to listen to the DownloadFinished signal
on the com.ubuntuone.SyncDaemon.Status D-Bus interface: that code
would look something like this:
A note: most files can't be printed as is: they need the application that
generated them to print them. However, printing systems know natively how to
handle PDF files. What this means, in practice, is that the app which uploads
the file for printing to the printer queue folder should convert it to PDF
before uploading it.
That's my proposal for how this could be done. If you're interested in
hacking on this, I'd love to hear from you!