Back in January of this year I wrote my first Windows Live Writer plug-in to save me manually copying my Delicious Bookmarks into my semi-regular Useful links posts. I have just created a project for the Delicious Bookmarks Plugin for Windows Live Writer on CodePlex.

This has a number of advantages for me, firstly its now out in the open and anyone can look at the source code and improve it – which will help. Secondly I no longer need to host it on my local Subversion server (that sounds pretty impressive but it is actually just my pc running VisualSVN Server) and that’s one less thing for me to have to backup.

So if anyone has any contributions they’d like to make please download a copy and let’s make it better together.

Tags: , , | Categories: Development | WindowsLiveWriter

I know its only been a few days since I released my Delicious Bookmarks plug-in for Windows Live Writer, but I found a few better ways of doing some things so reworked the plug-in to take advantage.

I guess it pays to read the documentation, SDK or API for something when you’re building a plug-in, but part of the fun of programming, for me at least, is to try to work it out for myself – and that’s what my original version of the plug-in was, me working out how I could do it my own way. What this means is that I’ve been able to leverage some features of WLW API to make the code more streamlined and also, by taking advantage of what’s on offer, do things in a way that WLW was designed to do. For example I to get the rss feed from delicious I was simply passing the url to an XPathNavigator and having that be responsible for requesting the feed. However using the built in PluginHttpRequest

PluginHttpRequest request = new PluginHttpRequest(uri);
Stream stream = request.GetResponse(TIMEOUT_SECONDS * 1000);

to make the HTTP request lowers the security requirements for the plug-in; and this fixed the problem I had trying to run this in the office.

Another nice feature that I took advantage of was the built in persistence mechanism, IProperties that allowed me to get rid of the xml config file that I had been using until then to persist data between uses. There was nothing ‘wrong’ with my xml config file, but it relied on the user having permissions to write to the installation directory, I’d already made a mistake when changing an attribute name in 1 place that I’d not refactored properly  - this way all I needed to do was to create a class that modelled my name/values and then provide an interface for the user to set their values. Again the developers of WLW were thoughtful enough to give me a nice easy place to allow that to happen. By adding “HasEditableOptions = true” to my WriterPlugin Attributes WLW added a button to the plug-in details screen for “Options”, which I used to hook up a revised WinForm to gather the users Options with. Then persist them via the IProperties interface and I’ve got my new version of the plug-in.

End result: smaller, easier to read classes, easier to write UnitTests for and easier to add new features to. So if anyone has any requests please let me know.

Delicious Bookmarks installer v1.2

Tags: | Categories: ASP.NET | Development | UsefulLinks | WindowsLiveWriter

DeliciousBookmarksInstaller.msi

I’ve recently started using Windows Live Writer to author my blog posts (seems that a lot of people are migrating to this, so I thought I’d see what all the fuss is about) and though there are 2 plug-ins for it that get your delicious bookmarks 1 of them doesn’t work and the other doesn’t do what I want. So I set about making one that does what I want. I got a copy of the dll for the one that doesn’t work and deconstructed it with the aim of seeing what was wrong and to see if I could fix it quickly. I soon realised that I was looking at a complete re-write; it had been written for a previous version of wlw, the way it processed the feed structure from delicious was a bit brittle and I also wanted a bit more functionality.

For my weekly Useful links posts I have been manually copying the links from my delicious bookmarks and only for those that are more recent than the last time I posted. However I have had in the back of my mind the idea that I would write something that did this for me, so have been adding a new tag to my bookmarks that I want to appear in my post.

This gives me a basic set of requirements:

  1. Specify Delicious user account
  2. Optionally enter tag(s) to filter the items returned from delicious
  3. Connect to the rss feed for the delicious account passing the arguments from my form
  4. Remove any bookmarks made after the last post
  5. Process the results and return them as an unordered list

Searching google it is easy to find articles that give you the basics of how to write a simple WLW plugin, and so I wont repeat that here.

Ok so my 1st requirement is to gather the username, and optionally tags, for the account to connect to. So I created a WinForm that inherits from

System.Windows.Forms.Form 

with textboxes to allow me to enter the details I wanted to return and properties for the values gathered from the input fields. Because the CreateContent method overrides DialogResult I needed to set the DialogResults for buttons on my form rather than program against the OnClick event e.g.

this.buttonOK.DialogResult = System.Windows.Forms.DialogResult.OK;

So far so good, that’s 2 of my requirements met. Next I needed to connect to the RSS feed delicious provide and append the username, and any tags if they’d been provided. However to save a bit of typing I also wanted to persist the values from my form so I could pre-populate the form each time I fire it up. So before going any further I added a method to load these values from a config.xml file, I could then also persist the last time I used this plugin so I could filter away ‘old’ bookmarks.

private string GetDeliciousFeed(string username, string parameters, DateTime lastPostTime)
{
string uri = DELICIOUS_FEEDS_URL;
const string AMOUNT_OF_RESULTS = "?count=100";
uri = string.IsNullOrEmpty(parameters) ? uri + username + AMOUNT_OF_RESULTS : uri + "/" + parameters + AMOUNT_OF_RESULTS;
int numResults = 0;
List titles = new List(0);
List urls = new List(0);
StringBuilder sb = new StringBuilder();
XPathNavigator navigator = new XPathDocument(uri).CreateNavigator();
XPathExpression expression = navigator.Compile("/rss/channel/item");
XPathNodeIterator nodes = navigator.Select(expression);
while (nodes.MoveNext())
{
nodes.Current.MoveToChild("pubDate", "");
string orig = nodes.Current.Value;
string pubDate = string.Format("{0:dd/MM/yyyy}", DateTime.Parse(orig.Remove(orig.IndexOf(" +"))));
if (DateTime.Parse(pubDate) > lastPostTime)
{
AddToLists(titles, urls, nodes);
numResults++;
}
}
if (numResults > 0)
{
sb = FormatResults(numResults, titles, urls);
}
else
{
MessageBox.Show("No new bookmarks since the last time!", "SJM Bookmark Plugin", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
return (sb + "

Auto parsed by delicious bookmark plugin

"); }

I created an XPathNavigator, XPathExpression and XPathNodeIterator to allow me to process the feed results and iterate through each item comparing its pubDate with my lastPostTime and if it was greater then add it to a titles and urls strongly typed list of strings. I could have simply used a dictionary<string, string> here, but if I ever wanted more details then that would have been some additional mucking about with the logic, whereas this way I would just need another list of strings. Then passed the 2 lists to FormatResults to handle building the list item strings or, if there were no new bookmarks, then to pop up a MessageBox.

Finally I persist the values from the form back to the config.xml file updating the lastPostTime value so I only return new results.

There are a few other bits and pieces involved in making this work, but they are not too interesting – creating the config.xml file if it isn’t found when trying to read from it as well as building the installer.

I was just about to add a link to the MSI, but that option seems to be missing from WLW… I can see me writing another plugin (unless someone has already written one!) to handle adding attachments. For now I’ll have to manually code this link:
DeliciousBookmarksInstaller.msi

Tags: , , , | Categories: ASP.NET | Development | UsefulLinks | WindowsLiveWriter

January 0922

Windows Live Writer

I’ve noticed recently more and more people are using Windows Live Writer to author their blog posts, so figured I’d give it a go and see what all the fuss is about. To get started you need to have a Live Account, which I do as I’m using Live Messenger and Live Sync – it’s actually another optional install that I’ve just ignored in the past.

Next you need to configure WLW for your blog(s), I’m using BlogEngine.net which uses the Metablog API and this is just one of the many standards supported by WLW so that was easy – just provide your url, admin username and password and you’re good to go.

Then to create posts you simply fire up WLW and start writing, the formatting options are pretty good / standard and you get full access to the html – it doesn’t seem to use the hideous engine used by IE or Word, the mark-up is good and clean. You can save drafts until you’re ready to post, and once you are ready all you need to do is click the publish button. I have mine set so it checks spelling and that I’ve got a category / tags set. So I shouldn’t end up posting something half complete. I also like the plug-ins – there’s a library of plug-ins for you to chose from to enhance your experience. To date I’ve installed a few (Syntax Highlighter Block, SEO Slug and Acronym Tags), yes I could hand craft these if I wanted, but why bother when they make it so easy to do?

True you need to set this up on each computer that you want to post from, but the same is true of any installed software – but it is a good platform and I can fall back on the web tool if I need to post and I’m not at one of my computers.

Tags: | Categories: Development | SiteNotice | Review | WindowsLiveWriter