Migrating from dasBlog to SubText

As I wrote in my previous post I changed my blogging software. In order to migrate all posts and comments from my previous blog i wrote a little program to do it. I did not read a lot of documentation on how to do this, strictly a trail and error approach.

I started out by looking for what web services the different blog systems exposed by doing a file search for *.asmx and just pointing my browser to then to have a look at the API’s.

For dasBlog the one that cauth my eye was /SyndicationService.asmx and for SubText it was the /Services/SimpleBlogService.asmx. So, I cranked up Visual Studio .Net 2005 and added those two web references.

WebRererences.Jpeg

After being at it a while I realized I did not know how to create the comments using the SimpleBlogService in SubText. So I got the SubText source code from sourceforge.net and opened up the solution in Visual Studio and added a method to the web service. Not at all backward compatible, but that don’t matter cause I only need it for the migration. So in SimpleBlogService.asmx.cs I added the following method.

[WebMethod(MessageName="AddCommentToEntry",
   Description="Add comment to post",EnableSession=false)] public void AddComment(int entryid, string username,
   string password, DateTime commentdate, string title, string body, string author, string email, string sourceIP, string sourceUrl) { CheckUser(username,password); Entry entry = new Entry(PostType.Comment); entry.Author = author; entry.Title = title; entry.TitleUrl = sourceUrl; entry.Body = body; entry.ParentID = entryid; entry.SourceName = sourceIP; entry.Email = email; entry.DateCreated = commentdate; entry.DateUpdated = commentdate; Entries.InsertComment(entry); }

Deployed that to my webserver and updated the web reference in the migration project. Now I got crunching on the migtraion. I choosed to use the Atom feed from dasBlog and in order to get all posts I went in to dasBlog admin and changed the syndication settings so that all posts would be in the feed.

SyndicationSettings.Png

Get to the code you’re saying and that i will. I created a console application for this. Starting out the main method with getting instances of the web services.

SubText.SBSSimpleBlogService sbsSvc = 
   new dasBlogSubTextMigratio.SubText.SBSSimpleBlogService(); dasBlog.SyndicationService dasBlogSvc =
   new dasBlogSubTextMigratio.dasBlog.SyndicationService();

Next, get the feed.

class Program
{
    static void Main(string[] args)
    {
        //Get instances of the webservices
        SubText.SBSSimpleBlogService sbsSvc =
new dasBlogSubTextMigratio.SubText.SBSSimpleBlogService(); dasBlog.SyndicationService dasBlogSvc =
new dasBlogSubTextMigratio.dasBlog.SyndicationService(); //Get the feed dasBlog.AtomRoot atomElement = dasBlogSvc.GetAtom(); foreach (dasBlog.AtomEntry e in atomElement.entry) { Console.WriteLine("Migrating post: \""
+ e.title + "\" ..."); string title = HttpUtility.HtmlEncode( e.title ); DateTime date = e.published; string body = e.content.Any[0].InnerXml; string[] categories = new string[0]; ; if (e.category != null) { categories = new string[e.category.Length]; for (int i = 0; i < e.category.Length; i++) { categories[i] = e.category[i].label; } } //Retrive guid for entry, I'll use it to extract the comments string guid = e.id.Substring(e.id.IndexOf("guid,") + 5, 36); Console.WriteLine(" Creating post in SubText"); int id = sbsSvc.InsertCategoryPost("username", "password", date,
title, body, categories); XmlDocument commentsDoc = new XmlDocument(); commentsDoc.Load("http://MyDasBlogSite/Content/AllComments.xml"); XmlNamespaceManager nsManager =
new XmlNamespaceManager(commentsDoc.NameTable); nsManager.AddNamespace("def",
"urn:newtelligence-com:dasblog:runtime:data"); XmlNodeList commentsForPost =
commentsDoc.SelectNodes(
"/def:ArrayOfComment/def:Comment[def:TargetEntryId = '"
+ guid.ToUpper() + "']", nsManager); if (commentsForPost.Count > 0) { Console.WriteLine(" Adding comment(s)"); } foreach (XmlNode node in commentsForPost) { DateTime dt = Convert.ToDateTime(GetValue(node, "def:Created",
nsManager)); string commentTitle = GetValue(node, "def:TargetTitle", nsManager); string commentBody = GetValue(node, "def:Content", nsManager); string email = GetValue(node, "def:AuthorEmail", nsManager); string author = GetValue(node, "def:Author", nsManager); string url = GetValue(node, "def:AuthorHomepage", nsManager); string ip = GetValue(node, "def:AuthorIPAddress", nsManager); sbsSvc.AddComment(id, "username", "password", dt,
commentTitle, commentBody, author, email, ip, url); } } Console.WriteLine("Done!"); return; } private static string GetValue(XmlNode node, string subnode,
XmlNamespaceManager nsManager) { if (node.SelectSingleNode(subnode, nsManager) != null) { return node.SelectSingleNode(subnode, nsManager).InnerText; } else { return ""; } } }

As you can see I did not (fast enough) find a way to get the comments from the web service so I went for the AllComments.xml file in dasblog.

There is probably a lot of better ways to do this, but this I how I did it and it seems to work so far.