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:
- Specify Delicious user account
- Optionally enter tag(s) to filter the items returned from delicious
- Connect to the rss feed for the delicious account passing the arguments from my form
- Remove any bookmarks made after the last post
- 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
ed3cada5-ca05-4cf6-904a-debeaee1852e|1|5.0