Attachment 'wordpress2blogger.py'
Download 1 # blogger wordpress api libraries
2 # Author: Yichao Zhang
3 # Email: [email protected]
4
5
6 import httplib
7 import urllib
8 import xmlrpclib
9 import time
10 from xmlrpclib import Error
11
12 # set debug mode
13 DEBUG = False
14 myencoding = 'utf-8'
15
16 # set your wordpress username, password, xmlrpc url
17 wp_username = 'admin'
18 wp_passwd = 'mypwd'
19 wp_url = 'http://localhost/wordpress/xmlrpc.php'
20
21 # set your blogger email, password, blogid
22 # blogid is in your blogspot Dashboard url, for example:
23 # http://www2.blogger.com/posts.g?blogID=18083698, "18083698" is your blogid.
24 blogger_email = '[email protected]'
25 blogger_passwd = 'mypwd'
26 blogger_blogid = '18083698'
27
28 # set how many recent posts do you want to import from wordpress to blogger
29 wp_recent_posts_num = 5
30 # set how many times do you want to try if it fails to post to blogger
31 tryCounter = 3
32
33 class SyncWorker:
34 def main(self):
35 wp = WordpressClient(wp_username, wp_passwd, wp_url)
36 blogs = wp.getRecentPosts(wp_recent_posts_num)
37
38 clientLogin = GoogleClientLogin(blogger_email, blogger_passwd, 'blogger', 'easter.blogsync')
39 auth = clientLogin.getAuth()
40 bg = BloggerClient(auth, blogger_blogid)
41
42 failedList = []
43 for blog in blogs:
44 title = blog['title'].encode(myencoding)
45 content = blog['description'].encode(myencoding)
46 labels = ','.join([c for c in blog['categories']]).encode(myencoding)
47 publishedDate = blog['dateCreated']
48 postid = blog['postid']
49 entry = Entry(title, content, labels, publishedDate)
50 print '>>>> starting postid == %s' % postid
51 print '>>>> ........ title == %s' % title
52 isSuccessfull = bg.insertEntry(entry)
53 counter = tryCounter;
54 while counter > 0 and not isSuccessfull:
55 print 'post failed, try again!'
56 isSuccessfull = bg.insertEntry(entry)
57 counter -= 1
58 if isSuccessfull:
59 print '>>>> post successfully\n'
60 else:
61 failedList.append(postid)
62 print '>>>> post unsuccessfully\n'
63 if failedList:
64 print '>>>> these posts not added:'
65 print failedList
66
67 class GoogleClientLogin:
68 def __init__(self, email, passwd, service, source):
69 params = urllib.urlencode({'Email': email, 'Passwd': passwd, 'service': service, 'source': source})
70 headers = {"Content-type": "application/x-www-form-urlencoded"}
71 conn = httplib.HTTPSConnection("www.google.com")
72 conn.request("POST", "/accounts/ClientLogin", params, headers)
73 response = conn.getresponse()
74 data = response.read()
75 # failed
76 if response.status == 403:
77 self.auth = None
78 else:
79 self.auth = data.splitlines()[2].split('=')[1]
80 conn.close()
81
82 def getAuth(self):
83 return self.auth
84
85 class BloggerClient:
86 def __init__(self, auth, blogid):
87 self.auth = auth
88 self.blogid = blogid
89 self.host = 'www.blogger.com'
90 self.path = '/feeds/%s/posts/default' % (self.blogid)
91
92 def insertEntry(self, entry):
93 return self.insertEntryXML(entry.getEntryXML(), self.host, self.path)
94
95 def insertEntryXML(self, entryXML, host, path):
96 headers = {"Authorization": "GoogleLogin auth=%s" % self.auth, "Content-type": "application/atom+xml"}
97 conn = httplib.HTTPConnection(self.host)
98 conn.request("POST", self.path, entryXML, headers)
99 data = conn.getresponse()
100 if DEBUG:
101 print '>>>> response.status == %s' % data.status
102 print '>>>> blogger server response:'
103 print data.read()
104 if data.status == 302:
105 location = data.getheader('location')[7:].split('/', 1)
106 host = location[0]
107 path = '/' + location[1]
108 self.insertEntryXML(entryXML, host, path)
109 elif data.status == 201:
110 return True
111 else:
112 return False
113
114 class Entry:
115 def __init__(self, title, content, labels, publishedDate):
116 self.title = title
117 self.content = content
118 self.labels = labels
119 self.publishedDate = publishedDate
120
121 def getLabelXML(self, label):
122 return '<category scheme="http://www.blogger.com/atom/ns#" term="%s"/>' % label
123
124 def __getLabelsXML(self):
125 return ''.join([self.getLabelXML(label) for label in self.labels.split(',')])
126
127 def __getPublishedDate(self):
128 date = str(self.publishedDate)
129 timezone = time.timezone
130 if timezone > 0:
131 sign = '-'
132 else:
133 sign = '+'
134 timezone = -timezone
135 tzHours = timezone/3600
136 tzMinutes = timezone % 3600 / 60
137 return '%(year)s-%(month)s-%(other)s%(sign)s%(hours)02d:%(minutes)02d' % \
138 {'year':date[0:4], 'month':date[4:6], 'other':date[6:], 'sign':sign, 'hours':tzHours, 'minutes':tzMinutes}
139
140 def getEntryXML(self):
141 entryXML = \
142 '''
143 <entry xmlns='http://www.w3.org/2005/Atom'>
144 <title type='text'><![CDATA[%s]]></title>
145 <published>%s</published>
146 %s
147 <content type="text"><![CDATA[%s]]></content>
148 </entry>
149 ''' % (self.title, self.__getPublishedDate(), self.__getLabelsXML(), self.content)
150 return entryXML
151
152 class WordpressClient:
153 def __init__(self, username, passwd, url):
154 self.username = username
155 self.passwd = passwd
156 self.url = url
157 self.wp = xmlrpclib.ServerProxy(url)
158 def getRecentPosts(self, num):
159 try:
160 blogs = self.wp.metaWeblog.getRecentPosts('', self.username, self.passwd, num)
161 except Error, v:
162 print v
163 return blogs
164
165 if __name__ == "__main__":
166 SyncWorker().main()
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.