203 lines
6.2 KiB
Python
203 lines
6.2 KiB
Python
#!/usr/bin/python
|
|
#
|
|
# Copyright (C) 2007, 2008 Google Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
|
|
"""Contains extensions to Atom objects used with Blogger."""
|
|
|
|
|
|
__author__ = 'api.jscudder (Jeffrey Scudder)'
|
|
|
|
|
|
import atom
|
|
import gdata
|
|
import re
|
|
|
|
|
|
LABEL_SCHEME = 'http://www.blogger.com/atom/ns#'
|
|
THR_NAMESPACE = 'http://purl.org/syndication/thread/1.0'
|
|
|
|
|
|
class BloggerEntry(gdata.GDataEntry):
|
|
"""Adds convenience methods inherited by all Blogger entries."""
|
|
|
|
blog_name_pattern = re.compile('(http://)(\w*)')
|
|
blog_id_pattern = re.compile('(tag:blogger.com,1999:blog-)(\w*)')
|
|
blog_id2_pattern = re.compile('tag:blogger.com,1999:user-(\d+)\.blog-(\d+)')
|
|
|
|
def GetBlogId(self):
|
|
"""Extracts the Blogger id of this blog.
|
|
This method is useful when contructing URLs by hand. The blog id is
|
|
often used in blogger operation URLs. This should not be confused with
|
|
the id member of a BloggerBlog. The id element is the Atom id XML element.
|
|
The blog id which this method returns is a part of the Atom id.
|
|
|
|
Returns:
|
|
The blog's unique id as a string.
|
|
"""
|
|
if self.id.text:
|
|
match = self.blog_id_pattern.match(self.id.text)
|
|
if match:
|
|
return match.group(2)
|
|
else:
|
|
return self.blog_id2_pattern.match(self.id.text).group(2)
|
|
return None
|
|
|
|
def GetBlogName(self):
|
|
"""Finds the name of this blog as used in the 'alternate' URL.
|
|
An alternate URL is in the form 'http://blogName.blogspot.com/'. For an
|
|
entry representing the above example, this method would return 'blogName'.
|
|
|
|
Returns:
|
|
The blog's URL name component as a string.
|
|
"""
|
|
for link in self.link:
|
|
if link.rel == 'alternate':
|
|
return self.blog_name_pattern.match(link.href).group(2)
|
|
return None
|
|
|
|
|
|
class BlogEntry(BloggerEntry):
|
|
"""Describes a blog entry in the feed listing a user's blogs."""
|
|
|
|
|
|
def BlogEntryFromString(xml_string):
|
|
return atom.CreateClassFromXMLString(BlogEntry, xml_string)
|
|
|
|
|
|
class BlogFeed(gdata.GDataFeed):
|
|
"""Describes a feed of a user's blogs."""
|
|
|
|
_children = gdata.GDataFeed._children.copy()
|
|
_children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry', [BlogEntry])
|
|
|
|
|
|
def BlogFeedFromString(xml_string):
|
|
return atom.CreateClassFromXMLString(BlogFeed, xml_string)
|
|
|
|
|
|
class BlogPostEntry(BloggerEntry):
|
|
"""Describes a blog post entry in the feed of a blog's posts."""
|
|
|
|
post_id_pattern = re.compile('(tag:blogger.com,1999:blog-)(\w*)(.post-)(\w*)')
|
|
|
|
def AddLabel(self, label):
|
|
"""Adds a label to the blog post.
|
|
|
|
The label is represented by an Atom category element, so this method
|
|
is shorthand for appending a new atom.Category object.
|
|
|
|
Args:
|
|
label: str
|
|
"""
|
|
self.category.append(atom.Category(scheme=LABEL_SCHEME, term=label))
|
|
|
|
def GetPostId(self):
|
|
"""Extracts the postID string from the entry's Atom id.
|
|
|
|
Returns: A string of digits which identify this post within the blog.
|
|
"""
|
|
if self.id.text:
|
|
return self.post_id_pattern.match(self.id.text).group(4)
|
|
return None
|
|
|
|
|
|
def BlogPostEntryFromString(xml_string):
|
|
return atom.CreateClassFromXMLString(BlogPostEntry, xml_string)
|
|
|
|
|
|
class BlogPostFeed(gdata.GDataFeed):
|
|
"""Describes a feed of a blog's posts."""
|
|
|
|
_children = gdata.GDataFeed._children.copy()
|
|
_children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry', [BlogPostEntry])
|
|
|
|
|
|
def BlogPostFeedFromString(xml_string):
|
|
return atom.CreateClassFromXMLString(BlogPostFeed, xml_string)
|
|
|
|
|
|
class InReplyTo(atom.AtomBase):
|
|
_tag = 'in-reply-to'
|
|
_namespace = THR_NAMESPACE
|
|
_attributes = atom.AtomBase._attributes.copy()
|
|
_attributes['href'] = 'href'
|
|
_attributes['ref'] = 'ref'
|
|
_attributes['source'] = 'source'
|
|
_attributes['type'] = 'type'
|
|
|
|
def __init__(self, href=None, ref=None, source=None, type=None,
|
|
extension_elements=None, extension_attributes=None, text=None):
|
|
self.href = href
|
|
self.ref = ref
|
|
self.source = source
|
|
self.type = type
|
|
self.extension_elements = extension_elements or []
|
|
self.extension_attributes = extension_attributes or {}
|
|
self.text = text
|
|
|
|
|
|
def InReplyToFromString(xml_string):
|
|
return atom.CreateClassFromXMLString(InReplyTo, xml_string)
|
|
|
|
|
|
class CommentEntry(BloggerEntry):
|
|
"""Describes a blog post comment entry in the feed of a blog post's
|
|
comments."""
|
|
|
|
_children = BloggerEntry._children.copy()
|
|
_children['{%s}in-reply-to' % THR_NAMESPACE] = ('in_reply_to', InReplyTo)
|
|
|
|
comment_id_pattern = re.compile('.*-(\w*)$')
|
|
|
|
def __init__(self, author=None, category=None, content=None,
|
|
contributor=None, atom_id=None, link=None, published=None, rights=None,
|
|
source=None, summary=None, control=None, title=None, updated=None,
|
|
in_reply_to=None, extension_elements=None, extension_attributes=None,
|
|
text=None):
|
|
BloggerEntry.__init__(self, author=author, category=category,
|
|
content=content, contributor=contributor, atom_id=atom_id, link=link,
|
|
published=published, rights=rights, source=source, summary=summary,
|
|
control=control, title=title, updated=updated,
|
|
extension_elements=extension_elements,
|
|
extension_attributes=extension_attributes, text=text)
|
|
self.in_reply_to = in_reply_to
|
|
|
|
def GetCommentId(self):
|
|
"""Extracts the commentID string from the entry's Atom id.
|
|
|
|
Returns: A string of digits which identify this post within the blog.
|
|
"""
|
|
if self.id.text:
|
|
return self.comment_id_pattern.match(self.id.text).group(1)
|
|
return None
|
|
|
|
|
|
def CommentEntryFromString(xml_string):
|
|
return atom.CreateClassFromXMLString(CommentEntry, xml_string)
|
|
|
|
|
|
class CommentFeed(gdata.GDataFeed):
|
|
"""Describes a feed of a blog post's comments."""
|
|
|
|
_children = gdata.GDataFeed._children.copy()
|
|
_children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry', [CommentEntry])
|
|
|
|
|
|
def CommentFeedFromString(xml_string):
|
|
return atom.CreateClassFromXMLString(CommentFeed, xml_string)
|
|
|
|
|