Jérôme Steunou

I code, I manage, I play music, I'm curious.

Comimoc Project

Why the Comimoc Project?

Comimoc stands for COMents In My Own Cloud. The goal of this project is to provide a simple system to handle comments for static blogs like this one, because I did not want to use Disqus and I could not find an alternative for Pelican. When I started it I had those criteria in mind:

  • Front-end separated from back-end. So it can be added easily with some JavaScript everywhere and the resources for the back-end mutualized.
  • Back-end very light, so it can be hosted on PaaS plateform if needed.

Also I would like to start playing with AngularJS for real and I know how to use Flask and MongoDB. So I made that choice and I did not need anything else. Nice. Plus, the advantage with this stack and separation is that if some people do not like AngularJS or just want to write his own front-end, he can. Same with the back-end.

Sounds sweet but show me some stuff!

Fine. All comments for this blog are handled by Comimoc and hosted thanks to Heroku. I also published the theme I made for Pelican with an integration of Comimoc.

Comimoc itself is on Github, both front and back. The Comimoc back-end is also avalaible on Pypi so you can just pip install comimoc and start using it just like that!

Example for Heroku and MongoLab addon:

3 files:

1) requirements.txt

gunicorn
comimoc

2) mycomimoc.py

# -*- coding: utf-8 -*-

import os

from comimoc import create_app

options = {
    "SECRET_KEY": "my secret key ;)",
    "MONGODB_SETTINGS": {
        "HOST": os.environ["MONGOLAB_URI"],
        "DB": "test" # flask mongoengine current bug: it wont use DB, but crashes with HOST alone
        },
    "CORS_ALLOW_ORIGIN_WHITELIST": ('http://jeromesteunou.net', 'http://www.jeromesteunou.net')
}
flask_app = create_app(options)

3) Procfile

web: gunicorn mycomimoc:flask_app

BOUM as easy as pie!

API description

For the developpers that want to develop their own front-end on top of Comimoc back-end, here is the technical documention.

Document comment

{
    _id: ObjectId,
    website: String,
    page: String,
    author_email: String,
    author_name: String,
    author_website: String,
    content: String,
    when: ISODate
}

HTTP /comments

GET /comments?website=string&page=string return a list of comments matching the couple website/page in an object. (See the security reason).

{
    comments: [
        {
            id: String,
            website: String,
            page: String,
            author_email: String,   // hash gravatar compatible
            author_name: String,
            author_website: String or null,
            content: String,
            when: String            // datetime in RFC 822 see http://tools.ietf.org/html/rfc822.html
        },
        {
            ...
        },
        ...
    ]
}

POST /comments add a new comment for the couple website/page. On success return a 201 with the saved comment in the same format the GET request.

{
    website: String,        // mandatory
    page: String,           // mandatory
    author_email: String,   // mandatory and email format
    author_name: String,    // mandatory
    author_website: String, // not mandatory
    content: String         // mandatory
}

Source code

All of these are BSD Licensed.