从四月一号开始就着手开发一个从“阳光博客”搬家到“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开发。
整个架构设计的核心思想是:
可扩展的博客管理,配置文件如下:
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。
四、开发实现
接口定义:
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*****************************************************************************/
11using System;
12using System.Collections.Generic;
13using System.Linq;
14using System.Text;
15
16namespace 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
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*****************************************************************************/
11using System;
12using System.Collections.Generic;
13using System.Linq;
14using System.Text;
15
16namespace 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),这样对自己以后的项目也有很大的帮助。