Package: django-chatrooms
Chatrooms is an app that provides multi-user chat rooms for your django site.It’s completely based on jQuery andgevent, 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.InstallationInstall the egg from pypi:$ pip install django-chatroomsor get the latest revision from github:$ pip install -e git+git://github.com/qubird/django-chatrooms#egg=chatroomsIf you use buildout, just adddjango-chatroomsto your eggs part.The egg setup takes care of installing all the needed dependencies, anyway you might need to installgreenletandlibeventto 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 addedstaticfiles_urlpatternsto urlconf like:from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += staticfiles_urlpatterns()and'django.contrib.staticfiles'is amongstINSTALLED_APPS.Then you’re ready to runsyncdb.Important Notedjango-chatrooms works properly in a multithreading environment (likegevent patched wsgi server, oruwsgi server with gevent plugin).To use the app with servers that pre-fork the application before running, likegunicorndoes, you need to use some sort of interprocess
communication.chatrooms.utils.redis_handlersmodule contains theRedisMessageHandlerclass,
which can be set assettings.CHATROOMS_MESSAGE_HANDLERSto use the application
in a gunicorn-like environment.
The module needs aredisinstance installed and running to work.Also achatrooms.utils.celery_handlers.CeleryMessageHandlerclass has been included.
It can be used assettings.CHATROOMS_MESSAGE_HANDLERSas well, but needsceleryto be installed.See theMessage Handlerssection to know how to implement your own handlers.Using the appModelsThe app installs two models: Room and Message.
Rooms can be created by Admin Site.
Room objects have the following fields:name:description:almost self-explainingslug:which identifies the room in urls and viewssubscribers: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 theCustom access policiessection for further details.ViewsBesides the core views that handle ajax requests to make the chat work, some class-based views have been designed.These are inviews.py:RoomsListView, which shows the list of rooms filtering the ones requiring a logged user if the user is not authenticatedRoomView, which renders the actual room pageGuestNameView, which is shown to non-logged users entering anallow_anonymous_accessroom to choose a guest nameTemplatesThe templates you might want to override arechatrooms/guestname_form.html, which is rendered by GuestNameView: it shows the form for choosing a guest namechatrooms/rooms_list.html, which is rendered by RoomsListViewchatrooms/room.html, which is the skeleton of the page where chat objects are placed dynamically. The page includes thejs/room.jsscript which requires agetContext()function like:<script type="text/javascript">
    getContext = function(){
        return {
            "username": "{{ user.username }}",
            "room_id": {{ room.id }},
        }
    }
</script>Some elements are required byroom.jsand need to be included inroom.html:#chatText: an emptydiv,#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.Stylesstatic/cssfolder contains the fileroom.cssyou might want to override to re-style the room page.TestsThetest_geventcommand has been implemented to test the chat features that use gevent libraries.Message Handlersutils.handlers.MessageHandlerclass implements the methodshandle_received_message(sender, room_id, username, message, date, [user])sender:the ChatView instanceroom_id:the id of the room where the message was sentusername:username or guest name of the user who sent the messagemessage:the content of the sent messagedate:the timestamp of the sent messageuser:request.user if user is authenticated, elseNoneretrieve_messages(chatobj, room_id, latest_msg_id)chatobj:the ChatView instanceroom_id:the id of the room whose messages are requestedlatest_msg_id:the id of the latest message sent to the roomget_latest_message_id(chatobj, room_id)chatobj:the ChatView instanceroom_id:the id of the room whose latest message id is requestedhandle_received_messagemethod is designed to perform operations
with the received message such thatretrieve_messagesis able to
retrieve it afterwards.retrieve_messagesmust return a list of tuples like[(message_id, message_obj),...], wheremessage_objis an instance ofMessageor an object with at least the following attributes:usernamedatecontentandmessage_idis a unique progressive identifier.get_latest_message_idmust 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 extendingchatrooms.utils.handlers.MessageHandler, saymy.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.Seeutils.handlers.MessageHandlerandajax.chat.ChatViewdocstrings for further details on these classes.Custom access policiesAccess to rooms can be controlled defining a function which takesrequestanduseras arguments, and returns True or False whether the user is allowed to access the room or not (room_idis given as a GET parameter of the request).Once you defined your function, saymy.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,requestanduserare passed to your function.
If it returnsFalse, a 403 Forbidden Resource response is given, else the request is normally processed.AcknowledgementsDenis Bilenko 's webchat examplehas been a great starting point for the design of this app.Further improvementsUsers list methods could be improved to work properly in multi-process environments, as it’s been done with message handlers.