
At the start of the year, Codeplex announced support for Mercurial (Hg), possibly the best tooled DVCS for Windows. We’ve now come full circle – originally MahTweets code was on Codeplex via TFS/SVNBridge, but after one too many stuff ups with SVNBridge refusing to let one or more of the team commit, we switched to self hosted SVN.
MahTweets has now returned to Codeplex ’cause DVCS is cool.
From a tooling point of view, all we had to do for Fisheye was upgrade 2.3 to get support for Hg. Changing TeamCity over was pretty easy too, like Fisheye we just had to point it to the Hg binary location and it was good to go. JIRA hooks into Fisheye, so it doesn’t need explicit Hg support. From a dev client point of view, we’ve changed from TortoiseSVN to TortoiseHg, and VisualSVN to VisualHg.
However, the solution, project and MSBuild file that the build server uses more complex. All of our automagic builds append the revision number from the source control. We were achieving this by using the MSBuild Community Tasks which includes tasks for Subversion in all our CSProjs’ (so every assembly has the correct version) and in our msbuild file.
<SvnVersion LocalPath="$(ProjectDir)" ToolPath="$(MSBuildCommunityTasksPath)\Subversion\">
<Output TaskParameter="Revision" PropertyName="Revision" />
</SvnVersion>
The obvious issue with this is that no projects could build because SvnVersion had a bit of a panic attack being unable to find any Subversion bindings. While there is no Mercurial support in the MSBuild Community Tasks, there is (thankfully) a separate library available – MSBuild Mercurial Tasks.
<HgVersion LocalPath="$(ProjectDir)" >
<Output TaskParameter="Revision" PropertyName="Revision" />
</HgVersion>
Very similar syntax, with the only difference being no ToolPath. The SvnVersion task uses ToolPath to point to your svn.exe, whereas HgVersion just uses the “hg” command so a command line client must be installed/registered properly with Windows (TortoiseHg installs this, or they maintain a command line client without the GUI)
It’s been a busy few weeks for me since Remix – surgery, a couple of MahTweets releases, expansion of the MahTweets team, but I’ve become rather internets famous while I was at this year’s Remix in Melbourne a few weeks ago.
First, there is the Hyro blog post from the lovely Kate Carruthers, Windows and Open Source – Social Media Aggregation client. Then Michael Kordahi and Andrew Coates ambushed me and dragged me up on stage for their live Frankly Speaking vod/podcast for FS31: Live from REMIX10
In my defence, I am a shy guy and don’t really like being in the spotlight – but how awesome are my sideburns?*

(Image Copyright Nick Ellery)
* The answer is: very awesome
Over on MahTweets.com, we’ve just launched the first developer preview screencast. The idea of these screencasts is to get feedback – positive or negative – from the community on features and changes which will help shape the direction MahTweets takes.
So far there is only the one video up, and its a bit long at 10minutes (~28meg), however this is likely to be the longest video as its a general overview of where we’re up to. We’ll upload smaller, more specific videos over the coming weeks.
If you all behave and are lucky, I may even upload some of the earlier videos of the prototypes.
We need to add more features to the screencast subsite, such as..
- Authenticated logins for comments
OpenID/FBConnect/Twitter OAuth – this will then carry over to when we launch a syncing service for MahTweets.
You’ll still have the semi-anonymous commenting system, but if you’re signed in and don’t erase the cookies, you don’t have to login for every comment.
- HTML5 Video
Instead of just providing a Silverlight player, we’ll add the HTML5 Video tag for browsers that support it using H.264 (so, Chrome/Safari). If your browser doesn’t meet that, it’ll ‘downgrade’ to the Silverlight player.
Why Silverlight over Flash? Silverlight player is a lot easier – the free Flash mp4 players I’ve tried in the past don’t stream, don’t scrub, and require watermarks/etc. Expression Encoder output the player for me, dead simple.
- Direct download link
A simple link to the source video file so you can download it directly. Currently if you’d like to download the screencast directly, just view source and find the ".mp4" file.
- RSS feed
To keep up to date, duh
Where is part one? Well a few months ago, Brendan wrote part one outlining the frustration we feel about everybody loving the "big boys" in the Twitter client space, never giving the smaller, (seemingly) the non-VC funded, open source clients a chance to shine.
It’s happened again, but this time its worse. Seesmic were yet again presenting at a major Microsoft conference (MIX10), banging on about how they got early access to the WinPhone7 Series hardware and SDK – how wonderful, another platform we simply can’t compete with because come day one, they’ll have not only had the emulator for longer, but physical devices to try everything on. And if we were to move to WP7S, we’d have to break the mindset of everybody who saw MIX/associated articles that "WP7S + Twitter = Seesmic". They are in the phone from before day one. You just can’t compete against that.
Oh, and something about updated desktop client that will include plugins – turns out via MEF, just like us. The one consolation I have is that all those promised features they keep banging on about – we’ve got them today. Now. 3 months ago. Not "in the near future" (anybody seen their iPhone client they promised? oh wait, doesn’t exist)
However the final crushing blow came when news broke that Silverlight (in beta form?) has now been released on Nokia’s S60 platform – and guess what the two example apps are? Bing and Seesmic.
Unlike Brendan, I’m not venting at the general noisy ‘industry’ and how hard it is to get a break, but how the favourites of PDC will continue being the favourites on every platform Microsoft releases, so long as Microsoft keep handing out early access to the same developer again and again. This isn’t so much about MahTweets, but the frustration that Microsoft pick a favourite and will run forever with them – what about the other, smaller clients in this field? Where is the love for Witty, Blu, Halfwit, Sobees, or Gadfly?
It feels less like "Developers, Developers, Developers" and more like "Developers – those guys, the rest of you don’t matter"
Why even bother?
After MahTweets 3 (which is a very major version/update), I won’t be bothering – I’ll be getting out of the "game". MahTweets will be maintained/major bug fixes, the others may continue working on it, but I have no more interest in creating Twitter clients.
Why is it so personal?
For lack of a better cliché, I am MahTweets. I don’t mean to diminish the role or contributions of others, far from it, when I say I am MahTweets, I mean that I’ve poured a lot of myself into it, I’m the public face, I’m the "overlord", I started the project. For the others, it’s a pet project – for me, I’m disabled and unable to get a ‘real job’ – it’s as close to a job as I’ll have for a long time.
Now that Rafael Rivera and Long Zheng have launched Geosense For Windows (or you can see Long’s post on it), I can happily brag how MahTweets has supported this since before they started working on it.
Geosense and MahTweets both use the Windows 7 Location and Sensor Platform – Geosense being the provider, MahTweet being the consumer. We supported it in MahTweets to geotag tweets and Flickr photos, in the hope that one day Microsoft or the hardware partners would be kind enough to consider Australia a real country and finally release some relevant hardware to the platform here. So far that hasn’t happened, which is where Geosense steps in.
Geosense with .NET
Geosense by itself doesn’t really do anything terribly exciting to the end user – it’s what Geosense enables for developers that is awesome. Location based services and games are primarily on phones only as it can be a hassle for the user to manually enter their location all the time – now it’s dead easy to bring those services and games to the desktop through rich clients.
To start with, grab the Sensor and Location .NET Interop Sample Library.
Below is an abridged version of the MahTweets GlobalPosition class file (it does some other stuff for other platforms that don’t have the sensor API’s, but that’s just a matter of people manually setting their location).
using Windows7.Location;
public class Location
{
public String City { get; set; }
public String Country { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
}
public static class GlobalPosition
{
private static LatLongLocationProvider _provider;
private static CivicAddressLocationProvider _civicprovider;
private static bool _loadproviderthrowsexception = false;
private const uint DEFAULT_REPORT_INTERVAL = 0;
public static Location GetLocation()
{
Location l = new Location();
try
{
if (_loadproviderthrowsexception)
{
return null;
}
if (_provider == null)
{
_provider = new LatLongLocationProvider(DEFAULT_REPORT_INTERVAL);
_civicprovider = new CivicAddressLocationProvider(DEFAULT_REPORT_INTERVAL);
}
var y = _civicprovider.GetReport() as CivicAddressLocationReport;
l.City = y.City;
l.Country = y.CountryOrRegion;
var x = _provider.GetReport() as LatLongLocationReport;
l.Latitude = x.Latitude;
l.Longitude = x.Longitude;
return l;
}
catch (Exception ex)
{
return null;
}
}
}
Easy. The code speaks for itself – create a LocationProvider, query it to get the Latitude/Longitude. The rest is up to you.
Bonus Points
And if you’re a Powershell junkie, the following works too
[Reflection.Assembly]::LoadFile("<absolute location to dll>\Windows7.SensorAndLocation.dll")
$provider = new-object Windows7.Location.LatLongLocationProvider(0)
$position = $provider.GetReport()
$position.Latitude
$position.Longitude
With each new version of MahTweets – even the sub-releases – many people are having columns not saving correctly.
Disclaimer: This is entirely my fault.
The Fix
Long story cut short, the quickest way to fix this is to delete all of your columns, recreate them, and then quit. They should then reappear on next launch.
If that doesn’t work, you can remove all of your accounts, columns, etc, and start from scratch, but it could give the same problem. The best way would be to delete your config file and start from scratch. That can currently be found in
C:\Users\<YourUserName>\AppData\Local\Apps\2.0\Data\<SomeHash>\<AnotherHash>\
maht..tion_<YetAnotherHash>\Data\2.7.4.529
Mine is
C:\Users\Paul\AppData\Local\Apps\2.0\Data\5B03WGLL.0H0\ODJ8MMQ8.3WX\
maht..tion_0000000000000000_0002.0007_342b7e02bb86691e\Data\2.7.4.529
Delete the user.config file and it should be fine until the next update. It’s not ideal, I know, but we are working on a solution, which will also result in the config file being moved to another location.
The Explanation
We know what the problem is, sort of. Columns are made up of many “UpdateTypes”, such as “Normal”, “Mentions”, “Direct Messages”. Every one you have selected is written to the settings file on close, under Filters (Filters –> FilterList –> StreamList –> FilterStream). Below is an example
<FilterStream>
<IsIncluded>Include</IsIncluded>
<Protocol>statusnet</Protocol>
<AccountName>aeoth</AccountName>
<Color>
<A>0</A>
<R>0</R>
<G>0</G>
<B>0</B>
<ScA>0</ScA>
<ScR>0</ScR>
<ScG>0</ScG>
<ScB>0</ScB>
</Color>
<UpdateTypeString>MahTweets2.IdenticaPlugin.MentionUpdate, MahTweets2.IdenticaPlugin,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</UpdateTypeString>
</FilterStream>
Although it’s a little hard to see, I’ve placed emphasis on the Version number. With each new version, that changes, so currently it will have 2.7.4.529 (for those playing at home, 529 is the Subversion commit number associated with that release). However, if you’ve upgraded from 2.7.3, MahTweets will go looking for that version, and isn’t able to find it.
As I’ve said, we are working on a solution, but its not here just yet.
On Wednesday night, we pushed out another version of MahTweets, version 2.7. It’s been a long time between releases (3 months!) but a huge amount of work has gone into it.
New Features
- Autocomplete Everywhere
In previous versions we didn’t have autocomplete for contact names. Now we do. And its everywhere you can type!
- Yammer Plugin
Fairly basic at the moment, but we will get it up to "Twitter level" of support in the next version. Currently you can view/send and downloading attachments.
- Plurk Plugin
- Ping.fm Plugin
No media ‘pings’ yet, but that’ll come soon – still beat Seesmic to it! ;)
- Bit.ly Plugin
We couldn’t support bit.ly in previous versions due to how IUrlShortener plugins worked, but now they can store credentials much like any other plugin.
- Geotagging for Flickr & Twitter (both viewing and sending geotagged tweets)
- Searching
We now have the ISearchProvider interface, which lets IMicroblogs (aka, connection plugins like Twitter) provide a way to search.
At the moment went have "regular" Twitter search and streaming Twitter search. Although not entirely certain, I’m fairly confident to say we’re the first or one of the first full feature Twitter clients with streaming search support!
Streaming search maintains a constant connection to twitter, but you get results in real time. How fast? In most tests, you get the tweet roughly the same time it appears in the web interface for the person tweeting!
Down the track we’ll be adding Yammer and Plurk ISearchProviders, perhaps even Facebook.
- Local Searching
- Read/Unread tracking
This is optional, but you can have all updates marked as unread as they come in. Click on the ‘unread’ banner (or really any of update except the text) to mark it read, or the new ‘Mark all read’ button (the big tick on the side)
- Profile Columns
Although only supported by the Twitter plugin in this version, MahTweets can now show additional information about a particular contact inside MahTweets, instead of having to go out to the browser.
We’re looking at making this extensible so ‘information’ can be pulled from places like Twadges/etc, once we find the right API’s.
Improvements
- Twitter support
MahTweets now supports more of the recent twitter features such as:
- geotagging,
- lists,
- block&report as spam,
- "new style" retweets
- Filtering
Our filtering was previously pretty good. Now its pretty awesome. Tri-state filtering means you can do nothing, include or exclude contacts or streams ("streams" are types of updates, ‘mentions’ or ‘direct messages’) from a column.
- UX
This version started as a big UX/UI overhaul. The key improvements are less WPF blurriness (mostly caused by drop shadows), a "smaller"/less space wasting update template, clearer/nicer looking icons, far more intuitive settings/setup window and a few other niceties.
- Multi-parent behaviour
This problem is almost exclusive to MahTweets, and we’ve mostly solved it. Most Twitter clients that support multiple accounts dont support multiple accounts in a single column. Well, since MahTweets does support this, the problem is that what happens when TwitterAccountA and TwitterAccountB are both following TwitterUserC?
Do you double up the Tweet from C so it appears once for A and once for B? Do you make just a single tweet available to whoever got there first? Or do you make some sort of uber tweet which is for both A and B once they’ve both updated?
We’ve chosen the latter option, which creates a drop down box when you go to reply, giving you a list of accounts to reply from:
That part we’ve solved, and it works great. The part we haven’t entirely solved is filtering. If the tweet comes in first from A but is a mention for B, it is marked as a mention for B, but the UI doesn’t reflect this (ie, no colour change, won’t always jump to the right column) until the UI is forced to update. Sometimes this doesn’t happen unless you toggle edit mode on the appropriate columns!
It’s complex and a unique problem, but we’ll get there eventually.
- Better memory usage
WPF can be a bit of a beast to work with for small memory usage, but we’re finally getting it down to a more respectable figure. It’ll vary with how many accounts you have setup, how many columns you have, and if you clear all streams or not on a regular basis, but we’ve seen 5%-50% less memory usage!
There have also been a huge assortment of bugfixes, too many to list.
MahTweets Website
The MahTweets website has also undergone a huge overhaul!
Hopefully in the near future we’ll add some videos showing off some of our somewhat more hidden features, as well as fleshing out the Features, Developers and the return of the Community Plugins pages.
Future
So what does the future hold for MahTweets? Apart from a few bug fix releases, we’ll be releasing a MahTweets Developer Toolkit as well as reenabling community plugins – this will all happen under "2.7". For the next major version (2.8), we’ve not nailed down what extra features we want. However, we’ll hope to have
- Video uploading (Vimeo, Facebook, Flickr, Viddler, YouTube)
- More plugins for Url shortening and Status Handling
- Synchronising settings between computers
There is also the strong possibility that we’ll look into creating MahTweets for Android, now that I have a HTC Dream (thanks Will!)
Microsoft ran a programming contest a few months ago called Code7 – the idea is you’d code up an app with specific support for Windows 7 – things like touch, location, taskbar improvements, etc. All you had to do was submit a (up to) 3 minute screencast of your app. The prizes were pretty awesome too, first place is trip to PDC09 + $17,777USD. Regional winners get trip to PDC09 + $7,777USD, and regional runners up get a $1000USD laptop.
Well, I fell into the latter category – that is, I was told I was a regional runner up – awesome eh? My entry was MahTweets, which has support for geocoding photos for Flickr using the Win7 Location platform, as well as taskbar enhancements.
When I say I was told I was a runner up, I mean that I was notified I’d win the prize if I completed certain forms, which I did instantly. Then I was told they’d send out the physical forms, since apparently electronically filling them in isn’t enough. Once the deadlines for submitting those forms came and went without the forms even arriving, I was a little concerned. Turns out Microsoft Legal Counsel decided it was "concerned about the use of the real status feeds from the various social media sites, use of the Flickr website" (emphasis mine – there was more stuff about logos of the various services featured, but that’s relatively minor)
Just to recap, I submitted a screencast of MahTweets, showing some of functions it does with tweets as well as uploading and geotagging a webcam picture (of my ugly mug) to Flickr. Because I featured my Flickr profile, Microsoft Legal Counsel was concerned that I didn’t have permission from Yahoo to use a screenshot of Flickr. Right. To be honest, it wasn’t until I started drafting up this post that I even noticed the Flickr crap – I’ve been more concerned with the "real status feeds".
Firstly, what the hell is a ‘real status feed‘? I asked for clarification on what they meant – and it took twelve days to get a response - turns out that’s just what normal people would call a tweet. I’d say ‘social media network update’, but I only showed off Twitter functionality. MSFT Legal wanted permission from every identifiable twit in the video. "Okay, sure, that’s do-able" I thought, "there is only about eight or nine people who actually have tweets/avatars being shown off".
Turns out that no, I was wrong, they want not only consent from those people, but from any handle visible – so if XYZ wrote "hello @foo", I’d have to get consent from "@foo" as well – as well as all the names visible when I demonstrated building a group/column. Once I got the final bit of clarification, I just gave up, as the number of people I needed consent from was reaching 40+. A big thank you for those who did give me consent when I thought it was still eight or nine people.
The most frustrating bit about this is the way it was set up to be a disappointment – if they had of opened with "hey, if you can clarify XYZ legal situation, we’ll award you a prize" that would have been cool, but the "hey, you’ve won! fill in a form!" then waiting a few days (as it took that long for each email response) to find out there were more concerns just left a bitter taste in my mouth.
MahTweets makes extensive use of the Managed Extensibility Framework (MEF) for plugins, and recently we had the need for a plugin to use WCF to connect to an external service. The plugin was going to connect to the Bing Translation Service, and auto-translate all tweets into the language of your choice.

However, we ran into a few problems. The normal WCF magics picks up the configuration automagically from your app.config. WCF looks at the program app.config, but under MEF this gets a little trickier. It continues to look at the host programs app.config not the plugin app.config. Something about AppDomains.
There are a few solutions
1. Write all your configuration in code behind
I haven’t actually figured out how to do this for WCF clients but for hosting WCF services, its fairly easy. Adding yet another plugin, I needed to do some hosting over NetTCP bindings (named pipes). This particular service is so the TweetSaver plugin can work.
ServiceHost service = new ServiceHost(typeof(TweetSaverService),
new Uri("net.tcp://localhost:3131/TweetSaverService"));
service.AddServiceEndpoint(typeof(TweetSaverService), new NetTcpBinding(), "TweetSaverService");
var smb = service.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (smb == null)
smb = new ServiceMetadataBehavior();
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
service.Description.Behaviors.Add(smb);
service.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexTcpBinding(),
"net.tcp://localhost:3131/TweetSaverService/mex");
service.Open();
Obviously for different types of bindings there are differences, but the configuration doesn’t vary too much.
2. Use ye-olde Web Reference instead of Service Reference
In Visual Studio 2008, you can’t just right click on the project to Add Web Reference anymore, it’s hidden away a little.
Right click on your project, Add Service Reference –> Advanced –> Add Web Reference
Or in pictures (click on any image to enlarge it)…


This is the method I ended up using for the Translator plugin, simply because it was the path of least resistance/work. The older style of SOAP interaction still uses configuration files, but unlike WCF it is happy to look in the plugin configuration file.
3. Include the configuration information inside the host config
I’d highly recommend against this, as it really defeats the purpose of having a plugin in the first place, but you can get around the issue by putting the configuration from your plugin’s app.config into the host program’s app.config.
MahTweets v2.5 Beta 4 was released a few days ago, the entire 2.5 series has only been publically floating around for a couple of weeks, and we’re just about to hit 300 users (according to the Twitter OAuth control panel)

This version isn’t just me – a big thanks to the team of WillHughes, NickHodge, UXLuver and Shiftkey – those guys have really made MahTweets awesome.
So what are the big changes from the earlier 2.0 release? Well, it’s been nearly a complete rewrite.
- Multiple account support
- Facebook support
- Extensible, plugin based architecture using Managed Extensibility Framework
- Url shortening
- Multiple uploading services (Flickr, Twitgoo, Twitpic, Yfrog, Thumbwhere)
- Theme support
- Multiple column support
- OAuth authentication for Twitter, and over HTTPS/SSL meaning MahTweets is more secure than most of the other clients out there
- IronRuby support
Don’t forget the other fairly awesome features like
- Webcam support
- Quick adjusting/filtering of columns
- Open source under MS-PL license
This version has been getting some good press too!
"the rest integrates a very few functions and only allows a maximum check for updates, and post new tweet.
But now we have a valid alternative, that even though developing, already shows its remarkable quality."
via TuttoVolume.net
Want a good Twitter client for your Windows system that doesn’t necessitate installing Adobe Air? Check out MahTweets.
If you’re willing to overlook the…er…interesting interface, MahTweets is loaded with features.
via DownloadSquad
Then @aeoth create MahTweets. It’s MS-PL. It’s extensible (via MEF). It has IronRuby for scriptable extensibility.
It is awesome.
Use it. Contribute. Let’s make the world’s best WPF Twitter Client.
via Nick’s MSDN blog
If you’ve got any problems or suggestions, head on over to our UserVoice page and leave some comments.
The source code can be found at codeplex, or the installer on the MahTweets feature page.