Commits

Adam Knight committed 6530456

The MetaWeblog API now works in a rudamentary sense and is rooted at /api/ by default. Much more work to come, but list and edit are working with some MT extensions.

  • Participants
  • Parent commits e3dfff7

Comments (0)

Files changed (4)

 * URL management should be central.
 * When an object is saved, it should save a redirect with its current URL and its content type.
 * If the URL ever changes, that redirect will start to get hit and serve as a safety net for the object.  It will always redirect to the object's current URL as returned by get_absolute_url.
+
+
+h1. ToDo Ideas
+
+* Remove the archive browser from being rooted at /; add another urls.py entry for it so it can be repurposed.
+* Add apps for codepoetry and macgeekery, such as products (manages software releases, including appcasts), projects (connects to bitbucket, maybe?), questions (asked and answered, with email notifications), and user profiles (AdSense IDs, among other things).
+* Allow Drupal import to import a specific taxonomy as the section list instead of content types.
+* Allow SITE_ID and other variables to be set from a SitePoetSite object, or something like that.  That way one set of FCGI instances can serve all hosted sites instead of needing one class per site so that the settings file is done right.
+* Add ability to set the default state of comments for sites that do not want to use it. Don't bother loading comment-related features (such as template tags) in such a case.

sitepoet/metaweblog.py

 from sitepoet.xmlrpc import public
 from django.conf import settings
 # import sitepoet.config
-import xmlrpclib.DateTime
+import xmlrpclib # import DateTime
 
 def authenticated(pos=1):
-    """
-    A decorator for functions that require authentication.
-    Assumes that the username & password are the second & third parameters.
-    Doesn't perform real authorization (yet), it just checks that the
-    user is_superuser.
-    """
-    
-    def _decorate(func):
-        def _wrapper(*args, **kwargs):
-            username = args[pos+0]
-            password = args[pos+1]
-            args = args[0:pos]+args[pos+2:]
-            try:
-                user = User.objects.get(username__exact=username)
-            except User.DoesNotExist:
-                raise ValueError("Authentication Failure")
-            if not user.check_password(password):
-                raise ValueError("Authentication Failure")
-            if not user.is_superuser:
-                raise ValueError("Authorization Failure")
-            return func(user, *args, **kwargs)
-        
-        return _wrapper
-    return _decorate
+	"""
+	A decorator for functions that require authentication.
+	Assumes that the username & password are the second & third parameters.
+	Doesn't perform real authorization (yet), it just checks that the
+	user is_superuser.
+	"""
+	
+	def _decorate(func):
+		def _wrapper(*args, **kwargs):
+			username = args[pos+0]
+			password = args[pos+1]
+			args = args[0:pos]+args[pos+2:]
+			try:
+				user = User.objects.get(username__exact=username)
+			except User.DoesNotExist:
+				raise ValueError("Authentication Failure")
+			if not user.check_password(password):
+				raise ValueError("Authentication Failure")
+			if not user.is_superuser:
+				raise ValueError("Authorization Failure")
+			return func(user, *args, **kwargs)
+		
+		return _wrapper
+	return _decorate
 
 def full_url(url):
-    return urlparse.urljoin(settings.SITE_URL, url)
+	return urlparse.urljoin(settings.SITE_URL, url)
 
 @public
 @authenticated()
 def blogger_getUsersBlogs(user, appkey):
-    """
-    an array of <struct>'s containing the ID (blogid), name
-    (blogName), and URL (url) of each blog.
-    """
-    return [{
-            'blogid': settings.SITE_ID,
-            # 'blogName': sitepoet.config.title,
-            'url': settings.SITE_URL
-            }]
+	"""
+	an array of <struct>'s containing the ID (blogid), name
+	(blogName), and URL (url) of each blog.
+	"""
+	return [{
+			'blogid': settings.SITE_ID,
+			# 'blogName': sitepoet.config.title,
+			'url': settings.SITE_URL
+			}]
 
 @public
 @authenticated()
 def metaWeblog_getCategories(user, blogid):
-    tags = Tag.objects.all()
-    return [tag.name for tag in tags]
+	tags = Tag.objects.all()
+	return [tag for tag in tags]
 
 # example... this is what wordpress returns:
 # {'permaLink': 'http://gabbas.wordpress.com/2006/05/09/hello-world/',
 #  'mt_allow_pings': 1}
 
 def format_date(d):
-    if not d: return None
-    return xmlrpclib.DateTime(d.isoformat())
+	if not d: return None
+	return xmlrpclib.DateTime(d.isoformat())
 
 def post_struct(post):
-    link = full_url(post.get_absolute_url())
-    categories = post.tags.all()
-    struct = {
-        'postid': post.id,
-        'title': post.title,
-        'link': link,
-        'permaLink': link,
-        'description': post.body,
-        'categories': [c.name for c in categories],
-        'userid': post.author.id,
-        # 'mt_excerpt': '',
-        # 'mt_text_more': '',
-        # 'mt_allow_comments': 1,
-        # 'mt_allow_pings': 1}
-        }
-    if post.pub_date:
-        struct['dateCreated'] = format_date(post.pub_date)
-    return struct
-
-def setTags(post, struct):
-    tags = struct.get('categories', None)
-    if tags is None:
-        post.tags = []
-    else:
-        post.tags = [Tag.objects.get(name__iexact=name) for name in tags]
-    
+	link = full_url(post.get_absolute_url())
+	struct = {
+		'postid': post.id,
+		'title': post.title,
+		'mt_basename': post.slug,
+		'link': link,
+		'permaLink': link,
+		'description': post.teaser,
+		'mt_tags': post.tags,
+		'userid': post.user.id,
+		# 'mt_excerpt': post.teaser,
+		'mt_text_more': post.content,
+		# 'mt_allow_comments': 1,
+		# 'mt_allow_pings': 1}
+		}
+	if post.date_published:
+		struct['dateCreated'] = format_date(post.date_published)
+	return struct
+
 @public
 @authenticated()
 def metaWeblog_getPost(user, postid):
-    post = Story.objects.get(id=postid)
-    return post_struct(post)
+	post = Story.objects.get(id=postid)
+	return post_struct(post)
 
 @public
 @authenticated()
 def metaWeblog_getRecentPosts(user, blogid, num_posts):
-    posts = Story.objects.order_by('-pub_date')[:int(num_posts)]
-    return [post_struct(post) for post in posts]
+	posts = Story.objects.order_by('-date_published')[:int(num_posts)]
+	return [post_struct(post) for post in posts]
 
 @public
 @authenticated()
 def metaWeblog_newPost(user, blogid, struct, publish):
-    body = struct['description']
-    # todo - parse out technorati tags
-    post = Story(title = struct['title'],
-                body = body,
-                author = user,
-                create_date = struct['dateCreated'],
-                status = publish and 'Published' or 'Draft')
-    post.prepopulate()
-    post.save()
-    setTags(post, struct)
-    return post.id
+	body = struct['description']
+	# todo - parse out technorati tags
+	post = Story(title = struct['title'],
+				body = body,
+				author = user,
+				create_date = struct['dateCreated'],
+				status = publish,
+				tags = struct.get('mt_tags', None),
+	)
+	post.save()
+	return post.id
 
 @public
 @authenticated()
 def metaWeblog_editPost(user, postid, struct, publish):
-    post = Story.objects.get(id=postid)
-    title = struct.get('title', None)
-    if title is not None:
-        post.title = title
-    body = struct.get('description', None)
-    if body is not None:
-        post.body = body
-        # todo - parse out technorati tags
-    if user:
-        post.author = user
-    post.status = publish and 'Published' or 'Draft'
-    setTags(post, struct)
-    post.prepopulate()
-    post.save()
-    return True
+	post = Story.objects.get(id=postid)
+	title = struct.get('title', None)
+	if title is not None:
+		post.title = title
+	body = struct.get('description', None)
+	if body is not None:
+		post.body = body
+		# todo - parse out technorati tags
+	if user:
+		post.author = user
+	post.status = publish
+	post.tags = struct.get('mt_tags', post.tags)
+	post.slug = struct.get('mt_basename', post.slug)
+	post.save()
+	return True
 
 @public
 @authenticated(pos=2)
 def blogger_deletePost(user, appkey, postid, publish):
-    post = Story.objects.get(id=postid)
-    post.delete()
-    return True
+	post = Story.objects.get(id=postid)
+	post.delete()
+	return True
 
 # http://qoli.de/blog/2007/nov/19/implementing-metaweblog-api/
 @public
 @authenticated()
-def metaWeblog_newMediaObject(user, blogid, struct):        
-    bits = b64decode(struct['bits'])
-    name = struct['name']
-    mime = struct['type']
-
-    attachment= Attachment(content= bits,
-                   filename= name,
-                   contenttype= mime)
-    attachment.save_content_file(name, bits)
-    attachment.save()
-
-    return {'url': attachment.get_content_url()}
+def metaWeblog_newMediaObject(user, blogid, struct):		
+	bits = b64decode(struct['bits'])
+	name = struct['name']
+	mime = struct['type']
+
+	attachment= Attachment(content= bits,
+				   filename= name,
+				   contenttype= mime)
+	attachment.save_content_file(name, bits)
+	attachment.save()
+
+	return {'url': attachment.get_content_url()}

sitepoet/models.py

 	
 	@models.permalink
 	def get_absolute_url(self):
-		return ('section-archive',(), {'section':self.name})
+		return ('section-archive',(), {'section':self.slug})
 
 
 class Page(Resource):
 	
 	def get_absolute_url(self):
 		if self.section:
-			section = self.section.name
+			section = self.section.slug
 		else:
 			section = None
 		
 from models import Story
 from django.conf import settings
 
-urlpatterns = patterns('sitepoet.views',
+urlpatterns = patterns('',
+	# MetaWeblog access point
+	url(r'^api/', 'sitepoet.xmlrpc.view', kwargs={'module':'sitepoet.metaweblog'}),
+)
+
+urlpatterns += patterns('sitepoet.views',
 	# Comments
     (r'^comments/', include('django.contrib.comments.urls')),
 	
+	# Front page
+	#  Enable this if you want the front page to not be an index of Stories, but a static Page.
+	# (r'^$', 'view_page', {'url':'/'}),
+	
 	# Articles
 	url(
-		regex  = r'^(?:(?P<section>[^/]+)/)?(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<slug>.+)/$',
+		regex  = r'^(?:(?P<section>[^/]+?)/)?(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<slug>.+)/$',
 		view   = 'story_detail',
 		name   = "story-detail"
 	),
 urlpatterns += patterns('sitepoet.views',
 	(r'^(?P<url>.*)$', 'view_page'),
 )
-
-# urlpatterns += patterns('',
-# 	# MetaWeblog access point
-# 	url(r'^xmlrpc/', 'sitepoet.xmlrpc.view', kwargs={'module':'sitepoet.metaweblog'}),
-# )