This repository has been archived by the owner on Oct 23, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Web-based realtime multiuser chat (final project for CS 329E)
mccutchen/watercooler
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
README Introduction ------------------------------------------------------------------------ Watercooler is a web application that provides realtime group chat, built with Python and the Django web programming framework. This document aims to be a high-level overview of its structure and functionality (it will no doubt be long-winded and cover the wrong details). Watercooler has only been tested in Firefox on OS X and Windows and Safari on OS X. It has been designed to be completely functional (though much less useful) with JavaScript disabled (ie, posts can still be made, etc., but there would be no live updating of chat pages). Testing Watercooler by yourself requires using at least two separate browsers, so that you can log in as two separate users to make posts to the same conversation. I've done this with Firefox and Safari as well as just Firefox under two separate profiles. Basic Structure ------------------------------------------------------------------------ Watercooler is a Django project, which means the source code follows the same basic patterns as other Django projects. At a basic level, Django projects are defined by the following elements: * settings.py, which defines the settings for the project * models.py, which defines the data models used by the project in terms of Django's object-relational mapper (ORM) * urls.py, which defines the URL structure of the project, mapping URLs to view functions * views.py, which contains the view functions to which URLs are mapped by urls.py Additionally, most Django projects, Watercooler included, will also have the following: * a templates directory, which contains the templates used by the view functions to generate output * admin.py, which sets up Django's built-in administrative interface for a project's particular data models (as defined in models.py) * a media directory, which contains the static media (ie, CSS, JavaScript, images, etc.) used by the project. These are generally not served by Django itself, but are instead served by another web server better suited for that task (eg, Apache, nginx, etc.). A note about the concepts of projects vs. applications in Django: When you read about Django, you will see that, generally speaking, a single Django "project" is composed of one or more Django "applications" (which can be shared between projects, ideally). Watercooler, because of its simplicity, is a single project and application (in the Django sense) in one. Django contrib apps used ------------------------------------------------------------------------ Watercooler takes advantage of some of Django's bundled contrib apps to easily extend its functionality. It uses the following apps: * django.contrib.admin, which provides a nice administrative interface to your data. * django.contrib.auth, which provides an authentication system for managing users (including logging them in and out and allowing them to register). These apps in turn use the django.contrib.contenttypes and django.contrib.sessions apps. Settings ------------------------------------------------------------------------ Django projects usually keep their settings in a module called 'settings.py'. For Watercooler, I have broken the settings up by hostname to make deployment to different hosts (eg, my local dev server and the remote production server) easiser. So, in the Watercooler source code, there is a settings directory which serves as a Python module. The common settings shared by all instances of Watercooler are contained in settings/__init__.py. Host-specific settings are kept in Python files named for the hostname to which they apply. For example, dev server is named 'butter', so the settings that apply to Watercooler on that server are in settings/butter.py. Chat pages ------------------------------------------------------------------------ The most complicated part of Watercooler is the functionality of the individual chat pages. Here is a basic explanation of how they work. Chats are identified by their "slug" in URLs. The slug is automatically generated based on the name given to the chat when it is created. Each Chat is composed of zero or more Posts. Posts are associated with a particular User, were created at a particular date and time, and have their content saved as plain text. When a particular Chat's page is loaded, all of its Posts are stuffed into a table with two columns: username and post content. Initially, the post content is plain text. On page load, the following steps are taken: * MediaHandler (defined in media/js/mediahandler.js) is initialized * PostHandler (media/js/posthandler.js) is initialized * LayoutHandler (media/js/layouthandler.js) is initialized Then, the PostHandler begins polling the server every two seconds to get any new Posts made by other users and to get an updated list of active and inactive Users for this particular Chat. MediaHandler ------------------------------------------------------------------------ The MediaHandler object is responsible for transforming each Post's plain text content into embedded multimedia objects when appropriate. Each Post's content is run through the MediaHandler.handle method, which simply looks for URLs. If a URL is found, one of the following steps is taken: * Image URLs (ie, those pointing to JPEG, GIF or PNG files) are transformed into inline image elements. * YouTube URLs are transformed into embedded YouTube videos. * MP3 URLs are transformed into embedded media players. * Any other URLs are transformed into hyperlink elements. On initialization, MediaHandler iterates over each post currently on the page and processes its content as described above. Then, when any new posts are added to the page (by the current user or other users), those posts are also processed. PostHandler ------------------------------------------------------------------------ When the PostHandler is initialized, it iterates through each Post on the page and adds its timestamp (which is given in the Post's <tr>'s class attribute) to a list of known timestamps. It then sets up an event listener on the post form that intercepts form submissions and instead adds the post via an Ajax request to the server. Finally, it begins polling the server for updates every two seconds. On every poll request, the PostHandler sends the latest timestamp that it knows about and receives from the server a list of Posts made since that timestamp and a list of active and inactive users. It adds any posts to the page (after having their content processed by the MediaHandler) and passes the list of users to the UserHandler, which updates the list of users in the sidebar. LayoutHandler ------------------------------------------------------------------------ The LayoutHandler tries to fit the layout of the page to the size of the user's browser window when the page is loaded. This ensures that the footer and post form are always at the bottom of the page, available without scrolling. This is, however, a brittle approach that breaks when the window is resized (and probably suffers from other problems). Flaws ------------------------------------------------------------------------ There are some flaws in Watercooler as it is currently constituted. Some are simply features which have not been implemented, others are problems for which a good solution has not yet been found. Here are those that I can think of off right now: * Private chats. All chats created through the public web interface are public. In a finished product, there would be private, password-protected chats that could be shared with a specific group of people (via automated email, presumably). I felt this was out of the scope of the project. * Post dates and times. At the moment, there is no date or time information displayed with the posts on chat pages, even though that data is readily available. I should figure out a good way to make that info available when desired. * Chat archiving. A chat page currently displays every post made in that chat. This would get unweildy with large or long-lasting chats, so an interface for archiving chats should be implemented. * Chats with duplicate names. Right now, if you try to create a chat with the same name as one that already exists, you are silently redirected to the existing chat's page. Ideally, a new chat with an adjusted slug would be created instead. * The dynamic layout of chat pages (done by LayoutHandler) is brittle and flaky. A better solution (preferably all CSS) would be nice. Wrapping Up ------------------------------------------------------------------------ I'll add to this document as things occur to me. Please let me know if you have any questions or comments. I'll be glad to answer them to the best of my ability. Will McCutchen mccutchen@gmail.com
About
Web-based realtime multiuser chat (final project for CS 329E)
Resources
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published