Hey guys,
We have a lot of progress to report! Thanks to Michael Lazarski,
Akshay Shekher and Tom Beckmann we now have a working implementation
of Contractor daemon using the new API. It's already much less buggy
than the older one.
Akshay has also transitioned Granite's wrapper to Contractor D-bus
API to the new API, it just needs one final round of review:
https://code.launchpad.net/~voldyman/granite/contractor-wid-dep-new-Contractor/+merge/158161
As soon as that's merged I'll land the new Contractor to the daily
PPA.
He has also transitioned the Contractor widgets to the new API, but
Dan doesn't want any widgets interfacing with Contractor in Granite,
so the merge request deprecates them instead of updating them.
All that's left is to document the API (unfortunately the old
Contractor API is undocumented too) and to transition applications to
the new API. It's easy and will instantly fix multiple bugs (e.g.
Scratch printing problems Cassidy complained about).
2013/3/30 Sergey "Shnatsel" Davidoff <sergey@xxxxxxxxxxxxxxxx>
Hey guys,
I have some unpleasant things to bring up. Sorry for the long post,
I hope it will not end up being another "TL;DR". (Come on, this is
important!)
As I've already reported, the current Contractor API is flawed. It
relies on the client app calling Process.spawn_command_line_async
on the string Contractor returns, which is bad for a long list of
reasons. The most apparent one is being unable to handle filenames
with spaces in them! This particular bug can be worked around in
Contractor in an ugly way, but other issues remail and the API is
not future-proof, so we'll have to break it and Granite API/ABI
sooner or later (because Granite provides widgets and convenience
functions for accessing Contractor API). Obviously it's better done
sooner than later, while we don't have much code to transition and
before the relevant Granite widgets get into a stable release.
The more future-proof approach is to return a contract identifier to
the client app and make the app call Contractor again to execute an
action, passing it the identifier and the filename. This way
Contractor can use proper process-launching functions or use
completely different last-mile data transfer mechanisms, so we'll be
able to add support for streaming data without writing it to disk or
invoking D-bus methods, all without breaking the API in the future.
I've investigated the problems of the current Contractor and wrote a
better specification, detailing its expected behavior and the
required API changes. I've discussed it with the original Python
Contractor authors and got the green light from them. Michael
Lazarski (lampe2) has taken a stab at cleaning up Ammonkey's code
and implementing the spec, but he's currently preoccupied by
contracted work (no pun intended). His Contractor branch can be
found at lp:contractor.
Additionally, I've looked into the state of Contractor support in
Granite and elementary applications. In short, it's not glamorous.
None of the apps use the Granite-provided ContractorMenu widget for
the "Export" button; every single app reinvents the wheel and
populates regular GTK menu with items acquired from Granite's
Contractor wrapper. Maya (the least ugly implementation I've seen so
far) even has a dedicated widget that's a clone of ContractorMenu!
The other Contractor widget, ContractorView, is used only by Eidete
where it doesn't seem to work; not sure if that's Contractor's fault
or Eidete's.
Finally, I don't understand why Granite has a wrapper for Contractor
- it doesn't seem to reduce complexity or abstract anything. Using
the D-bus API directly requires almost the same amount of code.
So IMO the proper course of action is the following:
* Rework Contractor's D-bus API according to my specification
* Deprecate/abolish the Contractor wrapper in Granite
* Update Granite widgets and Pantheon Files to work with the new
D-bus API
* Migrate other applications to using the Granite widgets
(currently Maya, Scratch, Midori and elementary-flavored Simple Scan)
However, I'm not sure this course of action is feasible for Luna.
I'm absolutely not OK with releasing Granite with an API so flawed
and which we're going to break in the future, so the alternative is
to replace the current Contractor wrapper functions with stubs, mark
them deprecated and replace Granite functionality in apps with
something else.
The options that spring to mind are:
* Replace Contractor actions with "Open With"
* Replace Contractor actions with a roughly similar but severely
limited nautilus-sendto. Despite its name it's not actually related
to Nautilus. This way we get sending files by bluetooth, email and
IM; the catch is that Geary is not supported by nautilus-sendto, so
we'll have to implement it (it should be done sooner or later for
decent integration with Ubuntu).
* Remove the "Export" button from apps altogether
Thoughts?
--
Sergey "Shnatsel" Davidoff
OS architect @ elementary
--
Sergey "Shnatsel" Davidoff
OS architect @ elementary