从四月一号开始就着手开发一个从“阳光博客”搬家到“Blogger”的工具,历经一个月,宣告失败!
下面是开发的过程:
一、项目背景
从07年四月开始,我就在阳光博客上开始写博客,整整两年。在写博客过程中觉得阳光博客提供的博客功能有如下地方不友好:
1、无法添加mita数据到博客
2、文章编辑器太简单,对程序代码没有良好的支持
3、站点老是被检测出有病毒,Google搜索无法进入,Firefox也是警告,不过这个好像最近解决了。
4、看过阳光博客站点的首页觉得很多推荐的博客之类的都是90后。。。
5、整个站点是用ASP搭建的,注意是ASP不是ASP.NET,落伍的技术,每次看见后缀名是.asp 觉得就不爽,心里作用。
使用Google提供的服务已经好多年了,差不多完全接受或者说是依赖Google已经两年多了,觉得它提供的服务还是比较稳定,而且能满足我很多的需求,
比如:Gmail,Bookmarks,Doc,Code等等,Blogger是被Google收购的一家博客站点,觉得应该不错,就想把博客迁入Blogger,再个发现它是全球博客服比较好的博客,还有另个是Wordspress,我也在用,不过只写英文的,锻炼英文,呵呵!
二、项目需求
把阳光博客中所有的帖子全部移入Blogger,范围只是博客,不包括回复和留言。由于Blogger不支持自己生成创建时间,所以对于时间也不导入。
三、项目设计:
1、接口
Blooger API:http://code.google.com/apis/blogger/docs/2.0/developers_guide_protocol.html
YgBlog使用从博客管理中导出的日志Rss文件
2、程序架构设计

IBlog是接口类,定义一个博客要实现的所有方法以及需要的属性
BlogspotEntity是Blogger的实现,核心是做登录验证和接受博客数据
YgBlogEntity是阳光博客的实现,核心职责是从Rss文件中读入博客实体
Utility是公用的一些方法的集合,现在加入的核心功能是数据请求一个URL,并返回URL的Response结果
BlogEntityCollection是方便把BlogspotEntity和YgBlogEntity输出到BlogTools项目中
BlogTools是UI层,提供的功能有博客移动和发布博客以及查看配置

UI 层使用WPF开发。
整个架构设计的核心思想是:
可扩展的博客管理,配置文件如下:
BlogList.xaml
1
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
2
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3
xmlns:list="clr-namespace:Disappearwind.BlogSolution.BlogTools;assembly=Disappearwind.BlogSolution.BlogTools">
4
<list:BlogInfo
5
x:Key="ygBlog"
6
BlogName="YgBlog"
7
AssemblyName="Disappearwind.BlogSolution.YgBlogEntity"
8
TypeName="Disappearwind.BlogSolution.YgBlogEntity.YgBlog"
9
IsReadOnly="True">
10
</list:BlogInfo>
11
<list:BlogInfo
12
x:Key="blogspot"
13
BlogName="Blogspot"
14
AssemblyName="Disappearwind.BlogSolution.BlogspotEntity"
15
TypeName="Disappearwind.BlogSolution.BlogspotEntity.BlogspotBlog"
16
IsReadOnly="False"
17
UserName="disappearwind@gmail.com"
18
Password="mypassword"
19
PostURL="http://www.blogger.com/feeds/4113265077745692418/posts/default">
20
</list:BlogInfo>
21
</ResourceDictionary>
每个BlogInfo配置的是实现了IBlog的BlogEntity,配置的时候需要指定程序集和类,如果是可以导入的博客则要提供用户名密码,以及导入请求的URL。
四、开发实现
接口定义:
IBaseBlog
1
/**//****************************************************************************
2
* Copyright (C) Disappearwind. All rights reserved. *
3
* *
4
* Author: disapearwind, disappearwind@gmail.com *
5
* Created: 2009-4-1 *
6
* *
7
* Description: *
8
* Definition interface for base blog. *
9
* *
10
*****************************************************************************/
11
using System;
12
using System.Collections.Generic;
13
using System.Linq;
14
using System.Text;
15
16
namespace Disappearwind.BlogSolution.IBlog
17

{
18
/**//// <summary>
19
/// Base blog interface
20
/// </summary>
21
public interface IBaseBlog
22
{
23
/**//// <summary>
24
/// Blog name,the type is string and it's readonly
25
/// </summary>
26
string BlogName
{ get;}
27
/**//// <summary>
28
/// Blog url,the url which the blog can access and it's readonly
29
/// </summary>
30
string URL
{ get; }
31
/**//// <summary>
32
/// Keyword assign to the blog
33
/// </summary>
34
string KeyWord
{ get; }
35
/**//// <summary>
36
/// The url or address of blog posts
37
/// when it used in get posts from blog,it is a rss url or xml file of post
38
/// and when it used in add post to blog it is the api of the blog support to manage blog
39
/// </summary>
40
string PostURL
{ get; set; }
41
/**//// <summary>
42
/// The url for authenticate user
43
/// </summary>
44
string AuthURL
{ get; }
45
/**//// <summary>
46
/// Login blog to operate blog
47
/// </summary>
48
/// <param name="userName">user name</param>
49
/// <param name="password">password</param>
50
/// <returns></returns>
51
bool Login(string userName, string password);
52
/**//// <summary>
53
/// Get all posts
54
/// </summary>
55
/// <returns>posts list</returns>
56
List<IPost> GetPosts();
57
/**//// <summary>
58
/// Add a post to the blog
59
/// </summary>
60
/// <param name="post">the post to be added,it must implement IPost</param>
61
/// <returns>result</returns>
62
bool AddPost(IPost post);
63
/**//// <summary>
64
/// Delete post
65
/// </summary>
66
/// <param name="post">the post to be deleted</param>
67
/// <returns></returns>
68
bool DetetePost(IPost post);
69
}
70
}
71
IPost
1
/**//****************************************************************************
2
* Copyright (C) Disappearwind. All rights reserved. *
3
* *
4
* Author: disapearwind, disappearwind@gmail.com *
5
* Created: 2009-4-1 *
6
* *
7
* Description: *
8
* Definition interface for base post. *
9
* *
10
*****************************************************************************/
11
using System;
12
using System.Collections.Generic;
13
using System.Linq;
14
using System.Text;
15
16
namespace Disappearwind.BlogSolution.IBlog
17

{
18
/**//// <summary>
19
/// post interface
20
/// </summary>
21
public interface IPost
22
{
23
/**//// <summary>
24
/// Post title
25
/// </summary>
26
string Title
{ get; set; }
27
/**//// <summary>
28
/// Post content
29
/// </summary>
30
string Content
{ get; set; }
31
/**//// <summary>
32
/// Post createdate,maybe didn't today,it was the actual created day.
33
/// </summary>
34
DateTime CreateDate
{ get; set; }
35
}
36
}
37
YbBlogEntity和BlogspotEntity负责实现这两个接口。当然也可以再添加其它的博客,只要实现了这两个接口就可以无缝的插入到BlogTools中
五、测试
工具开发完以后做了一些导入测试,可以导入大部分的博客,但是还是存在一些问题:
1、Blogger每天提供的访问URL的次数有限制,不能一直调试测试,好像大概每天只能有三次(做三次导入,每次我一般有50多条数据)
2、对于特殊标签Blogger不允许导入,比如YgBlog自定义的<o:p>
3、Html标签必须成对,如果有单个的则不能导入
4、Html中不能带属性,包括样式。
六、总结
整个项目对我来说是一个失败的项目:整个项目实现了基本数据从阳光博客到Blogger的导入,但是Html标签的处理比较失败。
代码完成的时间是4月17号,但是却话了近半个月的时间做调试测试。当然也有Blogger的限时访问的原因。
还有一个很重要的外界因素:Blogger在中国访问有问题,老是会挂掉。估计GFW屏蔽的吧。我在公司使用的是直连到日本的网络,不会有这个问题。
所以,这个工具只能自己娱乐了,不能作为实用工具了,真可惜。
后记:
我写这个博客的主要目的是和大家分享一下。我们每天用技术为公司创造价值,其实我们也可以用我们掌握的技术去为自己开发一些工具服务,顺便可以学学东西,包括程序设计的架构(比如BlogSolution中对接口的定义,以及实现的方案,无缝的插入扩展)和新的技术(Blogsolution中的BlogTools是用WPF开发的),以及使用一些别家公司提供的API(比如Google的Blogger API),这样对自己以后的项目也有很大的帮助。
附:Blogsolution Release