Canonical Voices

Posts tagged with 'python'

Michael Hall

Ubuntu API Website

For much of the past year I’ve been working on the Ubuntu API Website, a Django project for hosting all of the API documentation for the Ubuntu SDK, covering a variety of languages, toolkits and libraries.  It’s been a lot of work for just one person, to make it really awesome I’m going to need help from you guys and gals in the community.

To help smooth the onramp to getting started, here is a breakdown of the different components in the site and how they all fit together.  You should grab a copy of the branch from Launchpad so you can follow along by running: bzr branch lp:ubuntu-api-website

Django

First off, let’s talk about the framework.  The API website uses Django, a very popular Python webapp framework that’s also used by other community-run Ubuntu websites, such as Summit and the LoCo Team Portal, which makes it a good fit. A Django project consists of one or more Django “apps”, which I will cover below.  Each app consists of “models”, which use the Django ORM (Object-Relational Mapping) to handle all of the database interactions for us, so we can stick to just Python and not worry about SQL.  Apps also have “views”, which are classes or functions that are called when a URL is requested.  Finally, Django provides a default templating engine that views can use to produce HTML.

If you’re not familiar with Django already, you should take the online Tutorial.  It only takes about an hour to go through it all, and by the end you’ll have learned all of the fundamental things about building a Django site.

Branch Root

When you first get the branch you’ll see one folder and a handful of files.  The folder, developer_network, is the Django project root, inside there is all of the source code for the website.  Most of your time is going to be spent in there.

Also in the branch root you’ll find some files that are used for managing the project itself. Most important of these is the README file, which gives step by step instructions for getting it running on your machine. You will want to follow these instructions before you start changing code. Among the instructions is using the requirements.txt file, also in the branch root, to setup a virtualenv environment.  Virtualenv lets you create a Python runtime specifically for this project, without it conflicting with your system-wide Python installation.

The other files you can ignore for now, they’re used for packaging and deploying the site, you won’t need them during development.

./developer_network/

As I mentioned above, this folder is the Django project root.  It has sub-folders for each of the Django apps used by this project. I will go into more detail on each of these apps below.

This folder also contains three important files for Django: manage.py, urls.py and settings.py

manage.py is used for a number of commands you can give to Django.  In the README you’ll have seen it used to call syncdbmigrate and initdb.  These create the database tables, apply any table schema changes, and load them with initial data. These commands only need to be run once.  It also has you run collectstatic and runserver. The first collects static files (images, css, javascript, etc) from all of the apps and puts them all into a single ./static/ folder in the project root, you’ll need to run that whenever you change one of those files in an app.  The second, runserver, runs a local HTTP server for your app, this is very handy during development when you don’t want to be bothered with a full Apache server. You can run this anytime you want to see your site “live”.

settings.py contains all of the Django configuration for the project.  There’s too much to go into detail on here, and you’ll rarely need to touch it anyway.

urls.py is the file that maps URLs to an application’s views, it’s basically a list of regular-expressions that try to match the requested URL, and a python function or class to call for that match. If you took the Django project tutorial I recommended above, you should have a pretty good understanding of what it does. If you ever add a new view, you’ll need to add a corresponding line to this file in order for Django to know about it. If you want to know what view handles a given URL, you can just look it up here.

./developer_network/ubuntu_website/

If you followed the README in the branch root, the first thing it has you do is grab another bzr branch and put it in ./developer_network/ubuntu_website.  This is a Django app that does nothing more than provide a base template for all of your project’s pages. It’s generic enough to be used by other Django-powered websites, so it’s kept in a separate branch that each one can pull from.  It’s rare that you’ll need to make changes in here, but if you do just remember that you need to push you changes branch to the ubuntu-community-webthemes project on Launchpad.

./developer_network/rest_framework/

This is a 3rd party Django app that provides the RESTful JSON API for the site. You should not make changes to this app, since that would put us out of sync with the upstream code, and would make it difficult to pull in updates from them in the future.  All of the code specific to the Ubuntu API Website’s services are in the developer_network/service/ app.

./developer_network/search/

This app isn’t being used yet, but it is intended for giving better search functionality to the site. There are some models here already, but nothing that is being used.  So if searching is your thing, this is the app you’ll want to work in.

./developer_network/related/

This is another app that isn’t being used yet, but is intended to allow users to link additional content to the API documentation. This is one of the major goals of the site, and a relatively easy area to get started contributing. There are already models defined for code snippets, Images and links. Snippets and Links should be relatively straightforward to implement. Images will be a little harder, because the site runs on multiple instances in the cloud, and each instance will need access to the image, so we can’t just use the Django default of saving them to local files. This is the best place for you to make an impact on the site.

./developer_network/common/

The common app provides views for logging in and out of the app, as well as views for handling 404 and 500 errors when the arise.  It also provides some base models the site’s page hierarchy. This starts with a Topic at the top, which would be qml or html5 in our site, followed by a Version which lets us host different sets of docs for the different supported releases of Ubuntu. Finally each set of docs is placed within a Section, such as Graphical Interface or Platform Service to help the user browse them based on use.

./developer_network/apidocs/

This app provides models that correspond directly to pieces of documentation that are being imported.  Documentation can be imported either as an Element that represents a specific part of the API, such as a class or function, or as a Page that represents long-form text on how to use the Elements themselves.  Each one of these may also have a given Namespace attached to it, if the imported language supports it, to further categorize them.

./developer_network/web/

Finally we get into the app that is actually generates the pages.  This app has no models, but uses the ones defined in the common and apidocs apps.  This app defines all of the views and templates used by the website’s pages, so no matter what you are working on there’s a good chance you’ll need to make changes in here too. The templates defined here use the ones in ubuntu_website as a base, and then add site and page specific markup for each.

Getting Started

If you’re still reading this far down, congratulations! You have all the information you need to dive in and start turning a boring but functional website into a dynamic, collaborative information hub for Ubuntu app developers. But you don’t need to go it alone, I’m on IRC all the time, so come find me (mhall119) in #ubuntu-website or #ubuntu-app-devel on Freenode and let me know where you want to start. If you don’t do IRC, leave a comment below and I’ll respond to it. And of course you can find the project, file bugs (or pick bugs to fix) and get the code all from the Launchpad project.

Read more
Michael Hall

Today I reached another milestone in my open source journey: I got my first package uploaded into Debian’s archives.  I’ve managed to get packages uploaded into Ubuntu before, and I’ve attempted to get one into Debian, but this is the first time I’ve actually gotten a contribution in that would benefit Debian users.

I couldn’t have done with without the the help and mentorship of Paul Tagliamonte, but I was also helped by a number of others in the Debian community, so a big thank you to everybody who answered my questions and walked me through getting setup with things like Alioth and re-learning how to use SVN.

One last bit of fun, I was invited to join the Linux Unplugged podcast today to talk about yesterday’s post, you can listen it it (and watch IRC comments scroll by) here: http://www.jupiterbroadcasting.com/51842/neckbeard-entitlement-factor-lup-28/

Read more
Michael Hall

Today was a distracting day for me.  My homeowner’s insurance is requiring that I get my house re-roofed[1], so I’ve had contractors coming and going all day to give me estimates. Beyond just the cost, we’ve been checking on state licensing, insurance, etc.  I’ve been most shocked at the differences in the level of professionalism from them, you can really tell the ones for whom it is a business, and not just a job.

But I still managed to get some work done today.  After a call with Francis Ginther about the API website importers, we should soon be getting regular updates to the current API docs as soon as their source branch is updated.  I will of course make a big announcement when that happens

I didn’t have much time to work on my Debian contributions today, though I did join the DPMT (Debian Python Modules Team) so that I could upload my new python-model-mommy package with the DPMT as the Maintainer, rather than trying to maintain this package on my own.  Big thanks to Paul Tagliamonte for walking me through all of these steps while I learn.

I’m now into my second week of UbBloPoMo posts, with 8 posts so far.  This is the point where the obligation of posting every day starts to overtake the excitement of it, but I’m going to persevere and try to make it to the end of the month.  I would love to hear what you readers, especially those coming from Planet Ubuntu, think of this effort.

[1] Re-roofing, for those who don’t know, involves removing and replacing the shingles and water-proofing paper, but leaving the plywood itself.  In my case, they’re also going to have to re-nail all of the plywood to the rafters and some other things to bring it up to date with new building codes.  Can’t be too safe in hurricane-prone Florida.

Read more
Michael Hall

Quick overview post today, because it’s late and I don’t have anything particular to talk about today.

First of all, the next vUDS was announced today, we’re a bit late in starting it off but we wanted to have another one early enough to still be useful to the Trusty release cycle.  Read the linked mailinglist post for details about where to find the schedule and how to propose sessions.

I pushed another update to the API website today that does a better job balancing the 2-column view of namespaces and fixes the sub-nav text to match the WordPress side of things. This was the first deployment in a while to go off without a problem, thanks to  having a new staging environment created last time.  I’m hoping my deployment problems on this are now far behind me.

I took a task during my weekly Core Apps update call to look more into the Terminal app’s problem with enter and backspace keys, so I may be pinging some of you in the coming week about it to get some help.  You have been warned.

Finally, I decided a few weeks ago to spread out my after-hours community a activity beyond Ubuntu, and I’ve settled on the Debian new maintainers Django website as somewhere I can easily start.  I’ve got a git repo where I’m starting writing the first unit tests for that website, and as part of that I’m also working on Debian packaging for the Python model-mommy library which we use extensively in Ubuntu’s Django website. I’m having to learn (or learn more) Debian packaging, Git workflows and Debian’s processes and community, all of which are going to be good for me, and I’m looking forward to the challenge.

Read more
Michael Hall

Last week I posted on G+ about the a couple of new sets of QML API docs that were published.  Well that was only a part of the actual story of what’s been going on with the Ubuntu API website lately.

Over the last month I’ve been working on implementing and deploying a RESTful JSON service on top of the Ubuntu API website, and last week is when all of that work finally found it’s way into production.  That means we now have a public, open API for accessing all of the information available on the API website itself!  This opens up many interesting opportunities for integration and mashups, from integration with QtCreator in the Ubuntu SDK, to mobile reference apps to run on the Ubuntu phone, or anything else your imagination can come up with.

But what does this have to do with the new published docs?  Well the RESTful service also gives us the ability to push documentation up to the production server, which is how those docs got there.  I’ve been converting the old Django manage.py scripts that would import docs directly into the database, to instead push them to the website via the new service, and the QtMultimedia and QtFeedback API docs were the first ones to use it.

Best of all, the scripts are all automated, which means we can start integrating them with the continuous integration infrastructure that the rest of Ubuntu Engineering has been building around our projects.  So in the near future, whenever there is a new daily build of the Ubuntu SDK, it will also push the new documentation up, so we will have both the stable release documentation as well as the daily development release documentation available online.

I don’t have any docs yet on how to use the new service, but you can go to http://developer.ubuntu.com/api/service/ to see what URLs are available for the different data types.  You can also append ?<field>=<value> keyword filters to your URL to narrow the results.  For example, if you wanted all of the Elements in the Ubuntu.Components namespace, you can use http://developer.ubuntu.com/api/service/elements/?namespace__name=Ubuntu.Components to do that.

That’s it for today, the first day of my UbBloPoMo posts.  The rest of this week I will be driving to and fro for a work sprint with the rest of my team, the Ubuntu SDK team, and many others involved in building the phone and app developer pieces for Ubuntu.  So the rest of this week’s post may be much shorter.  We’ll see.

Happy Hacking.

Read more
Michael Hall

UPDATE: A command porting walk-through has beed added to the documentation.

Back around UDS time, I began work on a reboot of Quickly, Ubuntu’s application development tool.  After two months and just short of 4000 lines of code written, I’m pleased to announce that the inner-workings of the new code is very nearly complete!  Now I’ve reached the point where I need your help.

The Recap

First, let me go back to what I said needed to be done last time.  Port from Python 2 to Python 3: Done. Add built-in argument handling: Done. Add meta-data output: Well, not quite.  I’m working on that though, and now I can add it without requiring anything from template authors.

But here are some other things I did get done. Add Bash shell completion: Done.  Added Help command (that works with all other commands): Done.  Created command class decorators: Done.  Support templates installed in any XDG_DATA_DIRS: Done.  Allow template overriding on the command-line: Done.  Started documentation for template authors: Done.

Now it’s your turn

With the core of the Quickly reboot nearly done, focus can now turn to the templates.  At this point I’m reasonably confident that the API used by the templates and commands won’t change (at least not much).  The ‘create’ and ‘run’ commands from the ubuntu-application template have already been ported, I used those to help develop the API.  But that leaves all the rest of the commands that need to be updated (see list at the bottom of this post).  If you want to help make application development in Ubuntu better, this is a great way to contribute.

For now, I want to focus on finishing the port of the ubuntu-application template.  This will reveal any changes that might still need to be made to the new API and code, without disrupting multiple templates.

How to port a Command

The first thing you need to do is understand how the new Quickly handles templates and commands.  I’ve started on some documentation for template developers, with a Getting Started guide that covers the basics.  You can also find me in #quickly in Freenode IRC for help.

Next you’ll need to find the code for the command you want to port.  If you already have the current Quickly installed, you can find them in /usr/share/quickly/templates/ubuntu-application/, or you can bzr branch lp:quickly to get the source.

The commands are already in Python, but they are stand-alone scripts.  You will need to convert them into Python classes, with the code to be executed being called in the run() method.  You can add your class to the ./data/templates/ubuntu-application/commands.py file in the new Quickly branch (lp:quickly/reboot).  Then submit it as a merge proposal against lp:quickly/reboot.

Grab one and go!

So here’s the full list of ubuntu-application template commands.  I’ll update this list with progress as it happens.  If you want to help, grab one of the TODO commands, and start porting.  Email me or ping me on IRC if you need help.

add: TODO
configure: TODO
create: DONE!
debug: TODO
design: TODO
edit: DONE!
license: TODO
package: DONE!
release: TODO
run: DONE!
save: DONE!
share: TODO
submitubuntu: TODO
test: TODO
tutorial: TODO
upgrade: TODO

Read more
Michael Hall

During this latest round of arguing over the inclusion of Amazon search results in the Unity Dash, Alan Bell pointed out the fact that while the default scopes shipped in Ubuntu were made to check the new privacy settings, we didn’t do a very good job of telling third-party developers how to do it.

(Update: I was told a better way of doing this, be sure to read the bottom of the post before implementing it in your own code)

Since I am also a third-party lens developer, I decided to add it to my come of my own code and share how to do it with other lens/scope developers.  It turns out, it’s remarkably easy to do.

Since the privacy setting is stored in DConf, which we can access via the Gio library, we need to include that in our GObject Introspection imports:

from gi.repository import GLib, Unity, Gio

Then, before performing a search, we need to fetch the Unity Lens settings:

lens_settings = Gio.Settings(‘com.canonical.Unity.Lenses’)

The key we are interested in is ’remote-content-search’, and it can have one of two value, ‘all’ or ‘none’.  Since my locoteams-scope performs only remote searches, by calling the API on http://loco.ubuntu.com, if the user has asked that no remote searches be made, this scope will return without doing anything.

And that’s it!  That’s all you need to do in order to make your lens or scope follow the user’s privacy settings.

Now, before we get to the comments, I’d like to kindly point out that this post is about how to check the privacy setting in your lens or scope.  It is not about whether or not we should be doing remote searches in the dash, or how you would rather the feature be implemented.  If you want to pile on to those argument some more, there are dozens of open threads all over the internet where you can do that.  Please don’t do it here.
&nbps;

Update

I wasn’t aware, but there is a PreferencesManager class in Unity 6 (Ubuntu 12.10) that lets you access the same settings:

You should use this API instead of going directly to GSettings/DConf.

Read more
Michael Hall

Shortly after the Ubuntu App Showdown earlier this year, Didier Roche and Michael Terry kicked off a series of discussions about a ground-up re-write of Quickly.  Not only would this fix many of the complications app developers experienced during the Showdown competition, but it would also make it easier to write tools around Quickly itself.

Unfortunately, neither Didier nor Michael were going to have much time this cycle to work on the reboot.  We had a UDS session to discuss the initiative, but we were going to need community contributions in order to get it done.

JFDI

I was very excited about the prospects of a Quickly reboot, but knowing that the current maintainers weren’t going to have time to work on it was a bit of a concern.  So much so, that during my 9+ hour flight from Orlando to Copenhagen, I decided to have a go at it myself. Between the flight, a layover in Frankfurt without wifi, and a few late nights in the Bella Sky hotel, I had the start of something promising enough to present during the UDS session.  I was pleased that both Didier and Michael liked my approach, and gave me some very good feedback on where to take it next.  Add another 9+ hour flight home, and I had a foundation on which a reboot can begin.

Where is stands now

My code branch is now a part of the Quickly project on Launchpad, you can grab a copy of it by running bzr branch lp:quickly/reboot.  The code currently provides some basic command-line functionality (including shell completion), as well as base classes for Templates, Projects and Commands.  I’ve begun porting the ubuntu-application template, reusing the current project_root files, but built on the new foundation.  Currently only the ‘create’ and ‘run’ commands have been converted to the new object-oriented command class.

I also have examples showing how this new approach will allow template authors to easily sub-class Templates and Commands, by starting both a port of the ubuntu-cli template, and also creating an ubuntu-git-application template that uses git instead of bzr.

What comes next

This is only the very beginning of the reboot process, and there is still a massive amount of work to be done.  For starters, the whole thing needs to be converted from Python 2 to Python 3, which should be relatively easy except for one area that does some import trickery (to keep Templates as python modules, without having to install them to PYTHON_PATH).  The Command class also needs to gain argument parameters, so they can be easily introspected to see what arguments they can take on the command line.  And the whole thing needs to gain a structured meta-data output mechanism so that non-Python application can still query it for information about available templates, a project’s commands and their arguments.

Where you come in

As I said at the beginning of the post, this reboot can only succeed if it has community contributions.  The groundwork has been laid, but there’s a lot more work to be done than I can do myself.  Our 13.04 goal is to have all of the existing functionality and templates (with the exception of the Flash template) ported to the reboot.  I can use help with the inner-working of Quickly core, but I absolutely need help porting the existing templates.

The new Template and Command classes make this much easier (in my opinion, anyway), so it will mostly be a matter of copy/paste/tweak from the old commands to the new ones. In many cases, it will make sense to sub-class and re-use parts of one Template or Command in another, further reducing the amount of work.

Getting started

If you are interested in helping with this effort, or if you simply want to take the current work for a spin, the first thing you should do is grab the code (bzr branch lp:quickly/reboot).  You can call the quickly binary by running ./bin/quickly from within the project’s root.

Some things you can try are:

./bin/quickly create ubuntu-application /tmp/foo

This will create a new python-gtk project called ‘foo’ in /tmp/foo.  You can then call:

./bin/quickly -p /tmp/foo run

This will run the applicaiton.  Note that you can use -p /path/to/project to make the command run against a specific project, without having to actually be in that directory.  If you are in that directory, you won’t need to use -p (but you will need to give the full path to the new quickly binary).

If you are interested in the templates, they are in ./data/templates/, each folder name corresponds to a template name.  The code will look for a class called Template in the base python namespace for the template (in ubuntu-application/__init__.py for example), which must be a subclass of the BaseTemplate class.  You don’t have to define the class there, but you do need to import it there.  Commands are added to the Template class definition, they can take arguments at the time you define them (see code for examples), and their .run() method will be called when invoked from the command line.  Unlike Templates, Commands can be defined anywhere, with any name, as long as they subclass BaseCommand and are attached to a template.

Read more
Michael Hall

When the Unity developers introduced Dash Previews in Unity 6, I knew it was something I wanted to add to Singlet.  I didn’t have time to get the feature added in time to get it into Quantal’s Universe archive, but thanks to Didier Roche and Iain Lane, I was able to get it into Quantal’s Backports archive before the actual release date, so it will be available to all Ubuntu users right away.

Previews for all!

One of the main goals of Singlet, second only to making it easy to write Unity lenses and scopes, was to automatically add new features to any lenses and scopes written with it.  Previews are my first opportunity to put this into practice.  Singlet 0.3 will add Preview information for any Scope or SingleScopeLens written for Singlet 0.2!  To do this, Singlet 0.3 will use the same image, title and description used in the search results to populate the preview.  This is a big improvement over having no preview at all, and there is absolutely nothing the developer needs to do. Even better, if you have a custom handle_uri method, it will also add an “Open” button to your preview which will call it.

Better, faster, simpler Previews

Getting previews for free is nice, but it does limit the preview to only the information you are giving to the result item.  But the Previews API allows you to do so much more, and Singlet lenses and scopes can take full advantage of them.

The simplest way to add more data to your preview is to add a method to your Scope or SingleScopeLens class called add_preview_data.  This method will be called whenever Unity needs to show a preview for one of your result items, and will be given the specific result item being previewed, as well as a reference to the Unity.Preview object itself.

def add_preview_data(self, result_item, preview):
    if result_item['category'] == self.lens.events:
        url_parts = result_item['uri'].split('/')
        event = self._ltp.getTeamEvent(url_parts[5])
        venue = self._ltp.getVenue(event['venue'])
        if 'latitude' in venue and 'longitude' in venue:
            preview.props.image_source_uri = 'http://maps.googleapis.com/maps/api/staticmap?center=%s,%s&zoom=11&size=600x600&markers=%s,%s&sensor=false' % (venue['latitude'], venue['longitude'], venue['latitude'], venue['longitude'])

The result_item is a Python dict containing the keys ‘uri’, ‘image’, ‘category’, ‘mime-type’, ‘title’, ‘description’, and ‘dnd-uri’, the same fields you added to the results model in your search field. The code above, added to the LoCo Teams scope, sets the Preview image to a Google Maps view of the venue’s location. You can also add additional Preview Actions from within this method.

If you want even more control, you can instead add a method called simply preview to your class, which takes the result_item and the full result_model from your scope, letting you create a Unity.Preview object yourself, and doing whatever you want with it.

def preview(self, result_item, result_model):
    preview = Unity.GenericPreview.new(result_item['title'], result_item['description'], None)
    preview.props.image_source_uri = result_item['image']

    some_action = Unity.PreviewAction.new("do_something", "Do Something", None)
    some_action.connect('activated', self.do_something)
    preview.add_action(some_action)

    return preview

Read more
Michael Hall

Back in San Francisco, during UDS-Q, we had a discussion about the need for better online documentation for the various APIs that application developers use to write apps for Ubuntu.  The Ubuntu App Showdown and subsequent AppDevUploadProcess spec work has consumed most of my time since then, but I was able to start putting together a spec for such a site.  The App Showdown feedback we got from our developers survey highlighted the need, as lack of good Gtk documentation for Python was one of the most common problems people experienced, giving it a little more urgency.

Fortunately, Alberto Ruiz was at UDS, and told me about a project he had started for Gnome called Gnome Developer Network (GDN for short).  Alberto had already done quite a bit of work on the database models and GObject Instropection parsing needed to populate it.  The plan is to use GDN as the database and import process, and build a user-friendly web interface on top of that, linking in external resources like tutorials and AskUbuntu questions, as well as user submitted comments and code snippets.

Now that the spec is (mostly) done, we need to get together some developers who can implement it.  There will be a lot of front-end work (mostly HTML, CSS and Javascript), but also enough backend work (Python and Django) to keep anybody occupied.  I’ve created a Launchpad project for the site, and a team you can join if you’re interested in helping out.

The GDN code and some very basic template are already available. You can get the code from bzr with bzr branch lp:ubuntu-api-website and following the instructions in the DEVELOPMENT file.  I’ll also be running a live App Developer Q&A Session at 1700 UTC today (September 19th), and would be happy to help anybody get the code up and running during that time.

Read more
Michael Hall

Due to the popularity of the Ubuntu App Showdown Workshops, I plan to start holding a weekly Q&A session for all Ubuntu app developers using the same format: A live Google+ Hangout with IRC chat.

The first of these will be Wednesday of this week, at 1700 UTC (6pm London, 1pm US Eastern, 10am US Pacific).  Because it will be an On-Air hangout, I won’t have a link until I start the session, but I will post it here on my blog before it starts.  For IRC, I plan on using the #ubuntu-on-air channel on Freenode, though again the exact details will be posted the day of the session.

So bring your questions about developing apps for Ubuntu, packaging an submitting them to the Software Center.  If I can’t answer your question myself, I’ll help you find someone who can.

Read more
Michael Hall

As part of the Ubuntu App Showdown I started on a small project to provide a nice GUI frontend to Quickly.  While I was able to get it working and submitted before the contest deadline, I unfortunately didn’t have the time to make it do everything I wanted.  Since the end of the contest, however, I was able to spend a little more time adding some nice features to it.

Project Management

The majority of the work has gone into Quickly-Gtk’s project management.  Some of this was implemented already, such as the ability to switch the “current” project. But internally it was all kind of a mess of code to track that.  So I replaced all of that with a ProjectManager class that will store both the list of projects Quickly-Gtk knows about, but also keeps track of which project is “current”.  This class also implements Observer design pattern to let other parts of the code know about changes to both the list of projects and the current project.  This made it easy to, for example, display a notification on the screen whenever the current project was changed, regardless of whether it was changed in the window, the indicator, or from a Zeitgeist event.

Zeitgeist event monitoring

The other big development was integrating Quickly-Gtk with Zeitgeist.  For those that aren’t familiar with it, Zeitgeist is an event log that tracks all kinds of user activities and system events.  Applications can read past events or monitor them as they happen.  I wanted Quickly-Gtk to be smart enough to switch to a project as soon as the user started working on it, without requiring the user to make the switch themselves.  To do that, I set a Zeitgeist monitor to listen for file system events in any of the saved project directories.  I also set it to watch for the user viewing the project’s Launchpad page.  If any of those events happen, Quickly-Gtk will automatically make that the current project.

The future of Quickly-Gtk

While I was able to get a lot done with Quickly-Gtk, the underlying Quickly API and command line really weren’t designed to support this kind of use.  However, as a result of what we learned during the App Showdown, Didier Roche has begun planning a reboot of Quickly, which will improve both it’s command-line functionality, and it’s ability to be used as a callable library for apps like Quickly-Gtk.  If you are interested in the direction of Quickly’s development, I urge you to join in those planning meetings.

 

Launchpad Project: https://launchpad.net/quickly-gtk

 

Read more
Michael Hall

Hello Unity is now open for translations!

Please help me make this technology showcase is available to application developers in your native language.  Translations are done through Launchpad, and will be built into the Hello Unity package.

Read more
Michael Hall

I spent some more time over the weekend working on Hello Unity.  If you haven’t already, be sure to read my first post about it.  In short, Hello Unity is a showcase application that demonstrates all the different ways an application developer can integrate their app with the Unity desktop.

The current version of Hello Unity sports a new syntax-highlighted code display, which makes it much easier to read and understand what the code is doing.  I also spent a significant amount of time going through and heavily commenting the code to explain what everything was doing.

In the Launcher section I added support for setting the “urgent” status of the application.  In Unity, this will cause the application’s icon in the Launcher to shake and, if the Launcher is set to auto-hide, will also cause the icon to slide out into view while it shakes.  This is a very useful way of telling a user that your application needs their attention.

A new section was added for integrating with the Message Menu.  It automatically adds a Hello Unity section to the menu, and allows you to add count indicators to it.  Clicking on an item in the menu will execute the code for removing it.  All of this is explicitly commented on in the source code.

Another new section is for Notifications.  While it uses the generic libnotify API, it does highlight how to use it with Ubuntu’s Notify-OSD display system, including how to updated and append text to the currently displayed notification.

Once again, if you are interested in contributing to this project, you can get the code from the Launchpad project page.  Also available there are source tarballs and installable .DEB files.

Read more
Michael Hall

David Planella and I have spent the past couple of weeks gathering, cleaning and verifying Unity integration documentation that has existed on the Ubuntu wiki, individual blogs and inside the source code itself.   After publishing those docs, a couple of people asked for some kind of simple “hello world” type of application to show off how all that integration works.

So, I made one.

You can get the code from Launchpad:

bzr branch lp:hello-unity

It’s not complete yet, but it’s a start.  Let me know if you’re interesting in contributing to it.

Read more
Michael Hall

One of the most requesting things since I first introduced Singlet was to have a Quickly template for creating Unity Lenses with it.  After weeks of waiting, and after upgrading Singlet to work in Precise, and getting it into the Universe repository for 12.04, I finally set to work on learning enough Quickly internals to write a template.

It’s not finished yet, and I won’t guarantee that all of Quickly’s functions work, but after a few hours of hacking I at least have a pretty good start.  It’s not packaged yet, so to try it out you will need todo the following:

  1. bzr branch lp:~mhall119/singlet/quickly-lens-template
  2. sudo ln -s ./quickly-lens-template /usr/share/quickly/templates/singlet-lens
  3. quickly create singlet-lens <your-lens-project-name>
  4. cd <your-lens-project-name>
  5. quickly package

Read more
Michael Hall

Starting today at 1500 UTC, we’ll be conducting a series of online classes for Ubuntu Developer Week.  Whether you are interest in developing new applications for Ubuntu, or want to make an existing app take advantage of all of Ubuntu’s features, this is definitely something you should attend.

This cycle Daniel Holbach will kick things off with a overview of Ubuntu development, using Bazaar and Launchpad to collaborate both online and off with teams of developers all over the world.

After that I will be giving an overview of the unique collection of technologies and services that Ubuntu offers application developers, including Unity integration, Ubuntu One cloud storage, and the Software Center.  Then I will be joined by Micha? Sawicz to talk about Ubuntu TV, and how you can get a development environment setup and start hacking on it yourself

Later, David Callé and Michal Hruby will be showing you how to integrate with the Unity Dash by writing custom lenses and scopes for your content.  And if you are interested in that, be sure to come back Thursday for my session on writing simple lenses and scopes in Python using the Singlet library.

Mark Mims and Dustin Kirland will both by presenting on different ways Ubuntu lets you take advantage of the latest cloud technology to improve the development, testing and deployment of your application and stack.  And Stuart Langridge will be talking about the latest developments in the Ubuntu One Database (U1DB), and then showing how you can integrate our file and data syncing infrastructure into your own application.

You will also learn how to work upstream with Debian (both pulling changes in and sending them back), how to properly and easily package your application for distribution, and of course how to work on contributing changes back to Ubuntu itself.

Read more
Michael Hall

If you have written or know how to write a Quickly template, I’d like to get some help making one for Singlet Lenses and Scopes.

Read more
Michael Hall

I’ve finally had a little extra time to get back to working on Singlet.  There’s been a lot of progress since the first iteration.  To start with, Singlet had to be upgraded to work with the new Lens API introduced when Unity 5.0 landed in the Precise repos.  Luckily the Singlet API didn’t need to change, so any Singlet lenses written for Oneiric and Unity 4 will only need the latest Singlet to work in Precise[1].

The more exciting development, though, is that Singlet 0.2 introduces an API for Scopes.  This means you can write Lenses that support external scopes from other authors, as well as external Scopes for existing lenses.  They don’t both need to be based on Singlet either, you can write a Singlet scope for the Music Lens if you wanted to, and non-Singlet scopes can be written for your Singlet lens.  They don’t even have to be in Python.

In order to make the Scope API, I chose to convert my previous LoCo Teams Portal lens into a generic Community lens and separate LoCo Teams scope.  The Lens itself ends up being about as simple as can be:

from singlet.lens import Lens, IconViewCategory, ListViewCategory 

class CommunityLens(Lens): 

    class Meta:
        name = 'community'
        description = 'Ubuntu Community Lens'
        search_hint = 'Search the Ubuntu Community'
        icon = 'community.svg'
        category_order = ['teams', 'news', 'events', 'meetings']

    teams = IconViewCategory("Teams", 'ubuntu-logo')

    news = ListViewCategory("News", 'news-feed')

    events = ListViewCategory("Events", 'calendar')

    meetings = ListViewCategory("Meetings", 'applications-chat')


As you can see, it’s really nothing more that some meta-data and the categories.  All the real work happens in the scope:

class LocoTeamsScope(Scope):

    class Meta:
        name = 'locoteams'
        search_hint = 'Search LoCo Teams'
        search_on_blank = True
        lens = 'community'
        categories = ['teams', 'news', 'events', 'meetings']

    def __init__(self, *args, **kargs):
        super(LocoTeamsScope, self).__init__(*args, **kargs)
        self._ltp = locodir.LocoDirectory()
        self.lpusername = None

        if os.path.exists(os.path.expanduser('~/.bazaar/bazaar.conf')):
            try:
                import configparser
            except ImportError:
                import ConfigParser as configparser

            bzrconf = configparser.ConfigParser()
            bzrconf.read(os.path.expanduser('~/.bazaar/bazaar.conf'))

            try:
                self.lpusername = bzrconf.get('DEFAULT', 'launchpad_username')
            except configparser.NoOptionError:
                pass

    def search(self, search, model, cancellable):


I left out the actual search code, because it’s rather long and most of it isn’t important when talking about Singlet itself.  Just like the Lens API, a Singlet Scope uses an inner Meta class for meta-data.  The most important fields here are the ‘lens’ and ‘categories’ variables.  The ‘lens’ tells Singlet the name of the lens your scope is for.  Singlet uses this to build DBus names and paths, and also to know where to install your scope.  The ‘categories’ list will let you define a result item’s category using a descriptive name, rather than an integer.


 model.append('http://loco.ubuntu.com/events/%s/%s/detail/' % (team['lp_name'], tevent['id']), team['mugshot_url'], self.lens.events, "text/html", tevent['name'], '%s\n%s' % (tevent['date_begin'], tevent['description']), '')

It’s important that the order of the categories in the Scope’s Meta matches the order of categories defined in the Lens you are targeting, since in the end it’s still just the position number that’s being passed back to the Dash.

After all this, I still had a little bit of time left in the day.  And what good is supporting external scopes if you only have one anyway?  So I spent 30 minutes creating another scope, one that will read from the Ubuntu Planet news feed:

The next step is to add some proper packaging to get these into the Ubuntu Software Center, but you impatient users can get them either from their respective bzr branches, or try the preliminary packages from the One Hundred Scopes PPA.

[1] Note that while lenses written for Singlet 0.1 will work in Singlet 0.2 on Precise, the reverse is not necessarily true.  Singlet 0.2, as well as lenses and scopes written for it, will not work on Oneiric.

Read more
Michael Hall

Back when I first started writing Unity lenses, I lamented the complexity required to get even the most basic Lens written and running.  I wrote in that post about wanting to hide all of that unnecessary complexity.  Well now I am happy to announce the first step towards that end: Singlet.

In optics, a “singlet” is a very simple lens.  Likewise, the Singlet project aims to produce simple Unity lenses.  Singlet targets opportunistic programmers who want to get search results into Unity with the least amount of work.  By providing a handful of Python meta classes and base classes, Singlet lets you write a basic lens with a minimal amount of fuss. It hides all of the boilerplate code necessary to interface with GObject and DBus, leaving the developer free to focus solely on the purpose of their lens.  With Singlet, the only thing a Lens author really needs to provide is a single search function.

Writing a Singlet

So what does a Singlet Lens look like?  Here is a sample of the most basic lens, which produced the screenshot above:

#! /usr/bin/python

from singlet.lens import SingleScopeLens, IconViewCategory, ListViewCategory
from singlet.utils import run_lens

class TestLens(SingleScopeLens):

    class Meta:
        name = 'test'

    cat1 = IconViewCategory("Cat One", "stock_yet")

    cat2 = ListViewCategory("Cat Two", "hint")

    def search(self, phrase, results):
        results.append('http://google.com/search?q=%s' % phrase,
                             'file',
                             self.cat1,
                             "text/html",
                             phrase, phrase, '')

        results.append('http://google.com/search?q=%s' % phrase,
                             'file',
                             self.cat2,
                             "text/html",
                             phrase, phrase, '')

if __name__ == "__main__":
    import sys
    run_lens(TestLens, sys.argv)

As you can see, there isn’t much to it.  SingleScopeLens is the first base class provided by Singlet.  It creates an inner-scope for you, and connects it to the DBus events for handling a user’s search events.  The three things you need to do, as a Lens author, is give it a name in the Meta  class, define at least one Category, and most importantly implement your custom search(self, phrase, results) method.

Going Meta

Django developers will notice a similarity between Singlet Lenses and Django Models in their use of an inner Meta class.  In fact, they work exactly the same way, though with different properties.  At a minimum, you will need to provide a name for your lens.  Everything else can either use default values, or will be extrapolated from the name.  Everything in your Meta class, plus defaults and generated values, will be accessible in <your_class>._meta later on.

Categorically easy

Again borrowing from Django Models, you add categories to your Singlet Lens by defining it in the Class’s scope itself, rather than in the  __init__ method.  One thing that I didn’t like about Categories when writing my previous lenses was that I couldn’t reference them when adding search results to the result model.  Instead you have to give the numeric index of the category.  In Singlet, the variable name you used when defining the category is converted to the numeric index for that category, so you easily reference it again when building your search results.  But don’t worry, you category objects are still available to you in <your_class>._meta.categories if you want them.

The search is on

The core functionality of a Lens is the search.  So it makes sense that the majority of your work should happen here.  Singlet will call your search method, passing in the current search phrase and an empty results model.  From there, it’s up to you to collect data from whatever source you are targeting, and start populating that results model.

You can handle the URI

Unity knows how to handle common URIs in your results, such as file:// and http:// uris.  But often times your lens isn’t going to be dealing with results that map directly to a file or website.  For those cases, you need to hook into DBus again to handle the URI of a selected result item, and return a specifically constructed GObject response.  With Singlet, all you need to do is define a handle_uri method on your Lens, and it will take care of hooking it into DBus for you.  Singlet also provides a couple of helper methods for your return value, either hide_dash_response to hide the dash after you’ve handled the URI, or update_dash_response if you want to leave it open.

Make it go

Once you’ve defined your lens, you need to be able to initialize it and run it, again using a combination of DBus and GObject.  Singlet hides all of this behind the run_lens function in singlet.utils, which you should call at the bottom of your lens file as shown in the above snippet.

Lord of the files

There’s more to getting your Lens working that just the code, you also need to specify a .lens file describing your lens to Unity, and a .service file telling dbus about it.  Singlet helps you out here too, by providing command line helpers for generating and installing these files.  Suppose the code snippet above was in a file called testlens.py, once it’s written you can run “python testlens.py make” and it will write test.lens and unity-test-lens.service into your current directory.  The data in these files comes from <your_lens>._meta, including the name, dbus information, description and icon.  After running make you can run “sudo python testlens.py install”, this will copy your code and config files to where they need to be for Unity to pick them up and run them.

More to come

You can get the current Singlet code by branching lp:singlet.  I will be working on getting it built and available via PyPi and a PPA in the near future, but for now just having it on your PYTHONPATH is enough to get started using it.  Just be aware that if you make/install a Singlet lens, you need to make the Singlet package available on Unity’s PYTHONPATH as well or it won’t be able to run.  I’ve already converted my Dictionary Lens to use Singlet, and will work on others while I grow the collection of Singlet base classes.  If anybody has a common yet simple use case they would like me to target, please leave a description in the comments.

Read more