Git is decentralised-by-design source control management. It is meant to be self-hosted and self-controlled. These are important properties inherent in all free and libre software. If you have a copy, you have the right to that copy. Not like when you purchase a compact disc with music, when you might own the piece of processed plastic and aluminum but not the content stored on it.

GitHub, on the other hand, is centralised. It runs proprietary source code on the back-end. Users may not copy GitHub in order to run it on their own infrastructure. If GitHub has an outage, every single user has to suffer through it all the same. If GitHub gets hacked, every single user on the disservice gets hacked. If GitHub goes bankrupt? Well, then every single user on that platform loses. As well as all the users of software hosted on GitHub.

Decentralisation is an integral part of a software project I’m involved with, GNU social, for which we use git for version control and development. We might as well have used something like Mercurial, but for all our intents and purposes they are equivalent. Both mainline implementations of Mercurial and Git are free, libre software and they both let developers work independently and then merge the differences in a relatively seamless manner. It just so happens that git was the choice of the StatusNet developers and we’ve kept using it. But the mainline repository has always been hosted along with issue tracking using libre software.

But developers, even FLOSS developers, seem to flock to GitHub. Developer-related websites with OAuth-enabled logins centralise to GitHub (instead of something truly federated like OpenID 1.0). Projects, even large-scale free software projects, leave self-hosting to instead embed themselves in the fabric of centralised, proprietary vendor lock-in. Python has decided to move to GitHub for example (leaving Mercurial for source control, but keeping their own issue tracking) – essentially with the argument “everyone is there and other alternatives didn’t have killer features” (forgetting that software freedom is the biggest feature of all!).

Now, you may argue, git is still decentralised. Absolutely, when GitHub goes badonkers and either starts with advertisement (as all proprietary gratis services seem to) you can just move the repository since you’ll still have your local copy (Right? You’re not working with some cloud-based service without keeping a local copy? RIGHT?!). I just don’t personally want to find myself trying to change all the URLs everywhere, trying to communicate to all developers and users how to find new copies and set up a new issue tracking system and move all the issues and all the accounts and all the other things I can’t even think of.

But the worst case scenario of lock-in is that people become used to it. GitHub will undoubtedly start doing something annoying. Maybe it’s not third-party advertisement, maybe it’s something more subtle. Maybe less subtle, like blastering some repositories’ administrator e-mail inboxes with “upgrade plans” or other things that can’t be clicked away. Maybe they’ll undevelop their API and require you to use their website instead of a desktop client – unless it’s their desktop client. And when this happens, and repository owners get annoyed, they can’t channel their contributors to other sites because “that’s too much work” (for both sides of the situation). Because “everyone” are on GitHub.

So, (slightly more than) another week has passed and GNU Social has received a couple of stability and feature updates. Nothing very visible for the end-user, but administrators may appreciate it. Going chronologically through the shortlog:

First I did some minor fixes, mostly language and specifications to make more clear that we’re working in the GNU Social software. This includes removing some StatusNet names here and there, specifying our system requirements (PHP5.3) and preferring a local url shortener to a remotely hosted one (privacy issue). The “8 chars was too little” apprehends queue handlers which in the future may use longer frame-identifiers (more declarative names).

One goal I have with code updates are making better use of OOP, object oriented programming. It results in prettier code, which is easier to read and harder to get wrong (what with proper typing and all that). One part in this was clearing up a remnant of old times, the ‘subs.php’, and implement the same functions in the Subscription class.

There were small problems during the execution of this patch, but it was fixed in the following commits. Among these fixes were the introduction of Managed_DataObject::listFind, which instead of an array returns the actual multiple matches in an extended DB_DataObject class.

Proper exception handling is also a neat thing. So I introduced the ‘MethodNotFoundException’ which is thrown whenever a class hasnot implemented a function. Usually that’s handled through abstract classes and class interfaces, but abstract declarations are apparently not allowed for static functions. So instead they throw the mentioned exception. Then there was also some regression and neatness fixing to do, where the regression was related to javascript functionality.

We now support PHP5.5, at least after the following series of patches. 5.5 makes sure that PHP is not a _pure_ steaming pile of dung anymore. So I had to clear up some old programming mistakes that didn’t convert types and shut down data streams properly.

In the middle of all of this, I took the chance to update some PHP libraries too because stuff like OpenID wasn’t PHP 5.5 compatible.

A problem regarding URL shortening I noticed – if allowed notice length is infinite, then we ALWAYS shorten links (because two config settings were compared, where ‘0’ meant entirely different things).

Some minor problems I managed to introduce earlier were fixed here. Also, I applied several patches by Joshua Judson Rosen (rozzin). Thank you for these (one year old) patches!

80c6af0 Uncaught exception when no subscribers/subscriptions in ProfileList
633191d Making sure scripts and tests check for GNUSOCIAL defined (instead of STATUSNET)
981295f Autocomplete action must exist on user registration
562d5bc Remove bad common_path() call in context of cssLink().
8e5d58f Make paging work correctly in the user-directory even with the default filter set (i.e.: `all' = `no filter', so intrepret `filter=all' as `no filter').
9844ec7 Make the ForceGroup plugin work consistently for notices from remote users.
9085880 Allow the hostmeta to indirect from one domain to another. e.g.: rozzin@hackerposse.com => rozzin@status.hackerposse.com.
8e53eb2 Correct a logic-inverting typo in handling of replies to group-posts. The typo causes a tautology, which makes replies to group-posts always (or almost-always) go to the group(s). cf. http://status.net/open-source/issues/3638
44f7ad6 Correctly distribute notices from remote posters through local groups to remote group-members via OStatus. Allow the OStatus queue-handler to handle all posts, and give it the smarts required to make correct decisions about whether it should or shouldn't relay notices over OStatus. cf. http://status.net/open-source/issues/3540

…and now to the big implementation of the week – WebFinger. GNU Social now properly supports, I believe, RFC7033. Plus of course the former RFC6415 (Web Host Metadata), which StatusNet supports (but only XRD format). GNU Social supports both with both JSON and XML resource descriptors (JRD and XRD). It was followed-up by some regression fixes which were caught rather quickly thanks to debugging with postblue who tracks the master branch.

What WebFinger does is simplify and standardise metadata retrieval for users, websites, devices etc. using unique URIs – such as acct:mmn@social.umeahackerspace.se or https://social.umeahackerspace.se/mmn. What we don’t do is make use of the ‘rel’ parameters. Yet.

This also removed the previously available StatusNet hack ‘xrd.php’, replacing it with the PEAR XML_XRD library. We could probably also use Net_WebFinger for lookups, but so far no one has contributed RFC7033-compatible changes to it. It means more lines of code, but less maintenance. Code reuse is awesome.

As a bonus, or rather instead of implementing Quitter’s API changes, I pushed some Avatar class fixes. These simplify a lot of the code, as can be seen in commit b0dfc70 which replaces multiple get-avatar-check-if-it-is-there-and-get-the-url-otherwise-get-the-default-avatar-url (+ I could get rid of Twitter-specific hacks that returned 73×73 sized avatars when they sometimes should’ve been 96×96 pixels).

And lastly, I just now fixed a problem with a new behaviour in lib/plugin.php where all the Plugin extended classes (i.e. all plugins) automatically load files from their directory if they match desired class names. During WebFinger updates I introduced (for the LRDD methods) a snippet of code that replaces ‘_’ with ‘/’ so we can have a better directory structure for plugins which act like the LRDD plugin.

Parent retrieval would of course not work until others also upgrade to GNU Social from StatusNet, or patch their installations with that specific functionality. However, considering the amount of broken conversations that comes with more federated users I think it’s very desirable.

Erkan recently asked for a roadmap of GNU Social development, but unfortunately I’m right now just going to give the next best thing – a summary of what’s been done the latest month. Starting after Evan’s currently last StatusNet commit at Tuesday July 16 2013, 2a70ed2: Merge branch '1.1.x', it was merged into the stone-age stuff of previous GNU Social code from 2010… and new development began. This is the story of our commits from 2013-08-12 to 2013-09-17.

First up, updating some libraries

I guess noone had dared touch the old piece of legacy PHP code that’s called “DB”, i.e. the ancient database abstraction layer StatusNet uses (and doesn’t really get used properly as there are many manual SQL queries in the code still). I didn’t dare do this either, but updates are always nice. So the first essential commit was updating the external library DB to its latest version:

7d8e199 Update to DB_DataObject 1.11.2

There was the idea to migrate everything to MDB2, which would still be able to handle the DataObject classes. However, since it still wouldn’t take care of the biggest problem – functions that are internally called by static methods but aren’t declared static – I figured it wasn’t worth the hassle. And the OpenID plugin supposedly would need lots of work… Anyway, if there’s anything we should do (besides drop PHP!) it’s to migrate over to PDO.

Long-standing merge requests

Then there was work to integrate some fixes from the list of merge requests and such which had not been taken into StatusNet master yet:

3ad3535 Merge commit 'refs/merge-requests/230' of git://gitorious.org/statusnet/mainline into merge-requests/230
ea837ce added missing return statement after showForm call
f433f7c if parameters are not 0, null then limit will be PROFILES_PER_PAGE
56cfd2b comparing a url scheme should be done case insensitively
1095f7a new plugin to check, store and migrate password hashes to crypt()
2e8b729 Issue 3636 request clarity for users without validated emails on instances with RequireValidatedEmail active
7eecd93 _m function for translation seems to be what we use
e47d9ad Added author name to modified file
d6cf6e8 letting the noticeform at the top show, to fix broken reply button javascript
bd60ab2 fix typo on provider_url
f11d157 visual presentation of group's homepage href was its local stream url
20bad68 Added SSL option to web and cli installers
38ac5a7 Automatic memcache support enabler for config
542f00f printf tries to evaluate "%" in paths, echo does not

This felt like a relief for me personally, having written some of those myself. Several other good people had submitted merge requests as well which were taken care of in this round. All the details are in the commit log.

One big problem for new users was also the extreme sluggishness that arises from such a huge, dynamic piece of software as StatusNet. So we automatically enabled Memcache detection if PHP has the module. It requires the administrator to run a local memcache server, but at least no further configuration has to be done after ‘apt-get install memcached’.

What makes GNU Social GNU Social?

And so it became time for a distinction that separates GNU Social from StatusNet somewhat. Something which bothered me in every fresh install I ever made, too:

794163c Default to NOT ask for current location for new users

Privacy. At least we shouldn’t stalk fresh users by asking them where they live everytime they try to post stuff! Another privacy change had already been made (20bad68 regarding SSL-on-install), but this was the first that would immediately affect user experience. SSL improvements were made later as well (commit 81a357e), where a site configured as SSL ‘sometimes’ would never redirect users to http://.

Major overhaul of dataobjects

In a couple of steps to reduce code redundancy and ease future migration to better DB abstraction layers, many of the following commits were directed at the ‘classes/’ directory, finally taking some of the dataobjects to inherit “Managed_DataObject”. Which means that everything from caching to specifying data structure becomes much easier not to say more flexible.

…and during this time the code was broken several times. Part of the fixes also included depending on PHP >= 5.3, which means we can rely on much better object orientation and snazzier functionality (such as late static binding). Unfortunately several problems still exist internally in the DB abstraction layer, where it calls its own non-statically defined functions with static methods. So the ‘PHP Strict Standards’ warning bells keep going off all the time – and still do even after all of the commits in this post.

One important thing that changed during these commits however was the Memcached/Managed_DataObject API, where instead of calling the DB_DataObject function staticGet (which wasn’t static!) it has been renamed getKV (for getKeyValue). Some other related data-fetching functions were also renamed and changed throughout the codebase.

Code reuse is a good thing, viva la OOP!

Then there was a big one. Standardising the way class files are autoloaded, which had already been kinda-maybe-half-made in previous StatusNet code, I went through a lot of the code for plugins and could remove tons of lines of code with statically assigned ‘include_once’ lines. Instead it is all generally handled in the Plugin parent class for the event onAutoload. Many files were moved and renamed in the course of this commit, as they all would fit the same pattern, which can be seen in lib/plugin.php.

de55d8f plugins onAutoload now only overloads if necessary (extlibs etc.)

And then some more cleanup and fixing

More merge requests and general fixes that had been noticed while digging around in the code were implemented.

And some new parent classes

When working on Free & Social, I rewrote some major parts of the code. A lot of it isn’t quite finished yet (like the theme engine migration), but many bits and pieces can be put back in to GNU Social. Like the fact that just about every Action where one interacts with a form can inherit, and standardise to, a ‘FormAction’ class:

As you can see I migrated a couple of actions as well, but many still need work. And an introduction of a SettingsAction parent class would also be very good!

Tidying up, cleaning and implementing merge request

Back to house cleaning. Some code improvements were made where little effort was needed. Strict typing is very important if one doesn’t enjoy headaches while reading and debugging code. So some of that was introduced (and a little bit more would come later):

747fe9d Tidying up getUser calls to profiles and some events
a9c4bcd Removing unnecessary require_once lines (autoload!)
99312c8 Declaring some more static functions properly
81a357e Putting in functionality so that sites with the "Sometimes" SSL setting allow for users with plugins such as HTTPSEVERYWHERE who wish to use HTTPS to do so without having errors pop up. Specifically this references this issue: http://status.net/open-source/issues/3855#comment-48988.
ade8c69 Twitter cards implementation. Currently only supports 'photo' cards.
f0d86cd Add 'twitter:title' meta tag support.

jbfavre’s Twitter updates were also implemented. I actually haven’t tested these, but jbfavre is a good person whom we can all trust.

The Big JQuery Update

Yes, the web uses Javascript incredibly much today. And unfortunately GNU Social currently even depends on it for full functionality. That’s something I wish to change, to avoid a dependency on automatically executing programs in the browser. But it can undoubtedly increase usability. So updating JQuery to its latest version was next on the todo list:

1eead02 Changed bind() and unbind() to on() and off(). Shortcut for (document).ready().
6fa9062 Changed bind() and live() to on(). Changed .attr() to .prop() for checked and disabled. Shortcut for (document).ready(). This is the first attempt to convert live() elements to on() according to http://api.jquery.com/live/.
af4f2a1 Changed .attr() to .prop() for checked and disabled. Removed "style" removal which I assume was tied to opacity setting on line 9. Replaced "style" setting via attr() on line 12 with css().
1757a65 Shortcut for (document).ready(). Changed .attr() to .prop() for checked and disabled.
3efa107 json2 extlib updated to 2013-05-26 version
a56ad2c Updated jquery extlib to v2.0.3
a4d04d2 Fixed regression from util.js updates + syntax cleanup
3858897 farbtastic removed along with userdesign stuff
dfa1b15 Changing js .live calls to .on for jquery 2.x
438685b jquery javascript was moved to js/extlib
2da9288 jquery-ui updated and moved to js/extlib
56ebe91 jquery form updated and moved to js/extlib
4f065d6 Removed jOverlay as it's outdated and not referenced
0731207 updated jquery-infieldlabel from 0.1.2 to 0.2.1
31bace8 updated and moved jquery-jcrop (no longer .min.js)
3604924 updated and moved jquery-cookie
11f4363 Fixed regression from jquery-cookie update
6de3fc0 jquery 2.x update related fix (.die no longer defined)
5e24600 Minified javascripts are evil! Human readable source, please!
1775fce Added new config for lighttpd.conf that worked on my 1.28 setup.
4822965 Event::handle only takes array $args
83b8523 Events on user registrations now strictly typed
d480ed4 Gravatar pretty much equals disregarding privacy
8935a2f Autocomplete migrated to jquery-ui autocomplete
8140c4f Bad call to joinAdd in Profile.php

It seems to have worked well for me, at least! I believe many of these commits can be imported without any of the previously listed ones, as they should only touch javascript files and some small portions of fairly static code. A modern JQuery library can help a lot to make GNU Social clientside development interesting for more people!

Some of the commits in the latest list are unrelated to JQuery updates (essentially all of the last ones except 8935a2f), but are instead part of tidying up and making the code stricter and less redundant. Many scripts are even thrown away, as they were never referenced anywhere in the code (such as farbtastic and jOverlay).

My favorite commit was “5e24600 Minified javascripts are evil! Human readable source, please!”. In the future we should also have a closer look at LibreJS for compatibility and compliance!

I’ve aquired a Nokia 5220 from a dear friend of mine. It’s a rather cheap, simple phone but it sports a camera, capacity to play music and video etc. It doesn’t support 3G connections, but heck GPRS is good enough for low-bandwidth stuff. So I’m thinking about starting a photo/fashion blog embedded into my deep, political criticism and other crap I almost manage to write down.

The phone has a Flickr application, which I’m guessing was installed by default rather than the previous owner. This Flickr application allows me to upload images to the account, which is then retrievable from the internets of course. Pretty basic and probably useful for most people who want to easily share their images. Personally I’m not quite satisfied and will probably write my own interface for a photo sharing module to WordPress (or stand-alone) myself…

Anyhow, the first question I get when I’ve newly registered a Flickr account and access it with my mobile phone is: “Nokia wants to link to your Flickr account”. Now, what does this mean?

This is a third-party service. If you don’t trust it with access to your account, then you should not authorize it.

Right. That’s all sound and stuff. But one might be curious as to what would be authorized if you accepted this third-party agreement… Boy was I surprised when I scrolled down and read the following:

Wow. Nokia asks permission to become me. Interestingly enough, this is followed by the statement that “Nokia will not have permission to: Delete photos and videos from your account”. Then, I ask myself, what do they mean by allowing them to replace but not delete? And who the fuck would ever authorize them to do this?

I of course clicked “NO THANKS” and uploaded my pictures after logging in to Flickr. But the question appeared once again when I started the application a second time… I wonder if they ever stop nagging. (Was I merely using a fallback HTTP interface? I guess I’ll never know…)

I understand that they need this access to allow their third party application to manage your account details. No human interaction is needed, but still it is not denied. The company Nokia might as well employ 5000 Chinese who do the “management” manually, rather than automatically through software.

This is also why “cloud computing” is bad. It’s the same theory. Outsource/export your control, rights and supervision to a third-party company. No, it’s much better to keep your computing to yourself. You wouldn’t ask a stranger to manage your family photo albums, right?

Update 2010-03-10: As the comment for this post have pointed out, it’s not Nokia the company who are asking for permission, it’s the Nokia photo sharing software. I’m still confused as to why I can’t just hand it my username and password, or better yet a private API key, and be done with it… It should be obvious for people that when you use third-party software it’s distributed “as-is”.