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.
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.
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.
Tags: .NET Development, Blogging