Package zinnia :: Package xmlrpc :: Module metaweblog
[hide private]

Source Code for Module zinnia.xmlrpc.metaweblog

  1  """XML-RPC methods of Zinnia metaWeblog API""" 
  2  import os 
  3  from datetime import datetime 
  4  from xmlrpclib import Fault 
  5  from xmlrpclib import DateTime 
  6   
  7  from django.conf import settings 
  8  from django.contrib.auth.models import User 
  9  from django.contrib.sites.models import Site 
 10  from django.core.urlresolvers import reverse 
 11  from django.utils.translation import gettext as _ 
 12  from django.utils.html import strip_tags 
 13  from django.utils.text import truncate_words 
 14  from django.core.files.base import ContentFile 
 15  from django.core.files.storage import default_storage 
 16  from django.template.defaultfilters import slugify 
 17   
 18  from zinnia.models import Entry 
 19  from zinnia.models import Category 
 20  from zinnia.settings import PROTOCOL 
 21  from zinnia.settings import UPLOAD_TO 
 22  from zinnia.managers import DRAFT, PUBLISHED 
 23  from django_xmlrpc.decorators import xmlrpc_func 
 24   
 25  # http://docs.nucleuscms.org/blog/12#errorcodes 
 26  LOGIN_ERROR = 801 
 27  PERMISSION_DENIED = 803 
28 29 30 -def authenticate(username, password, permission=None):
31 """Authenticate staff_user with permission""" 32 try: 33 user = User.objects.get(username__exact=username) 34 except User.DoesNotExist: 35 raise Fault(LOGIN_ERROR, _('Username is incorrect.')) 36 if not user.check_password(password): 37 raise Fault(LOGIN_ERROR, _('Password is invalid.')) 38 if not user.is_staff or not user.is_active: 39 raise Fault(PERMISSION_DENIED, _('User account unavailable.')) 40 if permission: 41 if not user.has_perm(permission): 42 raise Fault(PERMISSION_DENIED, _('User cannot %s.') % permission) 43 return user
44
45 46 -def blog_structure(site):
47 """A blog structure""" 48 return {'url': '%s://%s%s' % ( 49 PROTOCOL, site.domain, reverse('zinnia_entry_archive_index')), 50 'blogid': settings.SITE_ID, 51 'blogName': site.name}
52
53 54 -def user_structure(user, site):
55 """An user structure""" 56 return {'userid': user.pk, 57 'email': user.email, 58 'nickname': user.username, 59 'lastname': user.last_name, 60 'firstname': user.first_name, 61 'url': '%s://%s%s' % ( 62 PROTOCOL, site.domain, 63 reverse('zinnia_author_detail', args=[user.username]))}
64
65 66 -def author_structure(user):
67 """An author structure""" 68 return {'user_id': user.pk, 69 'user_login': user.username, 70 'display_name': user.username, 71 'user_email': user.email}
72
73 74 -def category_structure(category, site):
75 """A category structure""" 76 return {'description': category.title, 77 'htmlUrl': '%s://%s%s' % ( 78 PROTOCOL, site.domain, 79 category.get_absolute_url()), 80 'rssUrl': '%s://%s%s' % ( 81 PROTOCOL, site.domain, 82 reverse('zinnia_category_feed', args=[category.tree_path])), 83 # Useful Wordpress Extensions 84 'categoryId': category.pk, 85 'parentId': category.parent and category.parent.pk or 0, 86 'categoryDescription': category.description, 87 'categoryName': category.title}
88
89 90 -def post_structure(entry, site):
91 """A post structure with extensions""" 92 author = entry.authors.all()[0] 93 return {'title': entry.title, 94 'description': unicode(entry.html_content), 95 'link': '%s://%s%s' % (PROTOCOL, site.domain, 96 entry.get_absolute_url()), 97 # Basic Extensions 98 'permaLink': '%s://%s%s' % (PROTOCOL, site.domain, 99 entry.get_absolute_url()), 100 'categories': [cat.title for cat in entry.categories.all()], 101 'dateCreated': DateTime(entry.creation_date.isoformat()), 102 'postid': entry.pk, 103 'userid': author.username, 104 # Useful Movable Type Extensions 105 'mt_excerpt': entry.excerpt, 106 'mt_allow_comments': int(entry.comment_enabled), 107 'mt_allow_pings': int(entry.pingback_enabled), 108 'mt_keywords': entry.tags, 109 # Useful Wordpress Extensions 110 'wp_author': author.username, 111 'wp_author_id': author.pk, 112 'wp_author_display_name': author.username, 113 'wp_password': entry.password, 114 'wp_slug': entry.slug, 115 'sticky': entry.featured}
116
117 118 @xmlrpc_func(returns='struct[]', args=['string', 'string', 'string']) 119 -def get_users_blogs(apikey, username, password):
120 """blogger.getUsersBlogs(api_key, username, password) 121 => blog structure[]""" 122 authenticate(username, password) 123 site = Site.objects.get_current() 124 return [blog_structure(site)]
125
126 127 @xmlrpc_func(returns='struct', args=['string', 'string', 'string']) 128 -def get_user_info(apikey, username, password):
129 """blogger.getUserInfo(api_key, username, password) 130 => user structure""" 131 user = authenticate(username, password) 132 site = Site.objects.get_current() 133 return user_structure(user, site)
134
135 136 @xmlrpc_func(returns='struct[]', args=['string', 'string', 'string']) 137 -def get_authors(apikey, username, password):
138 """wp.getAuthors(api_key, username, password) 139 => author structure[]""" 140 authenticate(username, password) 141 return [author_structure(author) 142 for author in User.objects.filter(is_staff=True)]
143 144 145 @xmlrpc_func(returns='boolean', args=['string', 'string', 146 'string', 'string', 'string'])
147 -def delete_post(apikey, post_id, username, password, publish):
148 """blogger.deletePost(api_key, post_id, username, password, 'publish') 149 => boolean""" 150 user = authenticate(username, password, 'zinnia.delete_entry') 151 entry = Entry.objects.get(id=post_id, authors=user) 152 entry.delete() 153 return True
154
155 156 @xmlrpc_func(returns='struct', args=['string', 'string', 'string']) 157 -def get_post(post_id, username, password):
158 """metaWeblog.getPost(post_id, username, password) 159 => post structure""" 160 user = authenticate(username, password) 161 site = Site.objects.get_current() 162 return post_structure(Entry.objects.get(id=post_id, authors=user), site)
163
164 165 @xmlrpc_func(returns='struct[]', args=['string', 'string', 'string', 'integer']) 166 -def get_recent_posts(blog_id, username, password, number):
167 """metaWeblog.getRecentPosts(blog_id, username, password, number) 168 => post structure[]""" 169 user = authenticate(username, password) 170 site = Site.objects.get_current() 171 return [post_structure(entry, site) \ 172 for entry in Entry.objects.filter(authors=user)[:number]]
173
174 175 @xmlrpc_func(returns='struct[]', args=['string', 'string', 'string']) 176 -def get_categories(blog_id, username, password):
177 """metaWeblog.getCategories(blog_id, username, password) 178 => category structure[]""" 179 authenticate(username, password) 180 site = Site.objects.get_current() 181 return [category_structure(category, site) \ 182 for category in Category.objects.all()]
183
184 185 @xmlrpc_func(returns='string', args=['string', 'string', 'string', 'struct']) 186 -def new_category(blog_id, username, password, category_struct):
187 """wp.newCategory(blog_id, username, password, category) 188 => category_id""" 189 authenticate(username, password, 'zinnia.add_category') 190 category_dict = {'title': category_struct['name'], 191 'description': category_struct['description'], 192 'slug': category_struct['slug']} 193 if int(category_struct['parent_id']): 194 category_dict['parent'] = Category.objects.get( 195 pk=category_struct['parent_id']) 196 category = Category.objects.create(**category_dict) 197 198 return category.pk
199 200 201 @xmlrpc_func(returns='string', args=['string', 'string', 'string', 202 'struct', 'boolean'])
203 -def new_post(blog_id, username, password, post, publish):
204 """metaWeblog.newPost(blog_id, username, password, post, publish) 205 => post_id""" 206 user = authenticate(username, password, 'zinnia.add_entry') 207 if post.get('dateCreated'): 208 creation_date = datetime.strptime( 209 post['dateCreated'].value.replace('Z', '').replace('-', ''), 210 '%Y%m%dT%H:%M:%S') 211 else: 212 creation_date = datetime.now() 213 214 entry_dict = {'title': post['title'], 215 'content': post['description'], 216 'excerpt': post.get('mt_excerpt', truncate_words( 217 strip_tags(post['description']), 50)), 218 'creation_date': creation_date, 219 'last_update': creation_date, 220 'comment_enabled': post.get('mt_allow_comments', 1) == 1, 221 'pingback_enabled': post.get('mt_allow_pings', 1) == 1, 222 'featured': post.get('sticky', 0) == 1, 223 'tags': 'mt_keywords' in post and post['mt_keywords'] or '', 224 'slug': 'wp_slug' in post and post['wp_slug'] or slugify( 225 post['title']), 226 'password': post.get('wp_password', ''), 227 'status': publish and PUBLISHED or DRAFT} 228 entry = Entry.objects.create(**entry_dict) 229 230 author = user 231 if 'wp_author_id' in post and user.has_perm('zinnia.can_change_author'): 232 if int(post['wp_author_id']) != user.pk: 233 author = User.objects.get(pk=post['wp_author_id']) 234 entry.authors.add(author) 235 236 entry.sites.add(Site.objects.get_current()) 237 if 'categories' in post: 238 entry.categories.add(*[Category.objects.get_or_create( 239 title=cat, slug=slugify(cat))[0] 240 for cat in post['categories']]) 241 242 return entry.pk
243 244 245 @xmlrpc_func(returns='boolean', args=['string', 'string', 'string', 246 'struct', 'boolean'])
247 -def edit_post(post_id, username, password, post, publish):
248 """metaWeblog.editPost(post_id, username, password, post, publish) 249 => boolean""" 250 user = authenticate(username, password, 'zinnia.change_entry') 251 entry = Entry.objects.get(id=post_id, authors=user) 252 if post.get('dateCreated'): 253 creation_date = datetime.strptime( 254 post['dateCreated'].value.replace('Z', '').replace('-', ''), 255 '%Y%m%dT%H:%M:%S') 256 else: 257 creation_date = entry.creation_date 258 259 entry.title = post['title'] 260 entry.content = post['description'] 261 entry.excerpt = post.get('mt_excerpt', truncate_words( 262 strip_tags(post['description']), 50)) 263 entry.creation_date = creation_date 264 entry.last_update = datetime.now() 265 entry.comment_enabled = post.get('mt_allow_comments', 1) == 1 266 entry.pingback_enabled = post.get('mt_allow_pings', 1) == 1 267 entry.featured = post.get('sticky', 0) == 1 268 entry.tags = 'mt_keywords' in post and post['mt_keywords'] or '' 269 entry.slug = 'wp_slug' in post and post['wp_slug'] or slugify( 270 post['title']) 271 entry.status = publish and PUBLISHED or DRAFT 272 entry.password = post.get('wp_password', '') 273 entry.save() 274 275 if 'wp_author_id' in post and user.has_perm('zinnia.can_change_author'): 276 if int(post['wp_author_id']) != user.pk: 277 author = User.objects.get(pk=post['wp_author_id']) 278 entry.authors.clear() 279 entry.authors.add(author) 280 281 if 'categories' in post: 282 entry.categories.clear() 283 entry.categories.add(*[Category.objects.get_or_create( 284 title=cat, slug=slugify(cat))[0] 285 for cat in post['categories']]) 286 return True
287
288 289 @xmlrpc_func(returns='struct', args=['string', 'string', 'string', 'struct']) 290 -def new_media_object(blog_id, username, password, media):
291 """metaWeblog.newMediaObject(blog_id, username, password, media) 292 => media structure""" 293 authenticate(username, password) 294 path = default_storage.save(os.path.join(UPLOAD_TO, media['name']), 295 ContentFile(media['bits'].data)) 296 return {'url': default_storage.url(path)}
297