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
26 LOGIN_ERROR = 801
27 PERMISSION_DENIED = 803
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
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
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
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
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
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
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
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):
134
135
136 @xmlrpc_func(returns='struct[]', args=['string', 'string', 'string'])
137 -def get_authors(apikey, username, password):
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):
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
297