| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 |
|
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 23 |
from OFS.SimpleItem import SimpleItem |
|---|
| 24 |
from Products.CMFCore.utils import getToolByName |
|---|
| 25 |
from Products.CMFDefault.utils import parseHeadersBody |
|---|
| 26 |
from AccessControl import ClassSecurityInfo |
|---|
| 27 |
import DateTime |
|---|
| 28 |
|
|---|
| 29 |
authOneMethods = [ |
|---|
| 30 |
'blogger/getTemplate', |
|---|
| 31 |
'blogger/setTemplate', |
|---|
| 32 |
'blogger/deletePost', |
|---|
| 33 |
'blogger/editPost', |
|---|
| 34 |
'blogger/newPost', |
|---|
| 35 |
'blogger/getRecentPosts' |
|---|
| 36 |
] |
|---|
| 37 |
|
|---|
| 38 |
def genericBloggerAuthOne(args): |
|---|
| 39 |
return args[2],args[3],args |
|---|
| 40 |
|
|---|
| 41 |
|
|---|
| 42 |
authTwoMethods = [ |
|---|
| 43 |
'blogger/getUsersBlogs', |
|---|
| 44 |
'blogger/getUserInfo' |
|---|
| 45 |
] |
|---|
| 46 |
|
|---|
| 47 |
def genericBloggerAuthTwo(args): |
|---|
| 48 |
return args[1],args[2],args |
|---|
| 49 |
|
|---|
| 50 |
class BloggerAPI(SimpleItem): |
|---|
| 51 |
"""http://www.blogger.com/developers/api/1_docs/""" |
|---|
| 52 |
security = ClassSecurityInfo() |
|---|
| 53 |
|
|---|
| 54 |
def __init__(self, RPCAuth = None): |
|---|
| 55 |
"" |
|---|
| 56 |
if RPCAuth: |
|---|
| 57 |
self.setupRPCAuth(RPCAuth) |
|---|
| 58 |
|
|---|
| 59 |
security.declarePublic('setupRPCAuth') |
|---|
| 60 |
def setupRPCAuth(self, RPCAuth): |
|---|
| 61 |
RPCAuth.addAuthProvider(authOneMethods, genericBloggerAuthOne) |
|---|
| 62 |
RPCAuth.addAuthProvider(authTwoMethods, genericBloggerAuthTwo) |
|---|
| 63 |
|
|---|
| 64 |
security.declarePublic('newPost') |
|---|
| 65 |
def newPost(self, appkey, blogid, username, password, content, publish): |
|---|
| 66 |
"""blogger.newPost makes a new post to a designated blog. Optionally, |
|---|
| 67 |
will publish the blog after making the post. On success, it returns the |
|---|
| 68 |
unique ID of the new post. On error, it will return some error |
|---|
| 69 |
message.""" |
|---|
| 70 |
|
|---|
| 71 |
self.plone_log('blogger/newPost') |
|---|
| 72 |
|
|---|
| 73 |
sbtool = getToolByName(self, 'simpleblog_tool') |
|---|
| 74 |
blog = sbtool.getByUID(blogid) |
|---|
| 75 |
|
|---|
| 76 |
post = content.split('\n') |
|---|
| 77 |
title = post[0] |
|---|
| 78 |
if len(title)>25: |
|---|
| 79 |
title = str(DateTime.DateTime()) |
|---|
| 80 |
body = '\n'.join(post[1:]) |
|---|
| 81 |
|
|---|
| 82 |
|
|---|
| 83 |
|
|---|
| 84 |
id = sbtool.idFromTitle(title) |
|---|
| 85 |
|
|---|
| 86 |
self.plone_log("<blogger.newPost()>") |
|---|
| 87 |
self.plone_log("blogid: ", blogid) |
|---|
| 88 |
self.plone_log("content: ", content) |
|---|
| 89 |
|
|---|
| 90 |
|
|---|
| 91 |
self.plone_log("publish: ", publish) |
|---|
| 92 |
self.plone_log("</blogger.newPost()>") |
|---|
| 93 |
|
|---|
| 94 |
blog.invokeFactory('BlogEntry', id = id, title = title, body = body) |
|---|
| 95 |
entry = getattr(blog, id) |
|---|
| 96 |
|
|---|
| 97 |
wf_tool = getToolByName(self, 'portal_workflow') |
|---|
| 98 |
if publish: |
|---|
| 99 |
state = sbtool.getPublishedState() |
|---|
| 100 |
entry.setEffectiveDate(DateTime.DateTime()) |
|---|
| 101 |
|
|---|
| 102 |
|
|---|
| 103 |
wf_tool.doActionFor(entry,'publish', None) |
|---|
| 104 |
|
|---|
| 105 |
return entry.UID() |
|---|
| 106 |
|
|---|
| 107 |
security.declarePublic('editPost') |
|---|
| 108 |
def editPost(self, appkey, postid, username, password, content, publish): |
|---|
| 109 |
"""blogger.editPost changes the contents of a given post. Optionally, |
|---|
| 110 |
will publish the blog the post belongs to after changing the post. On |
|---|
| 111 |
success, it returns a boolean true value. On error, it will return a |
|---|
| 112 |
fault with an error message.""" |
|---|
| 113 |
self.plone_log('blogger/editPost') |
|---|
| 114 |
|
|---|
| 115 |
sbtool = getToolByName(self, 'simpleblog_tool') |
|---|
| 116 |
|
|---|
| 117 |
entry = sbtool.getByUID(postid) |
|---|
| 118 |
|
|---|
| 119 |
entry.setBody(content, mimetype='text/html') |
|---|
| 120 |
|
|---|
| 121 |
if publish: |
|---|
| 122 |
wf_tool = getToolByName(self, 'portal_workflow') |
|---|
| 123 |
entry.setEffectiveDate(DateTime.DateTime()) |
|---|
| 124 |
wf_tool.doActionFor(entry, 'publish', None) |
|---|
| 125 |
|
|---|
| 126 |
return True |
|---|
| 127 |
|
|---|
| 128 |
security.declarePublic('deletePost') |
|---|
| 129 |
def deletePost(self, appkey, postid, username, password, publish): |
|---|
| 130 |
"Returns true on success, fault on failure" |
|---|
| 131 |
self.plone_log('blogger/deletePost') |
|---|
| 132 |
|
|---|
| 133 |
sbtool = getToolByName(self, 'simpleblog_tool') |
|---|
| 134 |
|
|---|
| 135 |
entry = sbtool.getByUID(postid) |
|---|
| 136 |
|
|---|
| 137 |
entry.aq_inner.aq_parent.manage_delObjects(entry.getId()) |
|---|
| 138 |
|
|---|
| 139 |
return True |
|---|
| 140 |
|
|---|
| 141 |
security.declarePublic('getRecentPosts') |
|---|
| 142 |
def getRecentPosts(self, appkey, blogid, username, password, num): |
|---|
| 143 |
"Return 'num' recent posts to specified blog" |
|---|
| 144 |
self.plone_log('blogger/getRecentPosts') |
|---|
| 145 |
sbtool = getToolByName(self, 'simpleblog_tool') |
|---|
| 146 |
blog = sbtool.getByUID(blogid) |
|---|
| 147 |
entries = blog.getFolderListingFolderContents(contentFilter={'portal_type': 'BlogEntry'},) |
|---|
| 148 |
|
|---|
| 149 |
posts = [] |
|---|
| 150 |
for entry in entries: |
|---|
| 151 |
posts.append( { 'dateCreated':entry.created() |
|---|
| 152 |
, 'userid':entry.Creator() |
|---|
| 153 |
, 'postid':entry.UID() |
|---|
| 154 |
, 'title':entry.Title() |
|---|
| 155 |
, 'description':entry.getBody() |
|---|
| 156 |
, 'excerpt':entry.Description() |
|---|
| 157 |
, 'content':entry.getBody() |
|---|
| 158 |
}) |
|---|
| 159 |
|
|---|
| 160 |
|
|---|
| 161 |
if num is not None: |
|---|
| 162 |
return posts[:int(num)] |
|---|
| 163 |
return posts |
|---|
| 164 |
|
|---|
| 165 |
|
|---|
| 166 |
security.declarePublic('getUsersBlogs') |
|---|
| 167 |
def getUsersBlogs(self, appkey, username, password): |
|---|
| 168 |
"""blogger.getUsersBlogs returns information about all the blogs a |
|---|
| 169 |
given user is a member of. Data is returned as an array of <struct>'s |
|---|
| 170 |
containing the ID (blogid), name (blogName), and URL (url) of each |
|---|
| 171 |
blog.""" |
|---|
| 172 |
self.plone_log('blogger/getUsersBlogs') |
|---|
| 173 |
catalog = getToolByName(self, 'portal_catalog') |
|---|
| 174 |
results = catalog(meta_type='Blog') |
|---|
| 175 |
|
|---|
| 176 |
blogs = [] |
|---|
| 177 |
for item in results: |
|---|
| 178 |
o = item.getObject() |
|---|
| 179 |
if o.portal_membership.checkPermission('Modify portal content', o): |
|---|
| 180 |
blogs.append( |
|---|
| 181 |
{'url': o.absolute_url(), |
|---|
| 182 |
'blogid' : o.UID(), |
|---|
| 183 |
'blogName' : o.title_or_id()} |
|---|
| 184 |
) |
|---|
| 185 |
|
|---|
| 186 |
return blogs |
|---|
| 187 |
|
|---|
| 188 |
security.declarePublic('getUserInfo') |
|---|
| 189 |
def getUserInfo(self, appkey, username, password): |
|---|
| 190 |
"""blogger.getUserInfo returns returns a struct containing user's |
|---|
| 191 |
userid, firstname, lastname, nickname, email, and url.""" |
|---|
| 192 |
self.plone_log('blogger/getUserInfo') |
|---|
| 193 |
|
|---|
| 194 |
membership=getToolByName(self, 'portal_membership') |
|---|
| 195 |
info={'name':'no name','email':'no email','userid':'no user id' |
|---|
| 196 |
,'firstname':'no first name','lastname':'no last name' |
|---|
| 197 |
,'url':'no url'} |
|---|
| 198 |
member=membership.getAuthenticatedMember() |
|---|
| 199 |
if member: |
|---|
| 200 |
for key,value in info.items(): |
|---|
| 201 |
info[key] = getattr(member,key,None) or value |
|---|
| 202 |
return info |
|---|
| 203 |
|
|---|
| 204 |
security.declarePublic('getTemplate') |
|---|
| 205 |
def getTemplate(self): |
|---|
| 206 |
"""blogger.getTemplate returns text of the main or archive index |
|---|
| 207 |
template for a given blog.""" |
|---|
| 208 |
|
|---|
| 209 |
self.plone_log('blogger/getTemplate') |
|---|
| 210 |
pass |
|---|
| 211 |
|
|---|
| 212 |
security.declarePublic('setTemplate') |
|---|
| 213 |
def setTemplate(self): |
|---|
| 214 |
"""blogger.setTemplate changes the template for a given blog. Can |
|---|
| 215 |
change either main or archive index template.""" |
|---|
| 216 |
|
|---|
| 217 |
self.plone_log('blogger/setTemplate') |
|---|
| 218 |
pass |
|---|
| 219 |
|
|---|