• Stars
    star
    107
  • Rank 323,587 (Top 7 %)
  • Language
    Python
  • Created almost 13 years ago
  • Updated over 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A django app providing reverse-ajax chat rooms. Based on gevent.

Django Chatrooms

Chatrooms is an app that provides multi-user chat rooms for your django site.

It's completely based on jQuery and gevent, whose libraries have been used to implement long polling.

It provides a set of models, views and templates ready out of the box and easily customizable.

Installation

Install the egg from pypi:

$ pip install django-chatrooms

or get the latest revision from github:

$ pip install -e git+git://github.com/qubird/django-chatrooms#egg=chatrooms

If you use buildout, just add django-chatrooms to your eggs part.

The egg setup takes care of installing all the needed dependencies, anyway you might need to install greenlet and libevent to let gevent work properly.

Once the egg is installed, add the following apps to your settings.INSTALLED_APPS:

INSTALLED_APPS = (
    # ...,
    'polymorphic',
    'chatrooms',
    # ...,
)

Then include chatrooms urls to your urlpatterns:

urlpatterns = patterns('',
    # ...,
    url(r'^chat/', include('chatrooms.urls')),
    # ...,
)

Make sure you also added staticfiles_urlpatterns to urlconf like:

from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += staticfiles_urlpatterns()

and 'django.contrib.staticfiles' is amongst INSTALLED_APPS.

Then you're ready to run syncdb.

Important Note

django-chatrooms works properly in a multithreading environment (like gevent patched wsgi server, or uwsgi server with gevent plugin).

To use the app with servers that pre-fork the application before running, like gunicorn does, you need to use some sort of interprocess communication.

chatrooms.utils.redis_handlers module contains the RedisMessageHandler class, which can be set as settings.CHATROOMS_MESSAGE_HANDLERS to use the application in a gunicorn-like environment. The module needs a redis instance installed and running to work.

Also a chatrooms.utils.celery_handlers.CeleryMessageHandler class has been included. It can be used as settings.CHATROOMS_MESSAGE_HANDLERS as well, but needs celery to be installed.

See the Message Handlers section to know how to implement your own handlers.

Using the app

Models

The app installs two models: Room and Message. Rooms can be created by Admin Site. Room objects have the following fields:

name:
description:almost self-explaining
slug:which identifies the room in urls and views
subscribers:which references a set of users (not used by default)
allow_anonymous_access:which tells whether the room is accessible only to logged users, or event to "guests". A guest user is asked to choose a guest name before entering the room.
private:
password:These fields aren't used by default. They might be useful for implementing custom policies of access. See the Custom access policies section for further details.

Views

Besides the core views that handle ajax requests to make the chat work, some class-based views have been designed.

These are in views.py:

  • RoomsListView, which shows the list of rooms filtering the ones requiring a logged user if the user is not authenticated
  • RoomView, which renders the actual room page
  • GuestNameView, which is shown to non-logged users entering an allow_anonymous_access room to choose a guest name

Templates

The templates you might want to override are

  • chatrooms/guestname_form.html, which is rendered by GuestNameView: it shows the form for choosing a guest name

  • chatrooms/rooms_list.html, which is rendered by RoomsListView

  • chatrooms/room.html, which is the skeleton of the page where chat objects are placed dynamically. The page includes the js/room.js script which requires a getContext() function like:

    <script type="text/javascript">
        getContext = function(){
            return {
                "username": "{{ user.username }}",
                "room_id": {{ room.id }},
            }
        }
    </script>
    

Some elements are required by room.js and need to be included in room.html:

#chatText: an empty div,
#chatSendText: text input where the user enters the text to send,
#chatSendButton: button input pressed by user to submit text,
#connectedUsersList: a list element where connected users are shown.

Styles

static/css folder contains the file room.css you might want to override to re-style the room page.

Tests

The test_gevent command has been implemented to test the chat features that use gevent libraries.

Message Handlers

utils.handlers.MessageHandler class implements the methods

  • handle_received_message(sender, room_id, username, message, date, [user])

    sender:the ChatView instance
    room_id:the id of the room where the message was sent
    username:username or guest name of the user who sent the message
    message:the content of the sent message
    date:the timestamp of the sent message
    user:request.user if user is authenticated, else None
  • retrieve_messages(chatobj, room_id, latest_msg_id)

    chatobj:the ChatView instance
    room_id:the id of the room whose messages are requested
    latest_msg_id:the id of the latest message sent to the room
  • get_latest_message_id(chatobj, room_id)

    chatobj:the ChatView instance
    room_id:the id of the room whose latest message id is requested

handle_received_message method is designed to perform operations with the received message such that retrieve_messages is able to retrieve it afterwards.

retrieve_messages must return a list of tuples like [(message_id, message_obj), ...], where message_obj is an instance of Message or an object with at least the following attributes:

  • username
  • date
  • content

and message_id is a unique progressive identifier.

get_latest_message_id must give back the id of the latest message received, consistently to the ways messages are stored and retrieved.

To implement your handlers you need to create a class extending chatrooms.utils.handlers.MessageHandler, say my.app.MyHandlerClass, override the aforementioned methods, and add to your settings:

CHATROOMS_HANDLERS_CLASS = 'my.app.MyHandlerClass'

This way your defined methods will be used as default handlers for received messages and requests for messages.

See utils.handlers.MessageHandler and ajax.chat.ChatView docstrings for further details on these classes.

Custom access policies

Access to rooms can be controlled defining a function which takes request and user as arguments, and returns True or False whether the user is allowed to access the room or not (room_id is given as a GET parameter of the request).

Once you defined your function, say my.app.user_can_enter_foo, add to your settings:

CHATROOMS_TEST_USER_FUNCTION = 'my.app.user_can_enter_foo'

Your function will be used as a test by view decorators. When the user sends ajax requests to send or get chat messages, or get the connected users list, request and user are passed to your function. If it returns False, a 403 Forbidden Resource response is given, else the request is normally processed.

Acknowledgements

Denis Bilenko 's webchat example has been a great starting point for the design of this app.

Further improvements

  • Users list methods could be improved to work properly in multi-process environments, as it's been done with message handlers.