/gdata/blogger/__init__.py
Python | 202 lines | 156 code | 12 blank | 34 comment | 0 complexity | 28871d5579cab9d637808bc30ffa10c0 MD5 | raw file
1#!/usr/bin/python 2# 3# Copyright (C) 2007, 2008 Google Inc. 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17 18"""Contains extensions to Atom objects used with Blogger.""" 19 20 21__author__ = 'api.jscudder (Jeffrey Scudder)' 22 23 24import atom 25import gdata 26import re 27 28 29LABEL_SCHEME = 'http://www.blogger.com/atom/ns#' 30THR_NAMESPACE = 'http://purl.org/syndication/thread/1.0' 31 32 33class BloggerEntry(gdata.GDataEntry): 34 """Adds convenience methods inherited by all Blogger entries.""" 35 36 blog_name_pattern = re.compile('(http://)(\w*)') 37 blog_id_pattern = re.compile('(tag:blogger.com,1999:blog-)(\w*)') 38 blog_id2_pattern = re.compile('tag:blogger.com,1999:user-(\d+)\.blog-(\d+)') 39 40 def GetBlogId(self): 41 """Extracts the Blogger id of this blog. 42 This method is useful when contructing URLs by hand. The blog id is 43 often used in blogger operation URLs. This should not be confused with 44 the id member of a BloggerBlog. The id element is the Atom id XML element. 45 The blog id which this method returns is a part of the Atom id. 46 47 Returns: 48 The blog's unique id as a string. 49 """ 50 if self.id.text: 51 match = self.blog_id_pattern.match(self.id.text) 52 if match: 53 return match.group(2) 54 else: 55 return self.blog_id2_pattern.match(self.id.text).group(2) 56 return None 57 58 def GetBlogName(self): 59 """Finds the name of this blog as used in the 'alternate' URL. 60 An alternate URL is in the form 'http://blogName.blogspot.com/'. For an 61 entry representing the above example, this method would return 'blogName'. 62 63 Returns: 64 The blog's URL name component as a string. 65 """ 66 for link in self.link: 67 if link.rel == 'alternate': 68 return self.blog_name_pattern.match(link.href).group(2) 69 return None 70 71 72class BlogEntry(BloggerEntry): 73 """Describes a blog entry in the feed listing a user's blogs.""" 74 75 76def BlogEntryFromString(xml_string): 77 return atom.CreateClassFromXMLString(BlogEntry, xml_string) 78 79 80class BlogFeed(gdata.GDataFeed): 81 """Describes a feed of a user's blogs.""" 82 83 _children = gdata.GDataFeed._children.copy() 84 _children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry', [BlogEntry]) 85 86 87def BlogFeedFromString(xml_string): 88 return atom.CreateClassFromXMLString(BlogFeed, xml_string) 89 90 91class BlogPostEntry(BloggerEntry): 92 """Describes a blog post entry in the feed of a blog's posts.""" 93 94 post_id_pattern = re.compile('(tag:blogger.com,1999:blog-)(\w*)(.post-)(\w*)') 95 96 def AddLabel(self, label): 97 """Adds a label to the blog post. 98 99 The label is represented by an Atom category element, so this method 100 is shorthand for appending a new atom.Category object. 101 102 Args: 103 label: str 104 """ 105 self.category.append(atom.Category(scheme=LABEL_SCHEME, term=label)) 106 107 def GetPostId(self): 108 """Extracts the postID string from the entry's Atom id. 109 110 Returns: A string of digits which identify this post within the blog. 111 """ 112 if self.id.text: 113 return self.post_id_pattern.match(self.id.text).group(4) 114 return None 115 116 117def BlogPostEntryFromString(xml_string): 118 return atom.CreateClassFromXMLString(BlogPostEntry, xml_string) 119 120 121class BlogPostFeed(gdata.GDataFeed): 122 """Describes a feed of a blog's posts.""" 123 124 _children = gdata.GDataFeed._children.copy() 125 _children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry', [BlogPostEntry]) 126 127 128def BlogPostFeedFromString(xml_string): 129 return atom.CreateClassFromXMLString(BlogPostFeed, xml_string) 130 131 132class InReplyTo(atom.AtomBase): 133 _tag = 'in-reply-to' 134 _namespace = THR_NAMESPACE 135 _attributes = atom.AtomBase._attributes.copy() 136 _attributes['href'] = 'href' 137 _attributes['ref'] = 'ref' 138 _attributes['source'] = 'source' 139 _attributes['type'] = 'type' 140 141 def __init__(self, href=None, ref=None, source=None, type=None, 142 extension_elements=None, extension_attributes=None, text=None): 143 self.href = href 144 self.ref = ref 145 self.source = source 146 self.type = type 147 self.extension_elements = extension_elements or [] 148 self.extension_attributes = extension_attributes or {} 149 self.text = text 150 151 152def InReplyToFromString(xml_string): 153 return atom.CreateClassFromXMLString(InReplyTo, xml_string) 154 155 156class CommentEntry(BloggerEntry): 157 """Describes a blog post comment entry in the feed of a blog post's 158 comments.""" 159 160 _children = BloggerEntry._children.copy() 161 _children['{%s}in-reply-to' % THR_NAMESPACE] = ('in_reply_to', InReplyTo) 162 163 comment_id_pattern = re.compile('.*-(\w*)$') 164 165 def __init__(self, author=None, category=None, content=None, 166 contributor=None, atom_id=None, link=None, published=None, rights=None, 167 source=None, summary=None, control=None, title=None, updated=None, 168 in_reply_to=None, extension_elements=None, extension_attributes=None, 169 text=None): 170 BloggerEntry.__init__(self, author=author, category=category, 171 content=content, contributor=contributor, atom_id=atom_id, link=link, 172 published=published, rights=rights, source=source, summary=summary, 173 control=control, title=title, updated=updated, 174 extension_elements=extension_elements, 175 extension_attributes=extension_attributes, text=text) 176 self.in_reply_to = in_reply_to 177 178 def GetCommentId(self): 179 """Extracts the commentID string from the entry's Atom id. 180 181 Returns: A string of digits which identify this post within the blog. 182 """ 183 if self.id.text: 184 return self.comment_id_pattern.match(self.id.text).group(1) 185 return None 186 187 188def CommentEntryFromString(xml_string): 189 return atom.CreateClassFromXMLString(CommentEntry, xml_string) 190 191 192class CommentFeed(gdata.GDataFeed): 193 """Describes a feed of a blog post's comments.""" 194 195 _children = gdata.GDataFeed._children.copy() 196 _children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry', [CommentEntry]) 197 198 199def CommentFeedFromString(xml_string): 200 return atom.CreateClassFromXMLString(CommentFeed, xml_string) 201 202