2020-07
9

状况连连

By xrspook @ 10:35:47 归类于: 烂日记

你永远都不知道纠结的路上会出什么状况。一路平坦不好玩,5分钟就能所有问题,那是无聊的节奏。老blog的重新上线是我近段时间一直在纠结的东西。要做的事情很多,应该如何开展?做这些事的步骤应该是怎样的?谁轻谁重?

首先我做的是处理blog的核心——内容。文字我是有的,我有大把大把,但里面也有非常多连我自己都说不上到底是什么的东西。有可能长文被阉割了,但我自己毫不知情,有可能是消息从其它网站上复制粘贴过来了,带入了一些我根本没有意识到的乱七八糟代码,不同网站连换行都不一样。有些是“br”,有些是“br/”,有些是“br /”,有些是“BR”,有些是“BR/”,仅仅是“b,r,/,空格”的排列组合就有多得你想不出的效果。如果这在HTML里,都不是问题,但我做静态blog的第一步是从html到markdown,该死的“strong”在html2text的脚本里是不允许期间有换行的,在这个脚本里,连续两个br就能自动匹配正路的p,但如果遇到稀奇古怪的“/”和空格呢?在我的python转码脚本里,我用了很多行去处理那些排列组合的问题,正则的、非正则的替换用了好多遍,所以脚本运行速度只可能在我一次又一次的增加新规则之后变得越来越慢。理论上,这些东西都是不存在,但事实就是这么残忍。除了html的问题,还有yaml以及文件名字符要求的问题。转义字符出现就丑陋了。丑陋归丑陋,字符不对,那是直接编译不出来的节奏。出状况这种事简直不计其数。我也不知道自己到底改了多少个版本,理论上脚本修改这种事我应该放在坚果云文件夹里进行,但因为我生成数据的文件夹和我的脚本文件夹一致,显然那就太消耗同步流量了,所以我大胆地把脚本放在了坚果云以外修改,那是一个错手就没得救的玩命。其实我完全可以把输出的文件夹设置在坚果云以外的地方,但我就是没有这么干。要把BlogBus和点点的数据匹配为WordPress的格式,然后再用WordPress格式的数据转化为markdown。为什么我要有WordPress这个步骤呢?起码但我学会了XML到另一个XML的规律后,不静态blog的时候我还能退回WordPress,虽然那意味着我导入数据的时间将是个天文数字。没经历过这些纠结,我就不会深切体会到好好码字,不要不规范乱写的重要性。从前,尤其是一开始在BlogBus写blog的时候,我总把网上看到的东西直接复制到编辑器里,这样过于简单的操作让我付出了非常多整理的代价。后来的点点几乎没有这种问题,现在我更加是极少会直接复制粘贴网上的东西到我的blog里发布,即便有时会截取一段,基本上都是保证无格式纯文本的。现在我知道了,但当时我不知道,成长是需要付出代价的。我仅仅是在处理自己的东西,所有坑都是我从前挖下的。如果我是被迫要帮别人擦屁股,估计我早就把那个人诅咒死几万年了。

内容基本确定下来后,一开始我觉得应该不会太难的静态blog主题原来也不好找。首先是样式得对上眼,其次是渲染速度要快。有些主题连单机渲染都会让我的电脑崩溃掉,连测试都无能,真的是什么都不用说了。我几乎得出一个结论,如果某个主题大于5MB,基本上无需考虑了,那些10MB左右的,更加会让我电脑宕机。不是人人都会遇到这种事,宕机与否的测试基于我需要渲染的文章有接近3900篇,不是人人都有这样的体量,这还是建立在我已经放弃了6100多篇图片内容已经失效,光文字意义不大的文章上。

内容好了,主题好了,还得考虑把网站托管在哪里。要免费,要速度快,要可以绑域名,要服务器稳定。对一个女人,对一个习惯于货比三家的人,这实在又是一个大纠结啊啊啊。

2020-07
4

累死累活

By xrspook @ 23:04:56 归类于: 烂日记

折腾了一个晚上,打算关电脑睡觉了,突然想起好像今天自己的blog还没写。我把时间都耗在了什么地方呢?我正在校对其中一个老blog里的内容。

之前,我的关注点纯粹是格式的转换,先从BlogBus的XML转化为WordPress的XML,然后再从WordPress的XML转化为一篇一篇的markdown。纯粹技术的东西我已经几乎完成了,余下来的问题,需要在不断的转换之中发现,然后修正。今天我花了一个晚上搞的是校对从前那个blog导出来的内容。不知道从什么时候开始,我发现里面有些文章的正文是不存在的,是空白的,至于为什么,非常有可能是当时的文章我发布的时候其实没有成功,但是标题和其他内容已经有了,失败的纯粹只是正文。至于为什么不行,我当时也不知道。通常那些失效的文章,我都是批量手动粘贴发布的,可能是从一个网页,也可能是从一个word文档贴过去。在贴的过程中,自动带入了非常多的超文本格式,这个我之前已经吐槽过了。在格式转换过程中,我不得不费尽九牛二虎之力把那些转回来。其中那些空白的正文,这一次我想把资料填补回去。

昨天我的确好不容易找回了那些资料,也进行了填充,发现效果还不错,但是原始导出的那个BlogBus文件就不再原始了。接着,我发现那些有正文的文章其实也不完全可信,因为正文的内容不知道为什么只有一部分,不是全文。难道发布以后,我没有好好一个一个浏览过吗?还是说点发布之前,我看到的东西的确是完整的,BlogBus没有给我单篇文章字数的限制,但是实际上发布的只是部分。我的问题在于,有可能发布出去以后,我没有在前台校对一遍,但是也有可能我校对过了,当时看是没有问题的,但是当我在BlogBus后台把自己的东西导出的时候出了状况。一开始我觉得可能是我自己的问题,但后来我发现,断字断得好神奇,一个单词可能只剩下头两个字母,显然,如果是我复制错误的话,不会有这么低级的东西,顶多我会漏掉一些段落。现在搞清楚到底是我人为的错误还是BlogBus阉割了我的东西已经毫无意义。所以,我只能一篇一篇地校对文章的开头和结尾,确保是完整的。一些篇幅比较短的文章,暂时我还没发现断尾的现象,但是,对一些比较长的文章,断尾是必然的。纯文字有100K以上那些文章,通常BlogBus只留给我一半的内容,余下的那些消失了,而且还不告诉我。我记得从前选择BSP的时候,我知道有一些是对单篇文章的字数有限制的,到达一定程度以后就会告诉你,超过多少字了,请你重新修改,否则不能发布,但BlogBus没有这个限制,起码在一开始我选择他的时候没有。另一方面,我觉得之所以这样,会不会跟他们数据库的存储模式有关。如果他们数据库的某个存储单元顶多只能100K,我在那里输入了150K的文字。当然多出来的那些就不可能被保存下来,这纯粹只是我的猜测。几十上百篇文章,一个一个去检查头尾是否齐全,格式有没有乱套,这是相当累人的。虽然那些最原始的东西我还有,但绝大多数那些东西我都是保存网页的。现在那些网页已经不能在Firefox里打开了,用Chrome也不行,于是我只能使用IE,而且是兼容视图模式。我不觉得当年我用保存网页的方式把文字记录下来有什么毛病,我只是不明白为什么现在的浏览器不允许我打开那些老东西。

如果当年就有markdown这种这么神奇的东西,大概我就不需要走这么多弯路了。

2020-07
3

攻克静态blog

By xrspook @ 10:30:05 归类于: 烂日记

上周五我才开始研究静态blog。我选定的基本是hugo,因为这个东西生成网站的速度非常快。暂时我只是在本地操作。一开始的时候我不知道那个生成网站的命令窗口必须一直开着网站才能浏览,关掉的话就开不了了。之所以不了解这个,大概我还没研究过hugo的原理。之所以我在本地测试WordPress的时候可以一直开网站是因为虚拟的那个东西其实一直都常驻我的电脑。同样是本地测试,静态网站的生成速度以及网页打开速度比WordPress快非常多。如果只是几篇文章,生成网站的速度是毫秒级的,基本上就是一眨眼的功夫。昨天我测试了,生成200多篇文章的网站,也非常快,只需0.5秒。但是,如果网站有9000多篇文章呢,到底需要多长时间生成?这个我还没测试出来。因为我那9000多篇文章还没有完全符合的hugo框架的要求。

要用Hugo建立静态网站,如果是从零开始,当然很简单,按照他们的规则去写就可以了,但对我来说,我不是从零开始的,之所以用这个东西是因为生成速度快,而且可以挂在免费的空间上面。因为我的老blog很多,所以我必须要找一个这样的地方。如果我仍然使用WordPress,显然就非常浪费资源了。静态网站跟动态网站最大的区别,我觉得是静态网站不自带评论功能。几乎可以这么说,静态网站如果不外挂,是无法交流的。因为我挂的是老blog已经早就不去更新了,从前那些挂着blog的BSP都已经全部没了。我会在静态blog上留下可以交流的链接,如果有需要,访客可以找到我的blog,然后留言。这样的好处是起码你还能找到我,但坏处就是,你不能在你感兴趣的那个地方直接留言。去到我的blog还得解释你是从哪里来的,这就比较麻烦。但换个思路,我把那些已经不存在的东西重新又翻出来让你见到,其实已经很不容易了。

hugo的建站不难,但是如何把核心内容转化为hugo适配的不容易。我要把XML格式的大文档转化为一篇一边的markdown文档,这个星期我都在折腾这个。我本想直接用一个python脚本解决所有问题,因为理论上这是相当简单的操作,但是我却发现能搜索的python脚本,根本不适合我。有些已经老掉牙了,用的是python 2的版本,我试着转版本,让失败了,因为我实在不知道,里面的某些操作到底在新版本里是怎么个整法。

经历XML转化为另外一种格式的XML之后,我对XML这个东西算是有点了解了,我个人觉得输出markdown其实要比XML格式互转简单一些。XML互转只需要输出一个文件,但是markdown要生成无数个文件。python的操作之中,我最生疏的就是文件处理。输入输出那一章书我觉得自己根本没毕业。现成的python脚本无法满足我,我得自寻出路。幸好有一个叫做html2text python模块拯救了我,这个东西解决了从html到markdown的转换,所以正文最核心的东西的转化已经不成问题了,虽然里面还有一些说不准什么时候会出现的状况,但总体来说效果不错。XML的格式转化如果有一些我不想转义的东西,我还能用cdata把那些都圈起来,圈起来以后就没烦恼了,但是用markdown文件在hugo建站,必须有一个YAML的开头,而那个东西是有严格的格式限制的。篇名、分类和标签都必须严格符合这些要求。因为我的网址输出用的是python的时间戳,完全是数字,所以没烦恼,一开始的时候,文档的文件名我用的是时间加篇名,但因为片名的幺蛾子太多,所以,我选择了用纯粹的时间,单位精确到秒。如果不是手动设置过时间,不会发生重复。接下来我需要做的是整一套替换列表。把里面严格限制不让用的东西全部整理一遍。这样才能保证hugo的网站里能生成了我的全部东西,而不会有些不合规则的直接被屏蔽掉。WordPress没有这种烦恼,顶多出来的东西乱码而已,只要我把可能乱码的东西全部cdata。简直爽歪歪。之所以可以这样,是因为我把数据导入到WordPress的时候,软件默认把我不规范的东西规范化了,现在这个步骤,我完全得靠自己。

虽然现在我生成的文件还不能100%的符合hugo的要求,但从完全不会到可以生成,而且大多还是合格的,能做到这个我已经很满意。

2020-06
23

做到了

By xrspook @ 10:27:38 归类于: 烂日记

昨天我终于用python写出了把点点转化为WordPress的脚本。这个东西我确信是可行的,因为python的转换过程中没有出错,这就证明没有遇到奇怪的事情。用别人脚本的时候,把转换好的文件上传到WordPress,我总会担心不成功,但我自己写的脚本,我知道该注意些什么,哪些参数是现在的WordPress必须要求有的,所以只要python的转换不出错,我的WordPress导入就不会有问题。因为点点的文章有9000多篇,要从后台管理界面导入到WordPress,会非常耗时间。如果一篇文章需要两秒,完全导入就需要5个多小时,所以我没有做这种事。我挑选出22篇,各个类型都有的,试验导入,结果非常成功,网页的效果也很好,完全按照我的意思生成了。我觉得如果要快速解决问题,估计我得在数据库端导入。之前把文章导入到WordPress,因为要尝试不同的版本,我得不断地导入删除,但删除的文章太多的时候,速度很慢。后来我暴力地在数据库那里直接写删除语句,结果秒杀就完成了。现在我发现了一个更干净的方法。直接把关联WordPress的数据库里的内容全部删掉,这也是一个秒杀的过程,而且绝对不会留下任何的手尾,比如文章删除了,但是分类和标签仍然在那里。可能某些东西已经不存在了,但是计数还停留在一个很大数值,之所以这样,肯定是因为我删除文章的时候不够艺术。与其让里面留那么多乱七八糟的东西,还不如直接把数据库清空。因为我这是单机上的WordPress,我纯粹只是用来测试。这样的删除是最快捷的。大概我从上周,才突然领悟出可以这样。别人之所以要在数据库里写语句删除文章或者标签,是因为不能删掉一些不应该删掉的东西,但我没有这个顾虑。既然在数据库层面可以快速的删除,那么理论上也应该可以从数据库层面快速的导入。之所以有这个想法,是因为我发现WordPress的插件有些是针对数据库的,有些是针对WordPress自带函数的,数据库层面的查询要自带函数快非常多。现在我已经学会了转换适配后台界面导入的文件格式转换。下一步大概我得学习一下如何在数据库层面进行导入。这么高端的做法,貌似之前我还没有听说过。在网站迁移的时候,的确是把数据库打包,然后重新放到别的地方的,但那个数据库是本来就已经存在的。从一个地方挪到另外一个地方,原封不动地,但是我却要把大量的数据以快速的方式导入到数据库,并且还得按照WordPress的脾性建立各种关联,显然这貌是非常不简单,但理论上应该可以做到。

我不知道我的python到底学成怎样了,但起码我可以用那个东西实现我自己的愿望。相比于书本的习题,我觉得实现自己的愿望更有成就感,虽然其中有很多问题完全只能靠自己,没有参考答案。虽然总的来说,脚本不是我一个人写的,我是站在巨人的肩膀上修改而成,但BlogBus和点点的结构还是有差异的。最幸运的是某些我不知道该用什么手段实现的东西前人已经给我指明了方向。昨天我只是把脚本写出来了,接下来我要把脚本优化,一些老是翻来覆去说的句子完全可以把那作为自定义函数。到底什么东西应该泛化,应该泛化到什么程度,这个我还没有想好。昨天之所以可以这么迅速地完成任务,大概是因为在我开始之前先做了个思维导图,明确了我到底要做些什么。基础数据有哪些,应该在哪里取数,需要判断的参数有哪些,各自的参数有什么特性,能不能合并同类项。之前我就写过类似的东西,但是跟思维导图比起来,之前我写的那个真的很水。有思维导图、有专业的思维导图软件,人的思路可以非常快地展开。整体定下来,下面的事情就只剩下一步一步地实现。我做梦也没想到,自己这次居然这么高效。某些我没有把握能快速解决好的问题,昨天不知道为什么很多都迎刃而解了。转换一个30多MB的XML文件,我用了16秒。转换出来的文件大小为22MB。我觉得应该可以更快,但怎么才能更快呢?文件里的数据结构是我没有考虑过的,我是不是应该从那里入手?一些相同的判断,大概我应该做一些合并。

追求更好是没有尽头的。

2020-06
18

BlogBus 2 WordPress – by xrspook

By xrspook @ 19:50:07 归类于: 扮IT

为什么要学习python?因为我见识过python有多牛逼,简单一个脚本文件,轻量级的东西实现强大的功能。因为要做XML文件的格式转换,所以我觉得我要学好python。Think Python 2看到第14章,我就转向去研究10年多以前网友写的BlogBus转WordPress的python脚本。之所以要研究,因为当时的WordPress格式和现在不一样,用以前的脚本转换出来的东西已经没办法直接导入到现在的WordPress里了。再去找写代码的那些人,有些网站还在,但有些已经消失了。我不能等待别人拯救我,我只能自己拯救自己。

我需要转换格式的是“回到过去——Betty迷的独白”和“Mi Internacional Cielo”,这两个旧BlogBus站点和我的主站“我的天”不一样,虽然里面有不少我原创的东西,但我从四面八方搜集回来的内容也不少。当时的BlogBus默认编辑界面是富文本,我看上去觉得格式没问题大概就可以了,但实际上格式是有问题的。从五湖四海搜集回来的文字里面怎么可能不夹杂各种格式,那些东西在富文本编辑下可能看不出来,但在源代码界面一团糟。如果当年我复制粘贴的时候有先去记事本过渡一下就不会有那么多的问题。所以除了要转换BlogBus和WordPress的标签以外我还要筛选删除那些坏事的源代码。

经过接近一周的努力,我终于整出来了。运行下面的python3脚本,如果能顺利完成,自动生成出新的XML文件,用官方途径导入WordPress 5.4.2是完全没有问题的,但我只测试了我自己的两个blog,是不是兼容其它我不知道。因为转换blog我是有自己的想法的,所以脚本中有一些个性化的东西,比如我把blog的标题变成了分类,把原来的分类变成了标签。脚本中有大量的反转义替换,主要是为了人去看CDATA的时候不太头晕迷糊,因为我那两个旧blog里有大量的西班牙语字符,不同的编码下,BlogBus的导出文件里有些被转义了有些没有。那些转义了的放到WordPress里不知道WordPress会不会转回来,我试过标题被BlogBus转义之后WordPress不会转回来,看得我云里雾里。因为转义很头痛,所以除了少数几个内容,有可能被转义的文字都被我用CDATA包裹了起来。

脚本不是我一个人的功劳,我只是在当年网友脚本的基础上做了调整,使之适配python3和WordPress 5.4.2。

我的脚本:xbus2wp.py (PS:下面脚本330行的《/p》是什么鬼怪!WordPress的脚本插件在搞什么!)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
'''
***使用说明***
终端界面输入xbus2wp.py bus.xml xrspook。其中:
xbus2wp.py为脚本名字,bus.xml为BlogBus导出文件,xrspook为博主名字,3个参数以空格分开
若运行无误,输出的文件名为[原文件名_xbus2wp.xml]
脚本基于python3,适配WordPress 5.4.2(2020-06-18)
'''
 
import re, sys, getopt, datetime
from xml.dom import minidom
from time import time
 
def convert(inputFileName, owner, order='asc'):
    """"""
    try:
        xmldoc = minidom.parse(inputFileName)
    except Exception as e:
        print ('Fail.')
        print (e)
        print ('Please repair or delete invalid token like "& < >" there.')
        sys.exit(1)
 
    bus = xmldoc.documentElement
    logs = bus.getElementsByTagName('Log')
 
    dom = minidom.Document()
    rss = dom.createElement('rss') # rss是root,根元素
    dom.appendChild(rss)      
    rss.setAttribute('version', '2.0')
    rss.setAttribute('xmlns:content', 'http://purl.org/rss/1.0/modules/content/')
    rss.setAttribute('xmlns:wfw', 'http://wellformedweb.org/CommentAPI/')
    rss.setAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/')
    rss.setAttribute('xmlns:wp', 'http://wordpress.org/export/1.0/')
    channel = dom.createElement('channel')
    rss.appendChild(channel)
    wxr_version = dom.createElement('wp:wxr_version') # 加入wxr戳,无戳无法进行WordPress导入
    channel.appendChild(wxr_version)
    wxr_version_node = dom.createTextNode('1.1')
    wxr_version.appendChild(wxr_version_node)
 
    busname = bus.getElementsByTagName('BlogName')[0] # 提取原BlogBus名字
    busname_text = getElementData(busname).replace(' ', '_')
 
    # create a list to contain items instead of appending them to
    # channel directly in order to sort them of lately according to order.
    if order == 'desc':
        item_list = []
    else:
        item_list = None
 
    for log in logs:
        title = log.getElementsByTagName('Title')[0]
        title_text = getElementData(title)
        content = log.getElementsByTagName('Content')[0]
        content_text = getElementData(content)
        logdate = log.getElementsByTagName('LogDate')[0]
        pubdate = getElementData(logdate)
        writer = log.getElementsByTagName('Writer')[0]
        creator = owner # BlogBus的writer根本没包含元素!
        category = getElementData(log.getElementsByTagName('Sort')[0])
        tagi = log.getElementsByTagName('Tags')[0]
        tags = getElementData(tagi).split(' ')
        new_tags = unique_tag(category, tags) # 新的wp标签里包含了原BlogBus里的分类与标签
        comments = log.getElementsByTagName('Comment')
 
        #-----
        item = dom.createElement('item')
 
        # handle title
        title_element = createElement(dom, 'title', title_text, 'cdata')
        item.appendChild(title_element)
 
        # handle type
        type_element = createElement(dom, 'wp:post_type', 'post', 'cdata')
        item.appendChild(type_element)
 
        # handle pubdate
        pubdate_element = createElement(dom, 'pubDate', convertPubDate(pubdate))
        item.appendChild(pubdate_element)
 
        # handle creator
        creator_element = createElement(dom, 'dc:creator', creator, 'cdata')
        item.appendChild(creator_element)
 
        # handle categories with domain
        category_element = createElement(dom, 'category', busname_text, 'cdata') # 把BlogBus标题设置为分类,因为我要合并多个旧blog
        category_element.setAttribute('domain','category')
        category_element.setAttribute('nicename', busname_text)
        item.appendChild(category_element)
 
        # handle tags
        for tag in new_tags:
            tag = tag.replace('&ntilde;', 'n')
            tag = tag.replace('summary_of_BLF', 'summary_of_BLF(from_rincondebetty)')
            tag = tag.replace('summary_of_EcoModa', 'summary_of_EcoModa(from_rincondebetty)')
            category_element = createElement(dom, 'category', tag, 'cdata')
            category_element.setAttribute('domain','post_tag')
            category_element.setAttribute('nicename', tag)
            item.appendChild(category_element)
 
        # handle content
        content_element = createElement(dom, "content:encoded", content_text, 'cdata')        
        item.appendChild(content_element)
 
        # handle post_date
        post_date_element = createElement(dom, "wp:post_date", pubdate)
        item.appendChild(post_date_element)
 
        # handle status
        status_element = createElement(dom, "wp:status", 'publish')
        item.appendChild(status_element)
 
        # handle comments
        if comments:
            commentElements = createComments(dom, comments)
            for commentElement in commentElements:
                item.appendChild(commentElement)
 
        if item_list != None:
            item_list.append(item)
        else:
            channel.appendChild(item)
 
    if item_list:
        item_list.reverse()
        for m in item_list:
            channel.appendChild(m)
 
    global filename # 输出设置
    output = filename + '_xbus2wp.xml'
    f = open(output ,'wb+')
    import codecs
    writer = codecs.lookup('utf-8')[3](f)
    dom.writexml(writer, '', ' ' * 4, '\n', encoding='utf-8')
    writer.close()
 
def unique_tag(category,tags): # 只保留唯一的标签
    category = category.replace(' ', '_')
    l = category.split() + tags
    new_l = []
    for item in l:
        if item not in new_l and item != '(from_rincondebetty)':
            new_l.append(item.replace(' ', '_')) # 替换空格为下划线
    return new_l
 
def getElementData(element): # 获取节点数据
    """"""
    data = ''
    for node in element.childNodes:
        if node.nodeType in (node.TEXT_NODE, node.CDATA_SECTION_NODE):
            data += node.data
    return data
 
def createComments(dom, comments):
    """"""
    l = []
    count = 0
    for comment in comments:
        count += 1 # 每篇文章的评论序号,没有序号,评论只能导入每篇最后一条
        email = comment.getElementsByTagName('Email')[0]
        homepage = comment.getElementsByTagName('HomePage')[0]
        name = comment.getElementsByTagName('NiceName')[0]
        content = comment.getElementsByTagName('CommentText')[0]
        date = comment.getElementsByTagName('CreateTime')[0]
        comment_element = createCommentElement(count, dom, email, homepage, name, content, date)
        l.append(comment_element)
    return l
 
def createCommentElement(count, dom, email, homepage, name, content, date):
    """"""
    comment_author = getElementData(name)
    comment_author_email = getElementData(email)
    comment_author_url = getElementData(homepage)
    comment_date = getElementData(date)
    comment_content = getElementData(content)
 
    comment_id_element = createElement(dom, 'wp:comment_id', str(count))
    comment_author_element = createElement(dom, 'wp:comment_author', comment_author)
    comment_author_email_element = createElement(dom, 'wp:comment_author_email', comment_author_email)
    comment_author_url_element = createElement(dom, 'wp:comment_author_url', comment_author_url)
    comment_date_element = createElement(dom, 'wp:comment_date', comment_date)
    comment_date_gmt_element = createElement(dom, 'wp:comment_date_gmt', comment_date)
    comment_content_element = createElement(dom, 'wp:comment_content', comment_content, 'cdata')
    comment_approved_element = createElement(dom, 'wp:comment_approved', '1')
 
    # make the comment element
    comment_element = dom.createElement('wp:comment')
    comment_element.appendChild(comment_id_element)
    comment_element.appendChild(comment_author_element)
 
    # validate email and url
    validEmail = validateEmail(comment_author_email)
    if (validEmail):
        comment_element.appendChild(comment_author_email_element)
 
    validUrl = validateUrl(comment_author_url)
    if (validUrl):
        comment_element.appendChild(comment_author_url_element)    
 
    comment_element.appendChild(comment_date_element)
    comment_element.appendChild(comment_date_gmt_element)
    comment_element.appendChild(comment_content_element)
    comment_element.appendChild(comment_approved_element)
 
    return comment_element
 
def createElement(dom, elementName, elementValue, type='text'): #建立节点标签和节点
    """"""
    global owner
    tag = dom.createElement(elementName)
    if elementValue.find(']]>') > -1:
        type = 'text'
    if type == 'text':
        text = dom.createTextNode(elementValue)
    elif type == 'cdata':
        elementValue = elementValue.replace('&amp;', '&')
        elementValue = elementValue.replace('&lt;', '<')
        elementValue = elementValue.replace('&gt;', '>')
        elementValue = elementValue.replace('&apos;', '\'')
        elementValue = elementValue.replace('&quot;', '"')
 
        # 大量替换与我的旧blog有各种编码的西班牙语字符有关
        elementValue = elementValue.replace('&copy;', '') # 版权标志
        elementValue = elementValue.replace('&nbsp;', '') # 空格
        elementValue = elementValue.replace('&ldquo;', '“') # 左双引号
        elementValue = elementValue.replace('&rdquo;', '”') # 右双引号
        elementValue = elementValue.replace('&lsquo;', '‘') # 左单引号
        elementValue = elementValue.replace('&rsquo;', '’') # 右单引号
        elementValue = elementValue.replace('&acute;', '´') # 单引号
        elementValue = elementValue.replace('&hellip;', '...') # 省略号
        elementValue = elementValue.replace('&mdash;', '—') # 破折号
        elementValue = elementValue.replace('&middot;', '·') # 分隔号
        elementValue = elementValue.replace('&deg;', '°') # 单位度
        elementValue = elementValue.replace('&iexcl;', '¡') # 西班牙语反叹号
        elementValue = elementValue.replace('&iquest;', '¿') # 西班牙语反问号
        elementValue = elementValue.replace('&ntilde;', 'ñ') # 西班牙语n
        elementValue = elementValue.replace('&Ntilde;', 'Ñ') # 西班牙语N
        elementValue = elementValue.replace('&aacute;', 'á') # 西班牙语a
        elementValue = elementValue.replace('&eacute;', 'é') # 西班牙语e
        elementValue = elementValue.replace('&iacute;', 'í') # 西班牙语i
        elementValue = elementValue.replace('&oacute;', 'ó') # 西班牙语o
        elementValue = elementValue.replace('&uacute;', 'ú') # 西班牙语u
        elementValue = elementValue.replace('&Aacute;', 'Á') # 西班牙语A
        elementValue = elementValue.replace('&Eacute;', 'É') # 西班牙语E
        elementValue = elementValue.replace('&Iacute;', 'Í') # 西班牙语I
        elementValue = elementValue.replace('&Oacute;', 'Ó') # 西班牙语O
        elementValue = elementValue.replace('&Uacute;', 'Ú') # 西班牙语U
        elementValue = elementValue.replace('&Atilde;', 'Ã') # 西班牙语A~
        elementValue = elementValue.replace('&ordf;', 'ª') # 西班牙语上标a
        elementValue = elementValue.replace('&ordm;', 'º') # 西班牙语上标o
 
        elementValue = elementValue.replace('<!--msnavigation-->', '')
        elementValue = elementValue.replace('博主', owner)
        elementValue = elementValue.replace('<i>', '')
        elementValue = elementValue.replace('</i>', '')
        elementValue = elementValue.replace('<br /><br />', '<br />')
 
        elementValue = re.sub(r"(?:<\?xml.*?>)", "", elementValue)
        elementValue = re.sub(r"(?:<[TDSFHI].*?>)", "", elementValue)
        elementValue = re.sub(r"(?:<\/[TDSFHI].*?>)", "", elementValue)
        elementValue = re.sub(r"(?:<P.*?>)", "<p>", elementValue)
        elementValue = re.sub(r"(?:<(table|tbody|tr|td|div|span|img|script|font|hr|object|param).*?>)", "", elementValue)
        elementValue = re.sub(r"(?:<\/(table|tbody|tr|td|div|span|img|script|font|object).*?>)", "", elementValue)
        elementValue = re.sub(r"\n", "", elementValue) # 把替换造成的空行删除
 
        text = dom.createCDATASection(elementValue)
    tag.appendChild(text)
    return tag
 
def convertPubDate(date, timediff='+0000'):
    """
    convert 2003-08-22 16:01:56
    to Thu, 23 Aug 2007 05:47:54 +0000
    """
    year, mon, day = int(date[:4]), int(date[5:7]), int(date[8:10])
    time = date[11:]
    aday = datetime.datetime(year, mon, day)
    d = {'1':'Mon', '2':'Tus', '3':'Wen', '4':'Thur', '5':'Fri', '6':'Sat', '7':'Sun'}
    m = {'1':'Jan', '2':'Feb', '3':'Mar', '4':'Apr', '5':'May', '6':'Jun',
         '7':'Jul', '8':'Aug', '9':'Sep', '10':'Oct', '11':'Nov', '12':'Dec'}
    weekday = d[str(aday.isoweekday())]
    month = m[str(mon)]
    pubdate = "%s, %d %s %s %s %s" % (weekday, day, month, year, time, timediff)
    return pubdate
 
def validateEmail(email):
    '''
    '''
    pattern = r'^[0-9a-z][_.0-9a-z-]{0,31}@([0-9a-z][0-9a-z-]{0,30}[0-9a-z]\.){1,4}[a-z]{2,4}$'
    p = re.compile(pattern)
    m = p.match(email)
    if m:
        return True
    else:
        return False
 
def validateUrl(url):
    '''
    '''
    pattern = r'^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$'
    p = re.compile(pattern)
    m = p.match(url)
    if m:
        return True
    else:
        return False
 
def main(argv=None):    
    global filename
    global owner
 
    if argv is None:
        argv = sys.argv
    # parse command line options
 
    args = sys.argv[1:]
    order='asc'
    if (len(args) == 2):
        print ('Converting...'),
        sys.stdout.flush()
        start = time()
        filename = args[0].replace('.xml', '')
        owner = args[1] # BlogBus没把博主名字输出,只能手动
        convert(args[0], args[1], order)
        end = time()
        print ('Done. Elapse %g seconds.' % (end - start))
 
if __name__ == "__main__":
    sys.exit(main())
</p>
© 2004 - 2020 我的天 | Theme by xrspook | Power by WordPress