from datetime import datetime, tzinfo, timedelta from urllib2 import urlopen, Request import re ZERO = timedelta(0) HOUR = timedelta(hours=1) # A UTC class. class UTC(tzinfo): """UTC""" def utcoffset(self, dt): return ZERO def tzname(self, dt): return "UTC" def dst(self, dt): return ZERO utc = UTC() # A class capturing the platform's idea of local time. import time as _time STDOFFSET = timedelta(seconds = -_time.timezone) if _time.daylight: DSTOFFSET = timedelta(seconds = -_time.altzone) else: DSTOFFSET = STDOFFSET DSTDIFF = DSTOFFSET - STDOFFSET class LocalTimezone(tzinfo): def utcoffset(self, dt): if self._isdst(dt): return DSTOFFSET else: return STDOFFSET def dst(self, dt): if self._isdst(dt): return DSTDIFF else: return ZERO def tzname(self, dt): return _time.tzname[self._isdst(dt)] def _isdst(self, dt): tt = (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.weekday(), 0, -1) stamp = _time.mktime(tt) tt = _time.localtime(stamp) return tt.tm_isdst > 0 Local = LocalTimezone() HREF = re.compile("""href\\s*=\\s*['"]?([^'"> ]+)""", re.I) USER_AGENT = 'PythonBlogger/0.1' class Post: def __init__(self, title, text, date=None, draft=False, postId=None, postURL=None): self.title = title self.text = text self.draft = draft self.postId = postId self.postURL = postURL if date is None: date = datetime.utcnow().replace(tzinfo=utc) if date.tzinfo is None: date = date.replace(tzinfo=Local) self.date = date def as_atom(self): return """\ %s %s %s %s """ % ( USER_AGENT, self.date.strftime("%Y-%m-%dT%H:%M:%S%z"), self.title, self.text, str(self.draft).lower() ) class Blog: def __init__(self, blogId, user, password): self.blogId = blogId self.atomURL = 'https://www.blogger.com/atom/' + blogId self.headers = { 'Authorization':'BASIC '+(user+':'+password).encode('base64').strip(), 'User-Agent': USER_AGENT, 'Content-type':'application/xml', } def add(self, post): data = urlopen( Request(self.atomURL, post.as_atom(), self.headers) ).read() for match in HREF.finditer(data): link = match.group(1) if link.startswith(self.atomURL) and post.postId is None: post.postId = link[len(self.atomURL)+1:] elif post.postURL is None: post.postURL = link else: break