» tagged pages
» logout
GNOME
Return to GNOME

Planet GNOME

(or Cancel)

(Editing anonymously: to be credited for your changes, login or register a new account)

other page actions:

Tags Applied to this Topic

1 person has tagged this page:

Planet GNOME is a window into the world, work and lives of GNOME hackers and contributors.

Friday, July 25, 2008

Havoc Pennington: TV Computer Update

Still looking for my perfect TV computer. Thanks to everyone for suggestions so far, I really appreciate it. Several people expressed interest in hearing any answers, so I'll keep posting what I learn.

Ideas suggested so far:

None of these are quite there for me yet. I do want an actual computer, not an appliance/"thin-client"; I don't have another computer free to be the server, and none of the appliances support all the video sites and formats we use. I'd also like some future safety. I don't even own any Blu-Ray DVDs right now, but this thing should last a few years, and who knows what new video services will come out over the next 5 years. (We canceled cable in favor of "a la carte" purchases online or in DVD form, so we don't need cable cards, tuners, or DVR functionality.)

Right now we're attaching my laptop to the TV and using the clever diNovo Mini as a remote. But I want to free up the laptop. (That's the bottom line objective here, get my laptop back.)

Any type of fan is probably a showstopper. I was almost willing to live with the Mac Mini fan since it is somewhat quiet, but the Mac Mini has a slow GPU in it. While a very quiet fan might be OK, my experience with supposedly quiet fans is that they aren't quiet enough, especially under CPU load, and especially after a year or two of wearing out. For my developer workstation I bought all the special quiet parts, and it's indeed very quiet while I type this, but the fan spins up if the CPU is under load... for example while watching video.

In short, fans are risky.

One thing I haven't investigated: just get a laptop. But I bet that's expensive-ish.

There are many good options if cost is not a factor; such as Hush, A-Tech Fabrication, mCubed, or Niveus. These are all great except they are very expensive. I'm willing to pay extra for something good, but a thousand dollars extra is too much.

I believe there's probably a solution involving the Intel DG45FC or a similar board, a slow/cheap/low-power CPU (perhaps a single-core Celeron - that could be slower than necessary even), a fanless case, a fanless CPU heatsink of some kind, and a quiet/low-power 2.5-inch notebook drive.

But, there's no way to know whether a given pile of parts will snap together and not catch on fire.

  • Fanless CPU heatsinks are huge, and cases that hold mini-ITX boards don't look big enough to fit them inside.
  • Even if they fit, fanless CPU heatsinks are probably intended to go in roomy cases with fans, not fanless mini-ITX cases.
  • No doubt if I wait long enough there will be something prebuilt available. I am tempted to try the Intel board though. Maybe I can cut a hole in the case for the heatsink ;-)

    Friday, July 25, 2008

    Jono Bacon: On Governance

    One of the primary functions of a community manager is to put governance in place where it is appropriate to help your community run effectively. Governance is a funny ā€˜ol word though, and everyone has their interpretation of what exactly it means, to what extent it should be used and how required it is. Like any kind of community work though, there is no hard and fast rulebook about how things work - good judgement is the best method of determining exactly how your community should be governed.

    The problem is that that bad governance can really bugger up a community. The concept of governance itself is to put in place processes and rules that are universally understood and accepted by the community in an effort to establish a semblance of control and guidance of the community and its growth. Get it right and your community feels well run, not restricted by bottlenecks and effective to growth. Get it wrong and it feels like a bleedin’ great ship that is impossible to turn around.

    The problem is that governance can very quickly turn into bureaucracy if you are not carefull. Bureaucracy is simply governance that refuses to change, despite a better method of governance becoming available. If you put rules in place and refuse to change them because they are the rules, your community gets bound in red tape and will heartily suck for all involved.

    Again, it all really comes down to common sense and a measured approach. A few things to bear in mind when considering the formation of constitutions, councils, mandates and other governance hop-scotch:

    • Not every community needs a council.
    • Setting up a council for the sake of having a council is a bad idea. Having a council does not make your community look any better, more mature or better equipped to do its work.
    • Before setting up a council, justify its existence. Justify what problems it will solve and what it seeks to achieve.
    • Always regularly re-assess the processes and effectiveness of your governance. Things change, community change, people change…and so will the effectiveness of your governance.

    Also, one final note. One of the most wonderful elements of Open Source is the diversity of people it brings along. However, Open Source also has its fair share of Civil Servants who get a kick out of councils, constitutions, boards, elections and what-not. While these people can be useful, and many have the right intentions and balance, beware those who believe that governance is important just for the sake of having governance - invariably this can result in Civil Servant death-matches where there is a fight for power, and the real people who actually care about doing interesting work in the community just get to sit there and watch a pointless power struggle. The best governance is invisible - it just exists and helps cool people to do cool things.

    Just my 0.2c.

    Friday, July 25, 2008

    James Cape: Phrases

    One phrase that I never want to hear again, ever: ā€œSpeaking Truth To Powerā€ No, seriously, way to make the act of dissent played out.

    Friday, July 25, 2008

    Lennart Poettering: String Pools

    In part 2.4.3 of Ulrich Drepper's excellent How To Write Shared Libraries (which unfortunately is a bit out-of-date these days) Ulrich suggests replacing arrays of constant strings by a single concatenated string plus an index lookup table, to avoid unnecessary relocations during startup of ELF programs. Maintaining this string pool is however troublesome, it is hard to read and difficult to edit. In appendix B Ulrich lists an example C excerpt which contains some code for simplifying the maintaining of such strings pools, after an idea from Bruno Haible. In my opinion however that suggestion is not that much simpler, and requires splitting off the actual strings into a seperate source file. Ugly!

    Some Free Software uses string pools to speed up relocation, e.g. GTK+. Some development tools like gperf contain support for string pools.

    All solutions for string pool maintaining I could find on the Internet were not exactly beautiful. Either they were completely manual, manual plus a validity checking tool, or very very cumbersome. Googling around I was unable to find a satisfactory tool for this purpose[1].

    After Diego Petteno complained about my heavy use of arrays of constant strings in libatasmart I sat down to change the situation, and wrote strpool.c, a simple parser for a very, very minimal subset of C, written in plain ANSI C. It looks for two special comment markers /* %STRINGPOOLSTART% */ and /* %STRINGPOOLSTOP% */, moves all immediate strings between those markers into a common string pool and rewrites the input with the strings replaced by indexes. Code accessing those strings must use the special _P() macro. With these minimal changes to a source file, passing it through strpool.c will automatically rewrite it to a string-poolized version. The nice thing about this is that the necessary changes in the source are minimal, and the code stays compilable with and without passing it through the strpool.c preprocessor.

    Here's an example. First the original non-string-poolized version:

    static const char* const table[] = {
    	"waldo",
    	"uxknurz",
    	"foobar",
    	"fubar"
    };
    static int main(int argc, char* argv[]) { printf("%s\n", table[2]); return 1; }

    For later use with strpool.c we change this like this:

    #ifndef STRPOOL
    #define _P(x) x
    #endif
    /* %STRINGPOOLSTART% */ static const char* const table[] = { "waldo", "uxknurz", "foobar", "fubar" }; /* %STRINGPOOLSTOP% */
    static int main(int argc, char* argv[]) { printf("%s\n", _P(table[2])); return 1; }

    When passed through strpool.c this will be rewritten as:

    /* Saved 3 relocations, saved 0 strings (0 b) due to suffix compression. */
    static const char _strpool_[] =
    	"waldo\0"
    	"uxknurz\0"
    	"foobar\0"
    	"fubar\0";
    #ifndef STRPOOL
    #define STRPOOL
    #endif
    #ifndef _P
    #define _P(x) (_strpool_ + ((x) - (const char*) 1))
    #endif
    #ifndef STRPOOL #define _P(x) x #endif
    /* %STRINGPOOLSTART% */ static const char* const table[] = { ((const char*) 1), ((const char*) 7), ((const char*) 15), ((const char*) 22) }; /* %STRINGPOOLSTOP% */
    static int main(int argc, char* argv[]) { printf("%s\n", _P(table[2])); return 1; }

    All three versions can be compiled directly with gcc. However, the version that was passed through strpool.c compresses the number of relocations for the table array from 4 to 1. Which isn't much of a difference, but the larger your tables are the more relevant the difference in the number of necessary relocations gets.

    A more realistic example is atasmart.c which after being preprocessed with strpool.c looks like this. In this specific example the number of necessary startup relocations goes down from > 100 to 9.

    I am note sure if the parser is 100% correct, but it works fine with all sources I tried. It even does suffix compression like gcc does for normal strings too.

    Footnotes

    [1] Or maybe I just suck in googling? Anyone has a suggestion for such a tool?

    Friday, July 25, 2008

    Jordi Mallach: Cinema de Barri in Benimaclet

    Last summer we tried to organise a Cinema d'estiu movie projections in Benimaclet's Church Square, in an attempt to promote social activities in the street done by the neighbours, for the neighbours. The response was very positive, and the first two projections attracted many people, who would bring a chair and their dinner to the old town's square to watch a movie. Unfortunately, the authorities, who were completely out of the loop, weren't happy and on the 3rd week the Local police appeared and said that that kind of activities needed official permits, and disallowed the projection.

    For this year's summer, we decided we'd try to do the projections once again, and learned that only a legally-established organisation can do the paperwork to get an authorisation. In parallel, some neighbours of Benimaclet, who had liked last year's idea, were working on their own to repeat the experience, and somehow Clara was contacted by them, and we ended up collaborating. As these people are members of the Associació de veïns of Benimaclet, there were legally able to do the paperwork, and soon we agreed on the four movies for this year, to be played every Sunday of July at 22:00h.

    Our pick for Sunday 6th was Giuseppe Tornatore's Cinema Paradiso, followed on the 13th by Elling, a Norwegian comical drama by Petter NƦss which I hadn't seen and I can totally recommend. Last week we saw Poniente, a Spanish film by Chus GutiƩrrez that focus on immigration issues in the South East of Spain, based on the racist happenings of El Ejido of 2000. Finally, next Sunday is the turn for some political action with V for Vendetta. A note for Benimaclet neighbours: if you don't come to see the movie, be aware that we plan to pump up the volume a lot for this one. You're definitely going to hear it from home. ;)

    We're very happy about the response of the neighbours this year. Not having done any effort to announce this around the city, except for a few posters around Benimaclet during the last week of June, people clearly remembered last year's experience and the plaƧa de Beni was full of chairs for all three weekends. It really helps to turn around during a projection and see so many people behind you participating in something you've invested some of your own time and money. It's probably too late now, but there's some talk of extending this to the Sundays in August, so we'll see. Also, we plan to do a picaeta for attendees as a small closing party for this year's cycle.

    See you on Sunday, and enjoy V!

    Friday, July 25, 2008

    Jordi Mallach: GNOME-Mud 0.11

    GNOME-Mud 0.11 was released yesterday. This was probably something unexpected to those who follow the mailing list, as it's the first release in over three years.

    Back in 2006, Les Harris started contributing to the project and started a major rewrite of the program. Things looked very promising, with the program being ported to newer GNOME technologies and standards and being basically rewritten from ground up. However, Les got hit by Real Lifeā„¢ and being the project's only real hacker, development basically stopped for nearly two years. On June, I was tempted to remove my irssi subscription to #gnome-mud; all I did was idling or telling people who popped by that nothing was being done and that wouldn't change unless someone rolled up their sleeves and finished up the nearly ready 0.11 release.

    A few days after considering declaring GNOME-Mud dead, Les joined IRC after more than a year of no contact, recovered his GNOME account password and started to commit the missing bits at an awesome pace.

    A few weeks later, 0.11 was done, with even more features than originally planned (support for more advanced MUD protocols like MSP or ZMP, for example) and I finally found the time to make a tarball and publish it. Les has lots of plans for the next release, and I hope my old wish of seeing GNOME-Mud becoming a MUD client that is comparable to the classic zMud will soon be a lot closer. The foundation set by this release certainly will make it easier to accomplish.

    As always, if you want to contribute, we'll be happy to help you out on #gnome-mud at GIMPnet, or in gnome-mud-list@gnome.org.

    Friday, July 25, 2008

    Matthew Garrett: 25 Jul 2008

    Linux hasn't claimed to be Linux in response to OSI queries since 2.6.24, so this is an interesting sidenote but basically irrelevant.

    Friday, July 25, 2008

    Christian Schaller: Back from Turkey

    So a little later than ā€˜everybody else’ I am now back from Turkey. Wim and I had both decided we needed some vacation and since we where going to Turkey for GUADEC it would be a great opportunity for us to travel around and see the area. Our original plan included climbing Mount Arrarat and visiting Georgia and Armenia, but trouble getting climbing permit combined with some german tourists getting kidnapped on Mount Arrarat by Kurd sepratists got us to adjust our plans. We ended up instead travelling down to cities such as Urfa (Edessa) and Harran, spending some days in Cappadocia and finally visiting Pamukkale and Ephesos. Had a blast of a time although Wim seemed a little less enthusiastic about females of the Korean and Taiwanese variety than me. Could of course just be that ā€˜Hello Kitty’ panties fail to get his sap boiling )

    For anyone travelling to Turkey I think spending 2-3 days in Gƶreme is an absolute must. It is a charming backpacker town with a lot of the hotels carved out of volcanic rock. A little gimmicky in the sense that the locals no longer live in the rocks for the most part, but the area is something which just have to be experienced.

    Although we enjoyed the food I think it is safe to say that neither myself or Wim will be eating salad with cucumber and tomato, sprinkled with a little lemon anytime soon. 10+ days in a row is enough for a while )

    One thing I started wondering about while travelling around was the enormous expectations by local people for what an EU membership would mean for the people of Turkey, ranging from the EU solving all minority rights issues for Kurds, Armenians and Alavis, west European living standards and salaries for everyone, to solidifying Turkeys secular traditions. While the EU will for certain help push Turkey in the right direction on these issues, I can’t help but wonder if a future EU membership for Turkey might end up being a big lettdown compared to the expectation level I experienced.

    Friday, July 25, 2008

    Abderrahim Kitouni: first release of the Vala plugin for Anjuta

    I'm pleased to announce the first release of my Anjuta plugin featuring code completion for Vala.

    You can get a tarball from here. You'll also need a patched version of vala : GCompletion binding, public Vala.Scope.symbol_table (maybe should be read only, there is also another small change that removes a warning), better source_reference for Vala.Block and support for error reporting in anjuta ui (not included in the plugin). (I'll bug Jürg later to include them.
    The plugin compiles with a dozen warnings (about ignored errors) so don't worry about it.
    to compile : make && make install, it needs to install in the same prefix as Anjuta, so you may need to install as root.

    If you have any suggestions, bug reports or other feedback, don't hesitate. Meanwhile, I'll be working on call tips.

    Friday, July 25, 2008

    Henri Bergius: Hello Planet GNOME

    Hi, all! My blog's desktop feed has recently been added to Planet GNOME, and so here is a quick introduction:

    My name is Henri Bergius and I am a free software hacker focused on things like the Midgard framework and some location-aware applications for desktop and mobile. I work at Nemein, a small Finnish CMS consultancy building stuff on top of Midgard. I'm quite interested in emerging web standards like microformats, GeoRSS, attention profiling, and in building free maps.

    I've been a fan of the GNOME project since the early beta days, and while I currently mostly work on Mac, I still keep following the project actively. I've a speaker in four GUADECs, starting with a presentation about Open Source CMS in Dublin, and followed with geo-focused presentations in Vilanova, Birmingham and Istanbul. As a member of COSS steering group, I was also one of the people behind the (unfortunately unsuccessful) Tampere GUADEC+aKademy bid.

    Here is my new hackergotchi:

    Bergie's Hackergotchi

    And yes, I am a former viking who happens to like ice cream.

    Friday, July 25, 2008

    Christian Hammond: Django Development with Djblets: Data Grids

    Table of contents for Django Development with Djblets

    1. Django Development with Djblets
    2. Django Development with Djblets: Custom Tag Helpers
    3. Django Development with Djblets: Unrooting your URLs
    4. Django Development with Djblets: Data Grids

    It’s been a while since my last post in this series, but this one’s a good one.

    A common task in many web applications is to display a grid of data, such as rows from a database. Think the Inbox from GMail, the model lists from the Django administration interface, or the Dashboard from Review Board. It’s not too hard to write something that displays a grid by doing something like:

    <table>
     <tr>
      <th>Username</th>
      <th>First Name</th>
      <th>Last Name</th>
     </tr>
    {% for user in users %}
     <tr>
      <td>{{user.username}}</td>
      <td>{{user.first_name}}</td>
      <td>{{user.last_name}}</td>
     </tr>
    {% endfor %}
    </table>

    This works fine, so long as you don’t want anything fancy, like sortable columns, reorderable columns, or the ability to let users specify which columns they want to see. This requires something a bit more complex.

    djblets.datagrids

    We wrote a nifty little set of classes for making data grids easy. Let’s take the above example and convert it over.

    # myapp/datagrids.py
    from django.contrib.auth.models import User
    from djblets.datagrid.grids import Column, DataGrid
    Ā 
    class UserDataGrid(DataGrid):
        username = Column("Username", sortable=True)
        first_name = Column("First Name", sortable=True)
        last_name = Column("Last Name", sortable=True)
    Ā 
        def __init__(self, request):
            DataGrid.__init__(self, request, User.objects.filter(is_active=True), "Users")
            self.default_sort = ['username']
            self.default_columns = ['username', 'first_name', 'last_name']
    # myapp/views.py
    from myapp.datagrids import UserDataGrid
    Ā 
    def user_list(request, template_name='myapp/datagrid.html'):
        return UserDataGrid(request).render_to_response(template_name)

    Now while this may look a bit more verbose, it offers many benefits in return. First off, users will be able to reorder the columns how they like and choose which columns to see. You could extend the above DataGrid to add some new column but leave it out of default_columns so that only users who really care about it would see it.

    Custom columns

    Let’s take this a step further. Say we want our users datagrid to optionally show staff members with a special badge. This might be useful to some users, but not all, so we’ll leave it out by default. We can implement this by creating a custom column with image data:

    class StaffBadgeColumn(Column):
        def __init__(self, *args, **kwargs):
            Column.__init__(self, *args, **kwargs)
    Ā 
            # These define what will appear in the column list menu.
            self.image_url = settings.MEDIA_URL + "images/staff_badge.png"
            self.image_width = 16
            self.image_height = 16
            self.image_alt = "Staff"
    Ā 
            # Give the entry in the columns list menu a name.
            self.detailed_label = "Staff"
    Ā 
            # Take up as little space as possible.
            self.shrink = True
    Ā 
        def render_data(self, user):
            if user.is_staff:
                return '<img src="%s" width="%s" height="%s" alt="%s" />' % \
                    (self.image_url, self.image_width, self.image_height, self.image_alt)
    Ā 
            return ""
    Ā 
    class UserDataGrid(DataGrid):
        ...
        staff_badge = StaffBadgeColumn()
        ...

    This will add a new entry to the datagrid’s column customization menu showing the staff badge with a label saying ā€œStaff.ā€ If users enable this column, their datagrid will update to show an staff icon for any users who are marked as staff.

    Custom columns can render data in a couple of different ways.

    The first is to bind the column to a field in the model. By default, a Column instance added to a DataGrid will use its own name (such as ā€œfirst_nameā€ above) as a lookup in the object. If you want to use a custom field, set the db_field attribute on the column. This field can span relationships as well. For example:

    class UserDataGrid(DataGrid):
        ...
        # Uses the field name as the lookup.
        username = Column("Username")
    Ā 
        # Spans relationships, looking up the age in the profile.
        age = Column("profile__age")

    The second is the way shown above, by overriding the render_data function. This takes an object, which is the object the datagrid represents, and outputs HTML. The logic in this can be quite complicated, depending on what’s needed.

    Linking to objects

    A datagrid is pretty worthless if you can’t link entries for the object to a URL. We have a couple of ways to do this.

    To link a column on a datagrid to a URL, set the link parameter on the DataGrid to True. By default, the URL used will be the result of calling get_absolute_url() on the object represented by the datagrid, but you can override this:

    # myapp/datagrids.py
    Ā 
    class UserDataGrid(DataGrid):
        username = Column("Username", sortable=True, link=True)
        ...
        @staticmethod
        def link_to_object(user, value):
            return "/users/%s/" % user

    Then

    link_to_object takes an object and a value. The object is the object being represented by the datagrid, and the value is the rendered data in the cell. The result is a valid path or URL. In the above example, we’re explicitly defining a path, but we could use Django’s reverse function.

    Usually the value is ignored, but it can be useful. Imagine that your Column represents a field that is a ForeignKey of an object. The contents of the cell is the string version of that object (implemented by the __str__ or __unicode__ function), but it’s just an object and you want to link to it. This is where value comes in handy, as instead of being HTML output, it’s actually an object you can link to.

    If you intend to link a particular column to value.get_absolute_url(), we provide a handy utility function called link_to_value which exists as a static method on the DataGrid. You can pass it (or any function) to the Column’s constructor using the link_func parameter.

    class UserDataGrid(DataGrid):
        ...
        myobj = Column(link=True, link_func=link_to_value)

    Custom columns can hard-code their own link function by explicitly setting these values in the constructor.

    Saving column settings

    If a user customizes his column settings by adding/removing columns or rearranging them, he probably expects to see his customizations the next time he visits the page. DataGrids can automatically save these settings in the user’s profile, if the application supports it. Handling this is as simple as adding some fields to the app’s Profile model and setting a couple options in the DataGrid. For example:

    # myapp/models.py
    Ā 
    class Profile(models.Model):
        user = models.ForeignKey(User, unique=True)
    Ā 
        # Sort settings. One per datagrid type.
        sort_user_columns = models.CharField(max_length=256, blank=True)
    Ā 
        # Column settings. One per datagrid type.
        user_columns = models.CharField(max_length=256, blank=True)
    # myapp/datagrids.py
    Ā 
    class UserDataGrid(DataGrid):
        ...
        def __init__(self, request):
            self.profile_sort_field = "sort_user_columns"
            self.profile_columns_field = "user_columns"

    The DataGrid code will handle all the loading and saving of customizations in the Profile. Easy, isn’t it?

    Requirements and compatibility

    Right now, datagrids require both the Yahoo! UI Library and either yui-ext (which is hard to find now) or its replacement, ExtJS.

    Review Board, which Djblets was mainly developed for, still relies on yui-ext instead of ExtJS, so datagrids today by default are built with that in mind. However, the JavaScript portion of datagrids should work with ExtJS today. The default template for rendering the datagrids (located in djblets/datagrids/templates/datagrids/) assumes both YUI and yui-ext are present in the media path, but sites using datagrids are encouraged to provide their own template to reflect the actual locations and libraries used.

    We would like to work with more JavaScript libraries, so if anyone wants to provide an implementation for their favorite library or help to dumb down our implementation to work with any and all, we’d welcome patches.

    See it in action

    We make extensive use of datagrids on Review Board. You can get a sense of it and play around by looking at the users list and the dashboard (which requires an account).

    That’s it for now!

    There’s more to datagrids than what I’ve covered here, but this should give you a good understanding of how they work. Later on I’d like to do a more in-depth article on how datagrids work and some more advanced use cases for them.

    For now, take a look at the source code and Review Board’s datagrids for some real-world examples.

    Friday, July 25, 2008

    John Carr: The blinding past

    I lolled so hard. Thanks Rob.

    Friday, July 25, 2008

    John Carr: Syncing my phone, its actually easy

    A few days ago, I saw a blog post highlighting how difficult it can be to sync a phone on the free desktop. For a battle hardened command line user, the steps aren’t that troubling (although that example looks easy compared to some of the setups i’ve seen). Regardless, I certainly wouldn’t want to put my parents through this experience.

    In contrast, after a recent mishap with my phone, restoring its address book from Evolution was trivial with the copy of Conduit SVN I had kicking around.
    Conduit and WM6

    I started Conduit and plugged in my phone. It appeared on the left hand side of the screen, so I dragged it and the Evolution endpoints to the canvas, and I did a sync. My address book is back.

    There is more UI love to go of course. SynCE automagicness is getting there, but we can make it even better. Plus, we love HAL, and the next step is to respond to new devices and say ā€œHey, I know how to deal with that thingy you just plugged inā€ and offer to sync to some sensible defaults (Evolution for PIM stuff, Tomboy for Notes, F-Spot for Photos, Banshee/Rhythmbox for Music). And of course, the next time I plug it in.. Just sync it. Never make me press the sync button again.

    The blinding future is to use PackageKit to download extra support packages like SynCE and libgpod as needed, when you plug in the device.

    Friday, July 25, 2008

    Christian Hammond: Django Tips: PIL, ImageField and Unit Tests

    Table of contents for Django Tips

    1. Django Tips: PIL, ImageField and Unit Tests

    I recently spent a few days trying to track down a bug in Review Board with our unit tests. Basically, unit tests involving uploading a file to a models.ImageField would fail with a validation error specifying that the file wasn’t an image. This worked fine when actually using the application, just not during unit tests.

    The following code would cause this problem. (Note that this isn’t actual code, just a demonstration.)

    # myapp/models.py
    from django.db import models
    Ā 
    class MyModel(models.Model):
        image = models.ImageField()
    # myapp/forms.py
    from django import forms
    from myapp.models import MyModel
    Ā 
    class UploadImageForm(forms.Form):
        image_path = forms.ImageField(required=True)
    Ā 
        def create(self, file):
            mymodel = MyModel()
            mymodel.save_image_file(file.name, file, save=True)
            return mymodel
    # myapp/views.py
    from myapp.forms import UploadImageForm
    Ā 
    def upload(request):
        form = UploadImageForm(request.POST, request.FILES)
    Ā 
        if not form.is_valid():
            # Return some error
            pass
    Ā 
        # Return success
    # myapp/tests.py
    from django.test import TestCase
    Ā 
    class MyTests(TestCase):
        def testImageUpload(self):
            f = open("testdata/image.png", "r")
            resp = self.client.post("/upload/", {
                'image_path': f,
            })
            f.close()

    After a good many hours going through the Django code, expecting there to be a problem with file handles becoming invalidated or the read position not being reset to the beginning of the file, I finally decided to look at PIL, the Python Imaging Library. It turns out that at this point, due to some weirdness with unit tests, PIL hadn’t populated its known list of file formats. All it knew was BMP, and so my perfectly fine PNG file didn’t work.

    The solution? Be sure to import PIL and call init() before the unit tests begin. If you have a custom runner (as we do), then putting it in here is appropriate. Just add the following:

    from PIL import Image
    Image.init()

    Hopefully this helps someone else with the problems I’ve dealt with the past few days.

    Friday, July 25, 2008

    Alex Graveley: @orph for 2008-07-24

    Trying out the WordPress Twitter Tools Plugin. Anyone know a better way to import Tweets into WordPress as blog posts?

    • Flirtig with 20 year olds on the beach is fun until we exchange ages and I realize there’s no longer a chance for romance. #
    • @hancher I like what I’ve seen so far. Not sure how it’s different from other expert sites like ask.com. #
    • Face of love lost haunting my dreams. #
    • Killer thunderstorms here seem fitting. #
    • @swiftrhett welcome to twitter! #
    • Damn. I want GNU Go ported to iPhone *right now*. #
    • @sandyarmstrong if there’s content selected to be used in a new note, I think it’s fine to use it as the title. Nice fruitful thread! #

    Thursday, July 24, 2008

    Mukund Sivaraman: New Banu logo

    Hylke Bons drew a new logo for Banu yesterday. I had requested him for a cuddly brown bear, and adapting Linus's words for Tux, said the bear should look contented and happy, as if it's just had a lot of honey :) Hylke replied within 2 hours with this logo image which is the sweetest bear I've ever seen. It even seems to be hiding a jar of honey behind it :) It's amazing he created it in so little time. Thank you Hylke!

    Banu logo

    Thursday, July 24, 2008

    Jeff Waugh: Power Boards

    You could probably power a small island with all of these. Oh wait, we are! A rather large number of our favourite iconic green laptops will be charging on these surge-protected power boards very soon. -)

    Pia will land in Niue next week, as one member of an elite team tasked with kickstarting the world’s first 100% saturation deployment of OLPCs. Of course, it helps that Niue is a tiny island nation in the middle of the Pacific!

    Thursday, July 24, 2008

    Marco Barisione: Back from GUADEC[1]


    Doesn’t this look like the GUADEC t-shirt?

    GUADEC was great and talks turned out to be more interesting than what I was expecting after all the decadence discussions, this is also proved by the fact that I managed to stay awake during all the talks despite having a party every day ). Being in an awesome city with wonderful food[2] helped a lot for the final result, this is why I’m so happy that Gran Canaria was chosen for the next GUADEC.

    In Istanbul I finally met other people working on WebKit or on related projects and had a chance to discuss with them about the future development of WebKit. While meetings on IRC are useful and allow you to talk with people from everywhere, real life meetings give you a much more efficient channel of communication: how about a hackfest for people working on WebKit, FireFox and desktop programs using them?

    [1] Actually I came back to Cambridge ten days ago but, as usual, I fail at writing blog posts at the right moment, I wanted to write this on Sunday but my flight was moved to Monday and then real life started again. [Insert here other childish excuses for being so lazy]
    [2] I’m already experimenting some Turkish recipes, Collabora people in Cambridge should expect a Turkish dinner really soon.

    Thursday, July 24, 2008

    John Palmieri: Interesting news out of the Intel camp

    It seems that Moblin will be switching from Ubuntu to Fedora Linux as their base operating system.Ā  I’m interested in finding out the underlying reasoning for such a move.Ā  The stated reason is because they wanted to use RPM instead of DEB.Ā  I can’t quite buy that but perhaps that is because having come from both camps I think that packaging is an implementation detail that too many people put way too much stock in.Ā  This has the effect of causing unnecessary emotional splits within the community resulting in animosity which often overshadows real threats.

    The second reason given, which has to do with building a community is pretty broad but more believable.Ā  Fedora has made huge strides while also sticking to its guns in the freedom department and being valuable upstream contributors. It may be that we sacrificed short term gains which can be gotten via a bit more differentiation, or out of the box ā€œjust worksā€ on closed hardware but as companies are being convinced to open up their specs and open drivers are being written, a large portion of which is being done by Fedora developers working upstream, little of the short term gains matter much.

    I suspect the real reason is somewhere in the community vein, staring with the Kernel and X team developers who work tirelessly making sure their work is fit for upstream consumption and can be supported in the long term. Following their lead the rest falls naturally out of that single notion of moving Linux forward as a whole. Kudo’s to all my Fedora friends - keep moving forward.

    [read this post in: ar de es fr it ja ko pt ru zh-CN ]

    Thursday, July 24, 2008

    David Bolter: Scratch-ing an Itch

    I gave a talk a few hours ago at the inaugural Scratch conference at the MIT Media Lab. Having first used Scratch last week, and leaving for the airport at 4am this morning I found myself reflecting...

    What am I doing?

    The title of the talk is "Scratching All Itches Equally" and originally listed Gregory Rosmaita, Liddy Nevile, and Jutta Treviranus as speakers. Gregory and Jutta couldn't make it so I was asked to jump in.

    Here is the description in the program guide:
    A discussion of strategies for ensuring that Scratch is usable by all, whether one can see the screen, or use a pointing device or an on-screen keyboard. The goal of the panel is to discuss Scratch’s architectural framework to ensure that it is capable of communicating with operating system accessibility APIs, as well as platform-agnostic APIs, such as IAccessible2 and ATK/AT-SPI (Assistive ToolKit/Assistive Technology Service Provider Interface).

    Liddy and I realized that the audience was going to be made up mostly of teachers so we decided to turn the talk into less of an engineering discussion, and more of a brainstorm. We framed the storm in the context of Scratch, and accessibility, or disability in the wide definition.

    Over lunch, it was cool to hear people from our talk bringing up topics from our brainstorming to groups who hadn't attended.

    What interests me most about Scratch is that it is playful programming that kids (well, not just kids) can pick up rather accidentally in order create and express their ideas. It makes a lot of sense to me that this kind of tool should be made accessible to all children, regardless of culture, gender, or physics. When you only allow a subset of people to participate in creating and making, you lose some of the most valuable and insightful influences; you stagnate.

    Thanks for reading.
    Page 1 | Next >>
    Username:
    Password:
    (or Cancel)